Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Linking dependencies  (Read 61590 times)

0 Members and 1 Guest are viewing this topic.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Linking dependencies
« Reply #30 on: October 15, 2013, 02:56:02 pm »
But what exactly happens now? What is the error?
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Linking dependencies
« Reply #31 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... ;)
« Last Edit: October 15, 2013, 03:15:47 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Linking dependencies
« Reply #32 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.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Linking dependencies
« Reply #33 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
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Linking dependencies
« Reply #34 on: October 15, 2013, 04:01:27 pm »
:'(
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Linking dependencies
« Reply #35 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...
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

FRex

  • Hero Member
  • *****
  • Posts: 1845
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Linking dependencies
« Reply #36 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
Back to C++ gamedev with SFML in May 2023

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Linking dependencies
« Reply #37 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).
Laurent Gomila - SFML developer

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Linking dependencies
« Reply #38 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.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Linking dependencies
« Reply #39 on: October 15, 2013, 10:56:26 pm »
You can look at the code here.

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.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Linking dependencies
« Reply #40 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 >_>
« Last Edit: October 15, 2013, 11:24:28 pm by Ixrec »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Linking dependencies
« Reply #41 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.
Laurent Gomila - SFML developer

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Linking dependencies
« Reply #42 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
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10801
    • View Profile
    • development blog
    • Email
Re: Linking dependencies
« Reply #43 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
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Linking dependencies
« Reply #44 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?
« Last Edit: October 15, 2013, 11:58:41 pm by Ixrec »