SFML community forums

General => Feature requests => Topic started by: Elias Daler on April 14, 2021, 12:16:18 am

Title: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Elias Daler on April 14, 2021, 12:16:18 am
I propose to not set  BUILD_SHARED_LIBS to "OFF" by default (except for platforms where static linking is not supported).

Some projects using CMake are building shared libraries which can be convenient for some people, but doesn't really follow what "BUILD_SHARED_LIBS" is meant to do.

See the docs: https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
Quote
If present and true, this will cause all libraries to be built shared unless the library was explicitly added as a static library.

This makes "BUILD_SHARED_LIBS" opt-in flag. But currently I need to "opt-out" from building shared libraries, which is not convenient, as I expect that static libs are built by default, which is the convention that a lot of CMake projects follow.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Laurent on April 14, 2021, 08:09:10 am
Quote
I propose to not set  BUILD_SHARED_LIBS to "OFF"
You mean to not set to "ON" or to set to "OFF", right?

I disagree, as static linking is far from being the default. To me it's a special case, that should be used only for specific reasons. It's even an exotic thing on non-Windows OSes.

Quote
I expect that static libs are built by default
CMake builds shared libs by default (if nothing is explicitly specified), so why would you expect static libs?
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: eXpl0it3r on April 14, 2021, 09:40:46 am
I agree with Laurent, the default should remain shared libraries, even if I tend to prefer static linking for my own projects on Windows as well.
Plus as mentioned, it's also the CMake default and what is normally expected.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Elias Daler on April 14, 2021, 12:19:44 pm
CMake builds shared libs by default (if nothing is explicitly specified), so why would you expect static libs?
Plus as mentioned, it's also the CMake default and what is normally expected.
This is not a CMake's default. BUILD_SHARED_LIBS should be manually defined and set to ON so that CMake builds a shared library instead of static one. E.g. this will produce static library:

# CMakeLists.txt
add_library(lib lib.cpp)

// main.cpp
void f(){}

# run:
cmake . && cmake --build . # will make liblib.a

---

It's a bit annoying that I have to "undefine" BUILD_SHARED_LIBS flag which is made for *enabling* shared library builds, but if there's such strong opposition to idea, I will not insist on changing the defaults.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: eXpl0it3r on April 14, 2021, 12:56:50 pm
Aha, I guess I was confused by the formulation of the initial question ;D

So you'd essentially want to add something along the lines of: set(BUILD_SHARED_LIBS ON CACHE BOOL)

Is that correct?
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Laurent on April 14, 2021, 02:57:47 pm
Quote
This is not a CMake's default. BUILD_SHARED_LIBS should be manually defined and set to ON so that CMake builds a shared library instead of static one.
My bad, I didn't check. I always create shared libs, whether it is at home or at work. Adding SHARED to add_library has probably become automatic for me, so that I don't notice it anymore.

I really wonder why STATIC is the default on CMake.

I checked a few other projects, and about half were defining BUILD_SHARED_LIBS to ON by default. So I would say it really depends on what's the most suitable default for each project. And shared libs is the recommended default for SFML, so I wouldn't change anything.

What's wrong about having to turn this flag off?
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Elias Daler on April 16, 2021, 12:41:05 am
My bad, I didn't check. I always create shared libs, whether it is at home or at work. Adding SHARED to add_library has probably become automatic for me, so that I don't notice it anymore.
You don't actually need to do this - if BUILD_SHARED_LIBS is set to ON, the libraries will compile as shared ones. But if you explicitly do add_library(some_lib SHARED) then it can only be compiled as a shared library and never as a static one.

I really wonder why STATIC is the default on CMake.
Maybe it comes from Windows projects where shared linking is kinda painful, because you need to do all this dllimport/dllexport stuff + copying of dll's to the executable's directory.

What's wrong about having to turn this flag off?
It's just a bit surprising, because I don't expect something to build as shared lib by default, because I don't set BUILD_SHARED_LIBS, but the library does it for me.

Also it forces programs which use SFML to explicitly set BUILD_SHARED_LIBS to some value so that when you call add_subdirectory(SFML), SFML will respect that. Otherwise your program will link everything statically, but SFML will set BUILD_SHARED_LIBS flag and set it to "ON" for itself anyway and build itself as a shared lib, even though the parent application didn't tell it to build as a shared lib.

But yeah, I guess I'll just have to say people to explicitly set BUILD_SHARED_LIBS before calling add_subdirectory(SFML) if they want the flag to work right globally.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: eXpl0it3r on April 16, 2021, 12:45:50 am
When you say, SFML's CMake sets it to ON, do you mean implicitly by using the SHARED keyword? Because there's no explicit setting of the mentioned variable.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Elias Daler on April 16, 2021, 03:15:56 am
When you say, SFML's CMake sets it to ON, do you mean implicitly by using the SHARED keyword? Because there's no explicit setting of the mentioned variable.
No, I mean this line (https://github.com/SFML/SFML/blob/252d26afb0aa6375e08ef95b754cccf60f31b6df/CMakeLists.txt#L57).
Ideally there'd be no such option defined/set at all - it'd be up to the user to set it.

Discussion about "SHARED" was in a reference to what Laurent has said.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Laurent on April 16, 2021, 09:09:20 am
It's probably not ideal, but what other solutions do we have? We really want SFML to build as shared libraries by default, and we want to provide an option so that users can change that easily.

As far as I understand, your request was to switch to static build by default. This is really not desired, especially on Unix platforms.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Elias Daler on April 16, 2021, 12:34:14 pm
I think if there's a strong opinion that shared libraries should be the default, then it's okay to leave it as is, I suppose. Just wanted to have some discussions on whether this was an intentional choice or not.

I hope that some day CMake will have something better to indicate if you want to built a static or shared library instead of this "BUILD_SHARED_LIBS" flag. :)
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Thrasher on June 20, 2022, 06:20:54 pm
It's a very common source of frustration in the SFML Discord's #general channel having to copy SFML DLLs to the right directory to get their programs to run. I think it's worth reevaluating whether going against the CMake default is our best choice for SFML 3.

I'd love to hear more arguments for why some people think static libraries are "exotic." I've been writing C++ on Unix-y OSes for about 6 years now and static libraries always just silently worked and felt anything but exotic so I'm struggling to understand in more detail why the maintainers disagree.

Would you consider a middle ground solution where certain OSes default to shared libs and others to static libs? We have all the infrastructure to do that fairly easily.
Title: Re: (CMake) Make BUILD_SHARED_LIBS=OFF by default
Post by: Thrasher on February 03, 2023, 11:48:15 pm
https://github.com/SFML/SFML/issues/2389

I opened an issue to remove any reference to `BUILD_SHARED_LIBS` and thus change back to the CMake default of static libraries.