SFML community forums

General => General discussions => Topic started by: Tank on October 09, 2012, 04:13:37 pm

Title: Linking dependencies
Post by: Tank on October 09, 2012, 04:13:37 pm
Hi guys, hi Laurent,

I wanted to ask (again) about changing the way SFML links to dependencies. It has been discussed a bit in this thread already: http://en.sfml-dev.org/forums/index.php?topic=7602.0

When talking with some guys in #SFML (irc.boxbox.org) and ##MinGW (Freenode), and remembering the issues we had with SFGUI (double definitions at the linker stage, i.e. importing GLEW 2 times), I felt like bringing this back to the table again.

Let's identify the problem first: SFML itself links to libraries it's using, also internally only. Those libraries are provided as pre-built static libraries in the releases and also in the source snapshots/SCM.  When building SFML, it links those dependencies in, statically, i.e. the archives (/static libs) are packed into the final SFML library.

I think the main purpose of that is to ease using SFML, so that the user doesn't has to link to GLEW, OpenAL and all the other dependencies.

However, there are some problems that shouldn't be ignored and that can lead to severe errors and crashes under certain circumstances: If the target executable (i.e. the user program) imports the same dependecies that are already being defined in SFML, clashes might happen (especially when using different GLEW versions). Also the developer can't exchange the dependency, e.g. to upgrade to a later version. Both together can lead to severe problems when, for example, the ABI changes. In general the ODR (one-defition rule) seems to be violated.

The solution would be to throw away all target_link_libraries() calls in SFML's CMake scripts. However I'm not 100% sure if that works with MSVC too. Such a change would indeed require the end-user to link to all the deps himself, but in my opinion telling/teaching them the right way is better than going for an easy approach with accepting that fatal bugs might happen.
Title: Re: Linking dependencies
Post by: Laurent on October 09, 2012, 04:30:59 pm
Quote
The solution would be to throw away all target_link_libraries() calls in SFML's CMake scripts
You meant the sfml_static_add_libraries calls, right?
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 09, 2012, 04:57:03 pm
You meant the sfml_static_add_libraries calls, right?
Specially that one but the others aren't actually need either.
If I've understood the discussion in the channels correctly the idea of static linking is that all the dependencies should be linked in the final state.

It was me that started the discussion on ##mingw because ar.exe couldn't find the OpenGL library. Somewhere along the way SFML/CMake/whoever assumes that the libs are in ../lib/ folder seen from the GCC directory which is wrong for MinGW w64 (it's located in /mingw-VERSION/lib/). This then lead to the discussion, that SFML shouldn't even touch the opengl libs.

Anyways I've removed all the target_link_libraries() and build SFML succesfully, then I had to specify all the deps in my application and everything build without any problems. ;)
Title: Re: Linking dependencies
Post by: Laurent on October 09, 2012, 05:49:22 pm
But target_link_libraries is when building dynamic libraries. The thing we're discussing now, i.e. adding static libraries to SFML static libraries, is done with sfml_static_add_libraries. If you remove all target_link_libraries calls then dynamic SFML libraries will produce linker errors.
Title: Re: Linking dependencies
Post by: Tank on October 09, 2012, 05:57:34 pm
Quote
If you remove all target_link_libraries calls then dynamic SFML libraries will produce linker errors.
That's not the case on Linux, it just builds fine. Also with MinGW on Windows. Maybe MSVC works different here, can't comment on that.

But yes, I'm talking about packing other library's object code into SFML.
Title: Re: Linking dependencies
Post by: Laurent on October 09, 2012, 06:19:59 pm
Quote
That's not the case on Linux, it just builds fine. Also with MinGW on Windows. Maybe MSVC works different here, can't comment on that.
Wait... how can the linker produce a binary that uses xyz functions from a library, without linking to it? What you guys say doesn't make sense, but it's probably me missing something obvious or misunderstanding you ???
Title: Re: Linking dependencies
Post by: Tank on October 09, 2012, 06:29:43 pm
Because normally only symbols are referenced. The actual code gets linked into executable in the executable's linker step. When producing an executable, you always have to link to every single dependency, otherwise you get unresolved externals.

That's different for libraries. To satisfy ODR, libraries should not link to their own dependencies. Otherwise it might happen that both the library AND the executable link in the same object code, which can lead to serious problems like described in the first post.

Just try it: Write a source file that uses an external library's function (e.g. OpenGL) and compile and link it into a library, *without* linking to that external library. It won't produce any errors -- except MSVC works differently, I don't know if it does.

On Linux I could perfectly build SFGUI without linking to SFML at all. :)
Title: Re: Linking dependencies
Post by: binary1248 on October 09, 2012, 08:04:53 pm
I think the confusing part about this whole discussion is really what is involved in this ominous "linking" process. When the linker runs different things happen depending on what kind of linkage the developer wants for his binary.

For static linkage obviously a code copy has to be done so that the final executable is portable across systems with the same architecture. This means that the calls to the static library are just resolved by the linker to internal addresses within the same executable where the copy of the code resides. This however is only the case when compiling the final executable, not for libraries, except for the special case of SFML. If you have multiple copies of the same library in 2nd order libraries ODR will horribly fail because you confused the linker and it won't know which code source to use. This is why you only provide the code of the library when the final executable is built. There the "last developer" can specify the source of the code for a specific library and the linker will know where to copy it from to satisfy everything that is needed by the 2nd order libraries and the executable. If multiple libraries all included their dependencies in themselves it would be akin to someone building multiple copies of SFML (all with different names of course) and linking them all to his final executable. Because the names of the exported symbols are all the same across those libraries something is bound to go wrong.

When linking dynamically things get tricky. In this case the linker just produces a table of external symbols that are needed (linked in) when the code is executed. This seems to be the simpler linkage type, but if you consider that you can dynamically link to a library that statically linked a library that you dynamically link in your final executable.... it starts to get really messy. You have to be really careful here in order to avoid name clashes. Some libraries probably facilitate such complex linking by inserting tons of preprocessor macros for each scenario, but seriously... if it can be avoided, why do so in the first place. I already hate mixing linkage types and it seems that doing so isn't recommended in MSVC since they have a very exotic way of doing things in general. Windows also happens to be the only OS I know of that requires (as in not optional) the developer to explicitly mark functions that should be exported out of a dynamic library. Is this a result of their vendor lock-in non-cooperative paranoid software development paradigm? Possibly, but that is a discussion for another time.

GLEW is the reason why this discussion started in the first place, and it is a result of how GLEW is built. From what I can tell, GLEW defines many many global variables that are hidden behind a few layers of macros. These global variables tell you whether capability xyz is available on the hardware as well as provide addresses to the advanced OpenGL functions we all love to use. In order to fill these variables with meaningful data they have to be initialized at some point, which is why glewInit() needs to be called. I think the problem should be obvious now. When we in SFGUI want to call glewInit() to initialize the variables in order to use them (it doesn't work if we don't call it because SFML calling it doesn't affect the variables we can access) we need a reference to the GLEW code. This is already included in sfml-graphics but we can't access it under certain circumstances, so we try to link in another copy of GLEW. This also doesn't work because the name already exists in the executable space and thus the headache begins. We ended up using GLee, just because it uses different names for exactly the same functionality.

I think it will make the lives of library developers like myself much easier if SFML dealt with dependencies "normally". The external libs would just need to be copied into the same folder as the SFML libs and
Code: [Select]
g++ main.o -o sfml-app -lsfml-graphics -lsfml-window -lsfml-systemwould become something like
Code: [Select]
g++ main.o -o sfml-app -lsfml-graphics -lsfml-window -lsfml-system -lfreetype -lglew -ljpeg -lopenal32 -lsndfilebut I'm sure that's something that won't even bother newcomers.
Title: Re: Linking dependencies
Post by: Laurent on October 09, 2012, 08:41:39 pm
Quote
Just try it: Write a source file that uses an external library's function (e.g. OpenGL) and compile and link it into a library, *without* linking to that external library. It won't produce any errors
Hum ok, I never noticed that. I don't know why one would do that though, except adding more work for the final user. But that's another discussion... unless you also suggest that I remove dependencies from shared libraries (which I've never seen).

The problem is clear and well understood by everyone here (I think), thanks for summarizing it so well.

Quote
we need a reference to the GLEW code. This is already included in sfml-graphics but we can't access it under certain circumstances
Can you clarify this point? Since SFML embeds GLEW, you just don't have to (or "can't" :P) link your own version of it, but the result is the same, it gets included to the final executable.

Quote
I'm sure that's something that won't even bother newcomers.
The Linux example is straight-forward of course, most dependencies are already installed and are in standard paths, so it's just a matter of adding a few -lxxx. On Windows things are worse: you need to add include and linker search paths (to those extra static libs), and you need to add them in your linker settings. It's not a big deal, but for beginners who can't even follow the getting started tutorial, it will be definitely too much. And be sure to see a lot of posts concerning this on the forum.

I'm not saying I'm against the idea of handling static libs the way they should be, but a lot of people will see the disadvantages, and only a few will see the benefits.
Title: Re: Linking dependencies
Post by: binary1248 on October 09, 2012, 08:58:31 pm
Quote
we need a reference to the GLEW code. This is already included in sfml-graphics but we can't access it under certain circumstances
Can you clarify this point? Since SFML embeds GLEW, you just don't have to (or "can't" :P) link your own version of it, but the result is the same, it gets included to the final executable.
OK, imagine theoretically, SFGUI would remove all dependencies to SFML, which means SFML isn't needed to use SFGUI, SFGUI could use GLEW on it's own because we would link against it as already mentioned so many times. What would happen if someone wanted to use SFML and this new SFGUI together? It won't work because SFML includes GLEW in sfml-graphics and (just as an example) is linked dynamically. SFGUI is also linked dynamically but needs to link in GLEW at runtime. It won't work because there will be 2 GLEWs in the final executable, the one inside SFML and the dynamically linked one.

Quote
I'm sure that's something that won't even bother newcomers.
The Linux example is straight-forward of course, most dependencies are already installed and are in standard paths, so it's just a matter of adding a few -lxxx. On Windows things are worse: you need to add include and linker search paths (to those extra static libs), and you need to add them in your linker settings. It's not a big deal, but for beginners who can't even follow the getting started tutorial, it will be definitely too much. And be sure to see a lot of posts concerning this on the forum.

I'm not saying I'm against the idea of handling static libs the way they should be, but a lot of people will see the disadvantages, and only a few will see the benefits.
If the libs are in the same folder as the library files themselves and the headers in the SFML header folders there will be no extra overhead. Sure placing non-SFML headers in the SFML header folders is a bit unorthodox, but if it helps newcomers, why not. It is still less strange than including everything in the static library archive. The only extra work that has to be done is a copy from the extlibs folder into the library file destination and header folders. Since you would write the script for this the newcomer won't notice any file copying or extra compiler/linker search settings.
Title: Re: Linking dependencies
Post by: Laurent on October 09, 2012, 10:36:25 pm
Quote
It won't work because there will be 2 GLEWs in the final executable, the one inside SFML and the dynamically linked one.
I know that, but I was asking about the "we can't access it" part. So in fact it was just another way to refer to the "different versions linked together" problem? I thought you were talking about another problem.

Quote
If the libs are in the same folder as the library files themselves and the headers in the SFML header folders there will be no extra overhead.
I don't like the idea of mixing SFML and external libraries in the same folder. But yes, that could be another option, which is probably not worse than the current one I guess.
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 09, 2012, 10:52:29 pm
Quote
I don't like the idea of mixing SFML and external libraries in the same folder. But yes, that could be another option, which is probably not worse than the current one I guess.
Or you could also just copy the extlibs folder. Sure the users would then need to specify two paths but I guess this could work out...
Title: Re: Linking dependencies
Post by: binary1248 on October 10, 2012, 12:32:13 am
I know that, but I was asking about the "we can't access it" part. So in fact it was just another way to refer to the "different versions linked together" problem?
Yeah it's all one and the same problem with many different names.
Title: Re: Linking dependencies
Post by: Tank on October 10, 2012, 12:14:01 pm
Quote
I don't like the idea of mixing SFML and external libraries in the same folder. But yes, that could be another option, which is probably not worse than the current one I guess.
Understandable, however it's already the same with the DLLs that have to be shipped with SFML in order for it to work, like sndfile and OpenAL. The user has to know that those must be copied to the final executable -- and I don't see a lot of postings on the forum asking why the program crashes with asking about a DLL.

Like binary said, the advantage of the .lib files is that those can be simply copied to SFML's lib directory, i.e. where the sfml-* libraries are saved to, and the user doesn't has to add any more linker and/or compiler search paths (considering that headers of external libraries also also added to SFML's include directory).

Remember that this is nothing that can be avoided really. It really leads to problems, and working around those is either not possible (in SFGUI's case) or very annoying to do (e.g. cloning SFML's source code, removing linking to external libraries, rebuilding).

Regarding the newbies: IF they are reading the tutorials -- and I think the most do if they have never used a similar library before -- then it'll be just adding a few more external libs to the linker options. A positive side-note: Many users asking "Can I use SFML with OpenGL or DirectX?" on IRC will probably recognize that SFML indeed uses OpenGL when adding "opengl" to the linker options. ;)
Title: Re: Linking dependencies
Post by: Laurent on October 10, 2012, 01:46:10 pm
Quote
Like binary said, the advantage of the .lib files is that those can be simply copied to SFML's lib directory, i.e. where the sfml-* libraries are saved to, and the user doesn't has to add any more linker and/or compiler search paths (considering that headers of external libraries also also added to SFML's include directory).
But it automatically creates a conflict if the user has its own version of one library in another search path.
Title: Re: Linking dependencies
Post by: Tank on October 10, 2012, 09:16:55 pm
That's true, which reminds me of the first post:

Quote from: Tank
[...]in my opinion telling/teaching them the right way is better than going for an easy approach with accepting that fatal bugs might happen.

;)
Title: Re: Linking dependencies
Post by: Laurent on October 10, 2012, 09:22:10 pm
Hum..... .......... ......... .......... ..........

I'm really close to say "yes" ;D
Title: Re: Linking dependencies
Post by: binary1248 on October 11, 2012, 10:01:28 am
Actually no conflict would (or should) occur. Intelligent (whatever that means) compilers/linkers have a well-defined order of going through their search paths and looking for the bits and pieces it needs. As Tank said, part of learning to develop applications consists of understanding things like this. If e.g. in Linux you want the cutting edge version of a library and the package manager only provides some 3-year-old version of it, you can always build it yourself. If done right it should not overwrite the existing version of the library but rather reside in a path that is checked earlier by the compiler/linker. This is the famous /usr/local directory many Linux distros come with and make use of. AFAIR /usr/local is checked before /usr and as such it should work as expected.

Even in Windows compilers often come with default versions of some libraries. Just because I specify that it should look in my own library directories first doesn't mean that if it finds multiple copies it will crash and die. The first occurrence takes precedence.
Title: Re: Linking dependencies
Post by: Tank on October 11, 2012, 07:46:32 pm
Quote
This is the famous /usr/local directory many Linux distros come with and make use of. AFAIR /usr/local is checked before /usr and as such it should work as expected.
Correct, however afaik the most used distribution, our beloved Ubuntu, changed that. /usr/local/ isn't included in $PATH anymore. Cheers! ;)
Title: Re: Linking dependencies
Post by: Cornstalks on October 14, 2012, 05:10:42 am
Such a change would indeed require the end-user to link to all the deps himself, but in my opinion telling/teaching them the right way is better than going for an easy approach with accepting that fatal bugs might happen.
I'd like this, personally. Is it possible for it to be a CMAKE option? To me that would be a win-win.
Title: Re: Linking dependencies
Post by: Tank on October 24, 2012, 11:50:42 am
Have any decisions been made on this topic yet? ;)
Title: Re: Linking dependencies
Post by: Laurent on October 24, 2012, 11:59:48 am
No. My free time is so limited that I can hardly do anything that requires more than 10 minutes of my time.

:(
Title: Re: Linking dependencies
Post by: Tank on October 24, 2012, 01:00:03 pm
Sounds very familiar to me. ;)

I'll try to get some free minutes this evening to hack a patch.
Title: Re: Linking dependencies
Post by: Laurent on October 24, 2012, 01:01:49 pm
Thanks, but I wasn't talking about the time required to do the modification, but the time required to think about it and make a final decision ;D

Before doing so I'd like to test it like a beginner (i.e. setup a project with static SFML libraries), to see whether the extra configuration steps are reasonable or not.
Title: Re: Linking dependencies
Post by: Tank on October 24, 2012, 01:05:56 pm
I know, but I'd like to see how it works out, too. And even if you'll decide not to do the modification, I will have to use a fork, therefore I need a patch anyway.

Quote
to see whether the extra configuration steps are reasonable or not.
Keep in mind the modifications aren't for being pro, but eliminating serious problems. ;)
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 27, 2012, 12:37:04 pm
I'd really like to see this change to happen soon... :-\

Could you at least change the macro in a way that it doesn't assume the library path?
Because with mingw-w64 the libraries are not located in the root/lib but in root/some-strange-version-name/lib folder...
Also there should be x64 extlibs build for mingw. ;)
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 12:01:15 am
With the commit 5931236 (https://github.com/SFML/SFML/commit/593123685851c6a1983d3e378e055e9c1a96b339) where winmm has been added as dependency to sfml-system SFML is now in a state where it can't be built static with or without static runtime libraries on Windows with any MinGW version. I tested TDM 4.7.1, MinGW Builds POSIX SJLJ 8.4.1, Older Nuwen x86 4.7.1, new Nuwen x64 4.8.1, Old official MinGW version, official MinGW 4.8.1 version and even MinGW 4.9-testing, etc.
It was also tested on Windows 7 as well as 8.1 and others.

So why am I posting this here? Because this topic here is exactly the issue, why SFML is crashing in the linker. The macro that "magically" includes every dependency into SFML up on static linking leads to the case the both sfml-window and sfml-system have their own version of winmm and when linking both libraries ld crashes "somewhere".

Now that we have an even more concrete reason why including everything into SFML is a bad idea, can we finally get a change and throw that horrible macro out? Please? :D

If you want another topic for the issue specific and/or a ticket let me know!

Phew "wasted" 3 days to track this issue down...
Title: Re: Linking dependencies
Post by: FRex on October 15, 2013, 12:10:22 am
Quote
SFML is now in a state where it can't be built static with or without static runtime libraries on Windows with any MinGW version
As in: can't be built static by MinGW at all?

Quote
Phew "wasted" 3 days to track this issue down...
I'm giving you a considerable amount of brag-rights-currency for tracking that down.
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 12:26:44 am
As in: can't be built static by MinGW at all?
You can build the lib, but once you try to link the window and the system module and invoke winmm calls in each library ld will crash.
The following example is enough:

#include <SFML/Window.hpp>
#include <SFML/System.hpp>

int main()
{
    sf::Mouse::getPosition();
    sf::Clock clock;
}
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 02:50:11 pm
There's an easy fix by making the window module not depend on winmm and since it depends on the system module everything should be fine.

I bet this "solution" will chosen instead of solving the real issue here. :-\
Title: Re: Linking dependencies
Post by: Laurent on October 15, 2013, 02:56:02 pm
But what exactly happens now? What is the error?
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 03:05:46 pm
But what exactly happens now? What is the error?
There is no error, it simply crashes ld, i.e. the linker itself.

With MinGW 4.9. that has some debug info enabled we got the following assert:
c:/dev/mingw32-49posixsjlj/bin/../lib/gcc/i686-w64-mingw32/4.9.0/../../../../i686-w64-mingw32/bin/ld.exe: BFD (GNU Binutils) 2.23.2 assertion fail ../../../src/binutils-2.23.2/bfd/cofflink.c:2389

Which then leads to the source code like:
  /* Write the modified symbols to the output file.  */
  if (outsym > flaginfo->outsyms)
    {
      file_ptr pos;
      bfd_size_type amt;

      pos = obj_sym_filepos (output_bfd) + syment_base * osymesz;
      amt = outsym - flaginfo->outsyms;
      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0
          || bfd_bwrite (flaginfo->outsyms, amt, output_bfd) != amt)
        return FALSE;

      BFD_ASSERT ((obj_raw_syment_count (output_bfd)
                   + (outsym - flaginfo->outsyms) / osymesz)
                  == output_index);

      obj_raw_syment_count (output_bfd) = output_index;
    }

It just seems ld can't deal with having two different libraries that include both the same library, thus when trying to extract them into the binary (linking static etc.) it might come in a conflict of trying to write the same library data twice or something like that. Just random guessing why ld crashes.

Thus the real issue here is, that SFML is extracting the object files and includes them into SFML's library, instead of letting the user link everything statically in the final step, like how static linking should be done!

Making only sfml-system link to winmm, will resolve the crashing, since there will only be one version of winmm, but it won't fix the wrong way of linking static dependencies... ;)
Title: Re: Linking dependencies
Post by: Laurent on October 15, 2013, 03:44:26 pm
Quote
Making only sfml-system link to winmm, will resolve the crashing
But sfml-window does depend on winmm, I can't remove the dependency. It would get linked to it through sfml-system only in the case of static build.
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 03:51:31 pm
Quote
Making only sfml-system link to winmm, will resolve the crashing
But sfml-window does depend on winmm, I can't remove the dependency. It would get linked to it through sfml-system only in the case of static build.
True, so... :P
Title: Re: Linking dependencies
Post by: Laurent on October 15, 2013, 04:01:27 pm
:'(
Title: Re: Linking dependencies
Post by: binary1248 on October 15, 2013, 05:16:29 pm
This was bound to happen, a ticking time bomb if you will... unless you magically try to make sure that different modules never import functionality from the same external libraries you can't prevent this from happening, not with this symbol importing system. It is not meant to be done like that, so we probably won't get any support from the tool developers either... we shouldn't be surprised this doesn't work any more...
Title: Re: Linking dependencies
Post by: FRex on October 15, 2013, 05:45:55 pm
Quote
a ticking time bomb if you will
And it took only 1 year. Yaay. ;D

Quote
:'(
That post made me lol, serious discussion and then suddenly post with just that from Laurent.
As funny as that was, is linking policy now going to change for SFML? :P
Title: Re: Linking dependencies
Post by: Laurent on October 15, 2013, 10:36:21 pm
Ok, let's do it before I change my mind (I hope I can finish it before I go to sleep -- otherwise I may revert everything tomorrow :P).
Title: Re: Linking dependencies
Post by: Ixrec on October 15, 2013, 10:38:44 pm
While Laurent's off doing that, could someone explain to me what the evil macro is and why it's evil?  I didn't see any explanations here that made sense to me, though I don't know all that much about linking and frankly the subject kind of scares me, but I'd like to at least have some idea what this debate was about.
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 10:56:26 pm
You can look at the code here (https://github.com/SFML/SFML/blob/master/cmake/Macros.cmake#L15).

Usually when you link a library statically against it's dependencies it essentially means, that you don't link them at all. You just tell the compiler where to look for the headers so it can make sure to work his magic in checking types and allocating stuff. But since the dependencies code is still needed you'll have to link all the dependencies of your application plus the ones of your dependencies in your finally application.

Static libraries are just archives of obj files, thus what SFML does when build its static library is unpacking all the object files from the dependencies and includes those files directly into SFML's library. This is genius idea if you're just out for reducing everything to one library (aka helping out the newbies), but it's limiting and literally screams for issues, because if you want to use a different version of the included dependency library you can run into conflicts with SFML's own version.

The latest issue that forces a change from SFML's side is that both sfml-system and sfml-window include the object files of winmm into their library, thus sfml-system has a version of winmm and sfml-window has a version of winmm, when you're now trying to compile code that uses the functions from both libraries, the linker can't fully understand which objects to use and given that SFML sets -Wl, --no-whole-archive the linker doesn't get a chance to complain about duplicated symbols.

So the removal of the macro will make it a bit harder for new beginners, BUT they'll finally learn how to link things the right way, while the power users can finally use their own external dependencies and link all the static libs in a final step how's supposed to be.
Title: Re: Linking dependencies
Post by: Ixrec on October 15, 2013, 11:15:44 pm
I guess I don't quite understand how it'll actually affect us newbies.

If we use the pre-compiled binaries, then...they're already compiled, and we don't have to link SFML's dependencies, just SFML itself.  Right?

If we compile from source code, then we use CMake, and CMake magically finds the dependency libraries for us.  Right?

Edit: I keep reading your post and that .cmake file over and over and even though it all looks and feels and probably is totally straightforward I just don't get it.  I hate linking issues so much >_>
Title: Re: Linking dependencies
Post by: Laurent on October 15, 2013, 11:26:23 pm
Quote
If we use the pre-compiled binaries, then...they're already compiled, and we don't have to link SFML's dependencies, just SFML itself.  Right?
No. After the change you'll have to link SFML dependencies as well when you link SFML statically. Because when you build a static library, there's no link step, it's just an archive of compiled files. Linking only happens in the user project, so that's the only place where all dependencies can be linked.

The key here is to differenciate between compiling and linking. So although static libraries are already compiled, they are not linked to anything.
Title: Re: Linking dependencies
Post by: binary1248 on October 15, 2013, 11:35:18 pm
Code: [Select]
SFML Libraries:
+-----------+   +-----------+
| Library A |   | Library B |
|           |   |           |
| Depends:  |   | Depends:  |
| opengl32  |   | gdi32     |   ...
| winmm     |   | winmm     |
| ...       |   | ...       |
|           |   |           |
+-----------+   +-----------+

During building SFML statically, ar rcs does this:
+-----------+   +-----------+   +-----------+   +-----------+
| Library A |   |   winmm   |   | opengl32  |   | Library A |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |   Lib A   |
|  symbols  | + |  symbols  | + |  symbols  | = |  symbols  |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |
+-----------+   +-----------+   +-----------+   + - - - - - +
                                                |           |
                                                |           |
                                                |  opengl32 |
                                                |  symbols  |
                                                |           |
                                                |           |
                                                |           |
                                                + - - - - - +
                                                |           |
                                                |           |
                                                |   winmm   |
                                                |  symbols  |
                                                |           |
                                                |           |
                                                |           |
                                                +-----------+

+-----------+   +-----------+   +-----------+   +-----------+
| Library B |   |   winmm   |   |   gdi32   |   | Library B |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |   Lib B   |
|  symbols  | + |  symbols  | + |  symbols  | = |  symbols  |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |
+-----------+   +-----------+   +-----------+   + - - - - - +
                                                |           |
                                                |           |
                                                |   gdi32   |
                                                |  symbols  |
                                                |           |
                                                |           |
                                                |           |
                                                + - - - - - +
                                                |           |
                                                |           |
                                                |   winmm   |
                                                |  symbols  |
                                                |           |
                                                |           |
                                                |           |
                                                +-----------+

When linking to both Library A and Library B statically ld does this:
+-----------+   +-----------+   +-----------+   +-----------+   
|  Program  |   | Library A |   | Library B |   |  Program  |
|           |   |           |   |           |   |           |
|  Program  |   |   Lib A   |   |   Lib B   |   |  Program  |
|  symbols  | + |  symbols  | + |  symbols  | = |  symbols  |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |
+-----------+   + - - - - - +   + - - - - - +   + - - - - - +
                |           |   |           |   |           |
                |           |   |           |   |           |
                |  opengl32 |   |   gdi32   |   |   Lib A   |
                |  symbols  |   |  symbols  |   |  symbols  |
                |           |   |           |   |           |
                |           |   |           |   |           |
                |           |   |           |   |           |
                + - - - - - +   + - - - - - +   + - - - - - +
                |           |   |           |   |           |
                |           |   |           |   |           |
                |   winmm   |   |   winmm   |   |   Lib B   |
                |  symbols  |   |  symbols  |   |  symbols  |
                |           |   |           |   |           |
                |           |   |           |   |           |
                |           |   |           |   |           |
                +-----------+   +-----------+   + - - - - - +
                                                |           |
                                                |           |
                                                |  opengl32 |
                                                |  symbols  |
                                                |           |
                                                |           |
                                                |           |
                                                + - - - - - +
                                                |           |
                                                |           |
                                                |   gdi32   |
                                                |  symbols  |
                                                |           |
                                                |           |
                                                |           |
                                                + - - - - - +
                                                |           |
                                                |           |
                                                |           |
                                                |   winmm   | <-----+
                                                |  symbols  |       |
                                                |           |       |
                                                |           |    ld sends
                                                + - - - - - +  it's regards
                                                |           |   and crashes
                                                |           |       |
                                                |           |       |
                                                |   winmm   | <-----+
                                                |  symbols  |
                                                |           |
                                                |           |
                                                +-----------+

We want this to happen when linking SFML libraries statically:
+-----------+   +-----------+   +-----------+   +-----------+   +-----------+   +-----------+   +-----------+
|  Program  |   | Library A |   | Library B |   |  opengl32 |   |   gdi32   |   |   winmm   |   |  Program  |
|           |   |           |   |           |   |           |   |           |   |           |   |           |
|  Program  |   |   Lib A   |   |   Lib B   |   |  opengl32 |   |   gdi32   |   |   winmm   |   |  Program  |
|  symbols  | + |  symbols  | + |  symbols  | + |  symbols  | + |  symbols  | + |  symbols  | = |  symbols  |
|           |   |           |   |           |   |           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |   |           |   |           |   |           |
|           |   |           |   |           |   |           |   |           |   |           |   |           |
+-----------+   +-----------+   +-----------+   +-----------+   +-----------+   +-----------+   + - - - - - +
                                                                                                |           |
                                                                                                |           |
                                                                                                |   Lib A   |
                                                                                                |  symbols  |
                                                                                                |           |
                                                                                                |           |
                                                                                                |           |
                                                                                                + - - - - - +
                                                                                                |           |
                                                                                                |           |
                                                                                                |   Lib B   |
                                                                                                |  symbols  |
                                                                                                |           |
                                                                                                |           |
                                                                                                |           |   ld is happy and gives us our executable
                                                                                                + - - - - - +
                                                                                                |           |
                                                                                                |           |
                                                                                                |  opengl32 |
                                                                                                |  symbols  |
                                                                                                |           |
                                                                                                |           |
                                                                                                |           |
                                                                                                + - - - - - +
                                                                                                |           |
                                                                                                |           |
                                                                                                |   gdi32   |
                                                                                                |  symbols  |
                                                                                                |           |
                                                                                                |           |
                                                                                                |           |
                                                                                                + - - - - - +
                                                                                                |           |
                                                                                                |           |
                                                                                                |   winmm   |
                                                                                                |  symbols  |
                                                                                                |           |
                                                                                                |           |
                                                                                                |           |
                                                                                                +-----------+
In static build, SFML does the linking of all it's dependencies for you, just for your convenience, at the expense of not conforming to convention. You could say it pretends to be GLEW, winmm and all those other libraries, so your linker won't complain when you don't link to them yourself. Now you can just include just the SFML libraries and your application will happily build. In the system we want, you will have to link to those libraries yourself, because SFML won't pretend to be them any more (this is overly simplified but I hope you get the point).

This means in your project linker settings, you will need to specify opengl32 gdi32 winmm glew openal etc. But this is such wide-spread convention every C++ programmer is expected to know and understand how to do this already. The only people who benefit from the current system are thus the beginners to C++ who have difficulty setting up their linker settings properly, but this is something SFML should aim to teach them as early as possible (and seriously... it only has to be done once per project so it's not like it saves any real time). With these changes SFML will be linked just like every other library out on the market, and the tools will behave normally again and all those dreaded side-effects (i.e. GLEW & friends) will magically disappear and we can start using them in the standard ways again.

If you really want to understand all the details of how compiling and linking in both modes works, you should read up on it or watch a video on it somewhere... it is simply too much information to put in a forum post.
I provided some information for another interested person already here:
http://sfgui.sfml-dev.de/forum/post775.html#p775
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 15, 2013, 11:39:17 pm
I guess they already said everything, but I didn't want to waste my ASCII diagram either, so here you go. :D

First is the current situation, second is the future situation.
          winmm   gdi32   opengl
           /  \     |     /
          /    \    |    /
         v      v   v   v
sfml-system-s  sfml-window-s
         \      /
          v    v
       example.exe


sfml-system-s  sfml-window-s  winmm  gdi32  opengl
         |         |           |       |      |
         | +-------+           |       |      |
         | | +-----------------+       |      |
         | | | +-----------------------+      |
         | | | | +----------------------------+
         | | | | |
         v v v v v
        example.exe
Title: Re: Linking dependencies
Post by: Ixrec on October 15, 2013, 11:53:57 pm
Okay, I think it makes perfect sense to me now.  Thanks for putting so much effort into all the ASCII charts just to deal with my stupidity.

Now my concern is purely practical.  Sticking to Windows here (on Linux the precompiled binaries never worked for me anyway so I had to compile from source there), would the list of library names we have to tell Visual C++ to link against be a constant?  Or would we have to worry about different lists of libraries depending on what iteration of Windows we have?  If it's a fixed list then I agree there's not much of a problem and it wouldn't make the tutorials difficult at all (unless you're one of those many, many people who can't seem to read directions anyway...).

P.S.: How do most C++ devs learn this stuff?  Every textbook/tutorial/class/guide I've seen/used for people new to C++ says NOTHING about pragmatic linking issues (they define conceptually linking but never mention what's involved in linking to other people's code).  So did you all have to learn this stuff through aimless googling and asking stupid questions on forums?
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 16, 2013, 12:16:06 am
Now my concern is purely practical.  Sticking to Windows here (on Linux the precompiled binaries never worked for me anyway so I had to compile from source there), would the list of library names we have to tell Visual C++ to link against be a constant?  Or would we have to worry about different lists of libraries depending on what iteration of Windows we have?
It shouldn't change as long as SFML doesn't add/change dependencies.

P.S.: How do most C++ devs learn this stuff?  Every textbook/tutorial/class/guide I've seen/used for people new to C++ says NOTHING about pragmatic linking issues (they define conceptually linking but never mention what's involved in linking to other people's code).  So did you all have to learn this stuff through aimless googling and asking stupid questions on forums?
Well I'm not sure if there are "C++ books" that teach such things in depth, but there are official documents of compilers and alike in the internet. Yes they are hard to read, but they'll teach you about anything you would ever want to know or even more.
Personally I've learned a lot by experimenting and chatting with more experienced people on IRC, but even to this day I don't understand everything fully.
I'd say, I really learned A LOT about CMake, MinGW and compiling/linking by setting up FlexWorld on Windows. I sat about two full days on the PC figuring out what's going on in those CMake files and try to fix issues with MinGW and since FlexWorld depended on at lot of libraries it trained me the hard way how to link them. But a lot of important inputs came from Tank, so I doubt it's possible to learn everything just by trying, one needs some sort of source.

Also I've bookmarked this (http://en.sfml-dev.org/forums/index.php?topic=7281.msg48091#msg48091) for a while, it contains some nice info, but doesn't go too much into detail.
Title: Re: Linking dependencies
Post by: Tank on October 16, 2013, 08:56:09 am
Just wanted to say thank you for the change! And guys, I like old-school stuff very much, but: http://www.yworks.com/de/products_yed_about.html ;)
Title: Re: Linking dependencies
Post by: Ixrec on October 16, 2013, 09:12:42 am
That looks amazing O_O  I am never using PowerPoint for graphs again.  Would be nice if it could magically plug in to doxygen somehow.

Once the evil macro is banished I'll try compiling the latest sources to make extra sure it's still newbie-friendly, since I'm the closest thing to a newbie in this thread.
Title: Re: Linking dependencies
Post by: Nexus on October 16, 2013, 10:11:10 am
This means in your project linker settings, you will need to specify opengl32 gdi32 winmm glew openal etc. But this is such wide-spread convention every C++ programmer is expected to know and understand how to do this already.
I don't remember doing this all the time, for a lot of libraries it's fine to link a single target (but maybe it's because I linked dynamically). Specifying all the low-level libraries is annoying even for non-beginners, because you have to memorize implementation details (that may even change over versions).

Don't forget that on Windows, it's not unusual to make use of automatic linking. Boost does this for example, and it might also be something to consider for SFML.

So did you all have to learn this stuff through aimless googling and asking stupid questions on forums?
MSDN is a good source for Windows-related development. I also learned a lot with Thor and its CMake configuration. But CMake itself was quite a pain to learn, because I hardly found clean, bigger examples...
Title: Re: Linking dependencies
Post by: binary1248 on October 16, 2013, 10:48:10 am
I don't remember doing this all the time, for a lot of libraries it's fine to link a single target (but maybe it's because I linked dynamically). Specifying all the low-level libraries is annoying even for non-beginners, because you have to memorize implementation details (that may even change over versions).
On Windows, for development of Windows applications that open up a window and do stuff interacting with the operating system, it doesn't matter what library you use, you will always need to link against winmm user32 gdi32 etc. So it isn't really a matter of memorizing implementation details (because it is always present regardless of library used), it's because the Windows executable loader doesn't do it for you automatically. On Linux and I guess OS X you need to do the same, randr X11 etc. So it's really just boilerplate, and has nothing specific to do with SFML. If you specify more than you need, the linker will just discard the superfluous stuff. But really... boilerplate project settings is something that I don't want to start complaining about ;) It is an O(1) operation after all. A simple solution to this would be to provide templates for the popular IDEs that SFML already has support for in its tutorials. It would be a welcome addition :).

Don't forget that on Windows, it's not unusual to make use of automatic linking. Boost does this for example, and it might also be something to consider for SFML.
Correct me if I'm wrong, but this automatic linking you refer to, wouldn't be that #pragma lib directive we've all seen would it? If so, this isn't portable since it isn't supported by GCC. See the note here (http://www.boost.org/doc/libs/1_54_0/more/getting_started/windows.html#link-your-program-to-a-boost-library). Don't know if clang breaks tradition and has support for it or not.
Title: Re: Linking dependencies
Post by: Nexus on October 16, 2013, 11:01:22 am
Correct me if I'm wrong, but this automatic linking you refer to, wouldn't be that #pragma lib directive we've all seen would it? If so, this isn't portable since it isn't supported by GCC.
Ok, then at least provide it for Visual Studio users. The g++ guys should finally introduce something like that, too :P

On Windows, which libraries would one now have to link explicitly that weren't necessary before?
Title: AW: Re: Linking dependencies
Post by: eXpl0it3r on October 16, 2013, 11:03:11 am
I don't remember doing this all the time, for a lot of libraries it's fine to link a single target (but maybe it's because I linked dynamically). Specifying all the low-level libraries is annoying even for non-beginners, because you have to memorize implementation details (that may even change over versions).
As said before you still can do things as always with dynamic linking. Only static linking is affected by these changes.
It only seems bad because many Windows libraries make it too easy. It's totally normal to link against all the dependencies and no you don't need to know implementation details, you only need to know its dependencies. We Windows user are a bit spoiled anyways, because we don't need to install any dependencies at all, they are either integrate into Windows or get ship with SFML as precompiled libraries.

If it's too much asked for some people, then they might want to stick with shared libraries. ;)

Don't forget that on Windows, it's not unusual to make use of automatic linking. Boost does this for example, and it might also be something to consider for SFML.
What do you mean with "automatic linking"?
Title: Re: Linking dependencies
Post by: binary1248 on October 16, 2013, 11:17:31 am
https://github.com/SFML/SFML/blob/master/src/SFML/System/CMakeLists.txt
https://github.com/SFML/SFML/blob/master/src/SFML/Network/CMakeLists.txt
https://github.com/SFML/SFML/blob/master/src/SFML/Window/CMakeLists.txt
https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/CMakeLists.txt
https://github.com/SFML/SFML/blob/master/src/SFML/Audio/CMakeLists.txt

All the libraries passed as EXTERNAL_LIBS to sfml_add_library. All of those in system, window and network are Windows specific (winmm, user32, gdi32, ws2_32) and will always be provided with any compiler/SDK bundle. The others specific to graphics and audio are openal32, glew32 (although sometimes this one is often provided as well), sndfile, jpeg and freetype. Laurent will need to set CMake up so they are copied to the SFML library install directory next to the SFML library files so the linker will be able to find them as well when linking them into projects.
Title: Re: Linking dependencies
Post by: FRex on October 16, 2013, 11:21:07 am
Quote
What do you mean with "automatic linking"?
#pragma comment(lib,"somelibyouwannadd.lib") probably, headers that have this pragma and add libs to libs list. Boost does that on visual so you don't have to type something that looks like boost_fs_vs10_hello_man_what_up_1_53_lib_static.lib all the time.
Title: Re: Linking dependencies
Post by: binary1248 on October 16, 2013, 12:01:30 pm
Oh, and I just discovered that Visual Studio goes ahead and links against all the common Windows libraries already by default:
Code: [Select]
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib
They are under "inherited values" so I guess they are part of the default configuration Visual Studio applies to all projects. Who thought a simple Hello World application could tax the linker this much? ;)
Title: Re: Linking dependencies
Post by: Laurent on October 16, 2013, 08:53:59 pm
Done.

Now please do me a favor: answer to all those people that use the latest revision of SFML and will post here because of linker errors -- until the next release and its updated tutorials :P
Title: Re: Linking dependencies
Post by: binary1248 on October 16, 2013, 09:05:48 pm
There are 2 kinds of people, no not 10, 2... those that know how to link, and those who don't know how to link. Take your pick which ones would have posted here anyway ;). We are prepared :).

P.S. Maybe someone would be kind enough to update the FAQ? Laurent seems to hint at this becoming an FAQ (singular) :P.
Title: Re: Linking dependencies
Post by: Nexus on October 17, 2013, 02:44:52 pm
Do you plan to update FindSFML.cmake, such that the SFML_LIBRARIES variable also contains the dependencies? Or maybe create a new variable?
Title: Re: Linking dependencies
Post by: Laurent on October 17, 2013, 02:57:44 pm
Quote
Do you plan to update FindSFML.cmake, such that the SFML_LIBRARIES variable also contains the dependencies? Or maybe create a new variable?
It seems like a good idea.
Title: Re: Linking dependencies
Post by: Nexus on October 18, 2013, 08:38:33 pm
Tell me if I can help you somehow :)

It would only affect Windows, wouldn't it? Do you rather want to add everything to SFML_LIBRARIES or create a separate variable SFML_DEPENDENCIES? I'm thinking of scenarios where one of the dependencies is also linked besides SFML (as it was the case for GLEW in SFGUI); maybe it would be good to have separate variables for the "core" SFML libraries and the dependencies...

Also, these variables should probably include Windows libraries, e.g. winmm.lib?
Title: Re: Linking dependencies
Post by: Laurent on October 18, 2013, 09:49:36 pm
If I do it I think I'll support all OSes, even if static linking is discouraged on Linux I can't provide a half-implemented feature.

All non-default libraries will be included, i.e. everything that I have to link myself for SFML. So yes, winmm will be part of it.

I initially wanted to put them in SFML_LIBRARIES directly, but you're right, if someone wants to use its own version of a library, it will become tricky :-\
Title: Re: Linking dependencies
Post by: binary1248 on October 19, 2013, 02:15:54 am
SFML should follow what other libraries already do with their _LIBRARIES variable in CMake... just specify the libraries actually provided by SFML. Nobody tosses all of their dependencies into their _LIBRARIES variable, otherwise you would see OpenGL and the rest of the operating system libraries in scripts like FindGLUT.cmake as an example. I'm guessing that it is convention and already expected that the user will link to the correct operating system libraries on their own.

When SFML looks for it's dependency packages, on Linux (and OS X?) it works perfectly, since everything is installed in a central location and whatever the user would want to use, they would have already installed as a package anyway, so the issue of the user wanting to use their own version of whatever library doesn't exist.

The problem on Windows is that CMake has no idea where the user might be hiding their libraries, so without explicitly asking or getting the information from a special environment variable, it has to assume there is none available. In this case, if the user wanted to use their own version of a library, they would simply specify it to CMake using the provided variables when configuring SFML.

If a user is dumb enough to use 2 different library versions, or let SFML use the "default" one and then use their own in their project, then they really can't complain that it won't work. On the other hand, since some distributions of MinGW come with e.g. GLEW and freetype installed into the compiler's directories already, SFML should try harder to use those instead of it's own. I have one of these distributions, and the Find scripts still prefer to use the libraries provided with SFML instead of the ones in my compiler folders. Good thing I don't use them in my projects... otherwise who knows what would happen.
Title: Re: Linking dependencies
Post by: Wizzard on October 19, 2013, 11:53:28 pm
Using MinGW I did the following setup:

Defines
GLEW_STATIC
SFML_STATIC
UNICODE

Libraries
sfml-audio-s
sfml-graphics-s
sfml-network-s
sfml-window-s
sfml-system-s
sndfile
openal32
jpeg
glew
freetype
ws2_32
gdi32
opengl32
winmm

It compiles and runs just fine - but I might be doing too much
Title: AW: Re: Linking dependencies
Post by: eXpl0it3r on October 20, 2013, 08:03:39 am
It compiles and runs just fine - but I might be doing too much
If you link all SFML modules then the list seems to be the same as mine. ;)
Title: Re: Linking dependencies
Post by: Nexus on October 24, 2013, 04:55:35 pm
Laurent, can we help somehow with the FindSFML module?

I'm currently figuring out how to handle the paths to the dependencies the best way. Many of the binaries are installed in the directory ${SFML_ROOT}/lib, however some (such as OpenGL) are provided by the operating system. Would it be necessary to refer to the corresponding CMake modules?

On Linux, I'm not sure at all -- there may be a lot of system libraries required (similar to winmm.lib on Windows). Let alone OS X...
Title: Re: Linking dependencies
Post by: Laurent on October 24, 2013, 05:05:34 pm
We should definitely find a solution quickly, I'm currently stuck with CSFML which is exactly in this case: it links SFML statically and uses FindSFML.cmake ;D

But it's complicated. The options are:

1. FindSFML.cmake provides a list of libraries names, it's up to the user to find them -> very inconvenient
2. FindSFML.cmake finds the dependencies and provides full paths -> what if user wants to use its own version of a library?
3. Don't do anything, like all other libraries seem to do and let the user handle dependencies on its own -> really inconvenient, especially in case of multi-platform programs
Title: Re: Linking dependencies
Post by: Nexus on October 24, 2013, 05:11:52 pm
2. FindSFML.cmake finds the dependencies and provides full paths -> what if user wants to use its own version of a library?
This looks like the way to go.

My suggestion: We define a SFML_DEPENDENCIES variable with the full paths to all dependencies. I could write a prototype, but I'm uncertain about the points I mentioned in the last post.

For more customization, it would still be possible to define single variables such as SFML_DEPENDENCY_GLEW, so SFML_DEPENDENCIES would just be a list of them. But at the moment, it's important that linking works again ;)
Title: Re: Linking dependencies
Post by: binary1248 on October 24, 2013, 05:16:13 pm
Just give the user a choice. If they don't care, they can let SFML handle everything. If they care (like me) they add everything themselves. If they do both, they burn ;D.
Title: Re: Linking dependencies
Post by: Nexus on October 24, 2013, 05:28:00 pm
Actually, we could set SFML_DEPENDENCIES to the default paths of all dependencies, and the user would then still be free to edit it (very easy in the CMake GUI). This is already much better than the status quo, where everybody has to rewrite the non-trivial CMake code to find the correct dependencies.

This approach is a problem, if the user wants to configure SFML programmatically from another script that calls CMake. He would then have to painfully extract and replace the paths he likes :P that's why we can think about the single variables later...
Title: Re: Linking dependencies
Post by: eXpl0it3r on October 24, 2013, 06:02:57 pm
Yes, if the users gets the chance to only change a variable rather than having to change CMake code itself, then this sounds like a good way.
People that want to automate things and use "non-standard" libraries, should be able to write some small CMake magic, besides CMake still kind of encourages such hacks... ;)

We should definitely find a solution quickly, I'm currently stuck with CSFML which is exactly in this case: it links SFML statically and uses FindSFML.cmake ;D
I've noticed, since I can't build my Nightly Builds for CSFML either. ;D
Title: Re: Linking dependencies
Post by: Laurent on October 24, 2013, 08:59:51 pm
Or maybe SFML could try to find the libraries, except for those that are already defined? In this case SFML would use what's already defined, this way the user would just have to find GLEW or whatever before finding SFML; it could even work automatically (FindGLEW.cmake does problably nothing if GLEW_FOUND, GLEW_LIBRARY etc are already defined).
Title: Re: Linking dependencies
Post by: Nexus on October 25, 2013, 08:19:58 am
That's a good idea.

I'm not sure if you can rely on the other CMake modules to do nothing if you request them (i.e. to expect them not to override any settings). If not, you could check whether an output variable is already defined (-> command reference (http://cmake.org/cmake/help/v2.8.8/cmake.html#command:if)):
if(DEFINED GLEW_FOUND)
Title: Re: Linking dependencies
Post by: Laurent on October 25, 2013, 08:26:39 am
There's one problem though: not all these libraries have a standard FindXxx.cmake script, with well-known variables to check. Some of them use a home-made script, and some others such as system libraries are not searched at all, their name is directly used in the target_link_libraries command. However I don't think users will want to link another version of the system libraries ;D

So there would be a problem only for GLEW and libsndfile.
Title: Re: Linking dependencies
Post by: Nexus on October 25, 2013, 08:28:30 am
At the moment, you somehow find them too, can't you apply the same approach again?

Maybe it will be necessary to handle corresponding variables to allow customization...
Title: Re: Linking dependencies
Post by: Laurent on November 04, 2013, 10:47:13 pm
I've done something. Now FindSFML.cmake provides a list of all dependencies (full path to libraries) per component or globally.

Tested on Windows (VC++ and gcc), not on Linux nor OS X. Linux may require some adjustements, and OS X is probably totally broken; but hopefully nobody will try to link SFML statically on these platforms until I get more help ;)

Customization of one or more paths is probably not straight-forward with this way of doing things, but at least things can work out-of-the box again.
Title: Re: Linking dependencies
Post by: Nexus on November 05, 2013, 03:32:47 pm
Nice, thank you! I have used SFML_DEPENDENCIES in Thor, and at least on Windows (Visual Studio + MinGW) it worked :)
Title: Re: Linking dependencies
Post by: eXpl0it3r on November 05, 2013, 04:30:18 pm
Yay! ;D

Would it be possible to adjust CSFML as well, or does that work out of the box?
Title: Re: Linking dependencies
Post by: Laurent on November 05, 2013, 04:33:37 pm
CSFML is already adjusted, since it was my test case.
Title: Re: Linking dependencies
Post by: eXpl0it3r on November 05, 2013, 04:41:12 pm
Oh my fault, I was sure, I had CSFML on my GitHub watch list, seems like I didn't. :)

Cool! So I'll look into pushing out a complete set of Nightly Builds "soon".
Title: Re: Linking dependencies
Post by: Tank on November 05, 2013, 09:26:04 pm
So how does this work in detail now? My proposal would have been to provide an option for disabling looking for dependencies completely. If the option is not given, SFML tries to satisfy them, which is also the default.
Title: Re: Linking dependencies
Post by: Laurent on November 05, 2013, 10:07:54 pm
In case of static link, SFML tries to locate the libraries it depends on, in standard paths and in ${SFML_ROOT}/lib (i.e. the same search paths as for the SFML libraries themselves).

If they are found, they are added to ${SFML_DEPENDENCIES} and ${SFML_XXX_DEPENDENCIES}, where XXX is the name of the corresponding module.

If one or more are not found, the expected behaviour is triggered (fatal error if REQUIRED, nothing if QUIET, information message otherwise).

I haven't really thought about customization yet, so suggestions are welcome ;)

Title: Re: Linking dependencies
Post by: c0d3r9 on February 06, 2018, 02:19:56 am
Sorry that i grab out this old thread.
Have anybody a list of the libs how i have to add?

I try it with codelite with self maked sfml but it seems the list is not correct filled.

edit: all fine....only a little bit honey in my head