SFML community forums

General => General discussions => Topic started by: Mars_999 on April 15, 2012, 08:44:22 am

Title: GLEW and not exporting the GLEW symbols in SFML
Post by: Mars_999 on April 15, 2012, 08:44:22 am
I have to ask why this isn't possible.... With some many great projects using SFML, seems almost insane that one can't access GLEW to keep external libs to a minimum while using this great lib....

I asked SFGUI why they used GLEE which is dead... and the answer is here

http://sfgui.sfml-dev.de/forum/topic87-glee-vs-glew.html

and since SFML is using GLEW and so do I, why do I need to include it again in my project...

Please explain this insanity.... Thanks!
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 15, 2012, 10:45:54 am
Aaaahhh my old friend binary1248. I love his posts, and it's always a pleasure to answer ;D

Quote
Then, out of pure coincidence we discovered to our dismay, yet another hindrance to the free usage of advanced OpenGL hidden within the CMake macros of SFML (https://github.com/SFML/SFML/blob/master/cmake/Macros.cmake#L149)
The highlighted line has nothing to do with the "problem". It just makes sure that SFML won't export its private classes and functions; this thing doesn't prevent your own app from linking against GLEW.
And... removing it wouldn't be enough to properly export GLEW in SFML libraries.
And... it applies on Linux and OS X only, whereas the "problem" is on Windows only (see below).

Quote
We wondered why he who maintains SFML would seek to hide such power from us. Alas there is but a reason for the many undertakings he has gone through, a mere "too complicated".
Did I really say that?
The answer is simple: GLEW is an implementation detail, it doesn't have to be exported by SFML. It would be crazy if every library exported all the functions and classes from the libraries that they use internally. Nobody does that.

And, most important: what binary1248 forgot to tell you is that there is a problem only on Windows when you link SFML statically and GLEW dynamically -- all other scenarios work fine.
And this is a problem only because SFML performs special extra steps on its static libraries: it literally copies its dependencies in its own libraries, so that you don't have to link all of them to your final app (yes, that's how static libraries are supposed to behave, they are not linked to their dependencies, they are just archives of compiled files). But then you would have to link to the same version of GLEW as SFML uses, namely the static one, which currently already works fine. So, it wouldn't change anything in fact.

Unfortunately, static link is currently required in order to avoid a SFML bug at application exit. But this will have all my attention and will hopefully be solved soon.

I truly like binary1248 and Tank feedback, they are experienced C++ programers who have a valuable point of view on SFML, but I would appreciate a little less aggressiveness and biased comments. I'm always open to discussions, there's no need to be so angry...
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 15, 2012, 10:58:21 am
I'd like to add a little something:

Quote
since SFML is using GLEW and so do I, why do I need to include it again in my project...
That's why shared libraries exist, and why they are by far the best option for libraries that depend on other libraries.
Static libraries... if Windows had a better way to manage DLLs (or, more precisely, if people knew how to manage them properly on Windows), we wouldn't need static libraries at all.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Mars_999 on April 15, 2012, 04:32:57 pm
Thanks.

I was unsure, and I only hope the GLEW version you use vs. one I would use in my projects doesn't cause any issues... That's all. Since I am sure I will be using a newer version....
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 15, 2012, 06:11:39 pm
Before writing my answer I made some tests, with a newer version than the one which is used by SFML. Everything worked fine :)
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: binary1248 on April 15, 2012, 06:37:17 pm
Quote
It would be crazy if every library exported all the functions and classes from the libraries that they use internally. Nobody does that.

It would also be crazy if every library included the static library archives they depend on into their own and not export them don't you think? The only reason I see that sfml-graphics includes the GLEW lib into itself is so that people don't have to type a (for me quite acceptable) -lGLEW in every one of their SFML projects. Static libraries don't go through the link step for a reason: they are just archives of precompiled code ready to be integrated somewhere. The final link step which is done when an executable is built looks for the dependencies and links them properly. Pretending that GLEW is always there without it being in a separate archive makes it even more confusing than just saying "by the way SFML depends on GLEW so you will have to link against it also". Sure it is simpler for those who have no idea what we are talking about here, but for those who do need to use GLEW, we have to link against it in out final app anyway so why not be friendly and share the archive among libraries? That's what they are for after all.

Quote
# this macro adds external dependencies to a static target,
# compensating for the lack of a link step when building a static library.
# every compiler has its own way of doing it:
# - VC++ supports it directly through the static library flags
# - MinGW/gcc doesn't support it, but as a static library is nothing more than an archive,
#   we can simply merge the external dependencies to our generated target as a post-build step
# - for other compilers and OSes, static build is not encouraged so we don't try to
#   pre-link dependencies, we just "link" them so that the SFML samples can compile
#   out-of-the-box (CMake forwards the dependencies automatically)

Just a warning, just because MSVC does something, it doesn't mean that that is the standard way of doing it. This quoted comment has me worried a bit. I assume you already know the difference between true linking and just including archives into each other. You said for other compilers and OSes static build isn't encouraged because you can't perform this archive inclusion for them. Don't you think they have a reason for that? It's because it isn't the standard way of doing things. I assume MinGW/gcc/ar has this functionality for totally different reasons (I've even combined all SFML libraries into one before just to speed up building) but forcing it when building SFML? I'd leave that to the user to decide. Maybe something like INCLUDE_STATIC_LIBS in CMake or something. And in case anybody didn't know you can disable that archive inclusion functionality in MSVC too although enabled by default.

And just for the record, I am (and Tank is also) against all simplifications that are made to cater to people not willing to learn how compiling and linking works. But you should have figured that out by now ;)

And about fvisibility,

Quote
# If using gcc >= 4.0 or clang >= 3.0 on a non-Windows platform, we must hide public symbols by default

Is that a miswording? Because saying "must" to me means there is no other way to do it. You probably have all the alleged performance improvements in mind, but remember this varies from case to case and looking at the size of the symbol tables in the SFML libraries I don't see why this is needed.

Reading through the SFML CMake configuration I also can't help but have this strange feeling that SFML really encourages one to link dynamically on Linux and Windows at all costs. Being a fan of static linking on Windows and seeing how many things are broken when static linking SFML I can only hope that the situation improves in the future. While performing my profiling on Windows and Linux, static linking everything makes it so much easier, which is why I also like to static link on Linux just for that purpose. I'd like to see more support for this too in the future.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 15, 2012, 08:16:48 pm
Quote
It would also be crazy if every library included the static library archives they depend on into their own and not export them don't you think?
No. The first thing has nothing to do with the second. I include dependencies in SFML static libraries so that users don't have to do it theirselves. The result is the same though.
By the way, what do you mean with "export them"? It's a static library, everything which is in it is accessible, isn't it?

Quote
Just a warning, just because MSVC does something, it doesn't mean that that is the standard way of doing it.
I can't see where it is said or implied in the quoted comment.

Quote
You said for other compilers and OSes static build isn't encouraged because you can't perform this archive inclusion for them.
I said that it is not recommended SO we don't try to do it anyway.

Quote
forcing it when building SFML? I'd leave that to the user to decide
He has to do it anyway, there's nothing to decide. So why not do it for them?

I know that this isn't the standard way of managing static libraries. And I usualy don't like doing unexpected things. But to me, doing what I do saves a lot of troubles to beginners. It's very convenient.
I'd like to know which difference it makes, really. Whether it's me or you, GLEW has to be linked anyway. Just to be clear, there's no technical issue. There isn't more problem with static dependencies being pre-linked, than with them linked in the final app.

Quote
Maybe something like INCLUDE_STATIC_LIBS in CMake or something.
Could be an option, yes.

Quote
Is that a miswording? Because saying "must" to me means there is no other way to do it.
"must" is used here because it has to match what's used in the code.

Quote
You probably have all the alleged performance improvements in mind, but remember this varies from case to case and looking at the size of the symbol tables in the SFML libraries I don't see why this is needed.
Why would I export internal classes and functions? In case you didn't notice, this flag is used only when building shared libraries.

Quote
Reading through the SFML CMake configuration I also can't help but have this strange feeling that SFML really encourages one to link dynamically on Linux and Windows at all costs.
Nop. On Linux only ;)
One should link statically on Linux only for very good reasons (like the use case that you describe). Many users want to link statically on Linux for very bad reasons, they don't know that the "regular" way is to link dynamically.

Quote
seeing how many things are broken when static linking SFML I can only hope that the situation improves in the future.
What's broken? What would you improve?

Quote
I'd like to see more support for this too in the future.
More support for what? Are you just talking about the INCLUDE_STATIC_LIBS CMake option, or something else?
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: binary1248 on April 15, 2012, 11:00:51 pm
Quote
More support for what? Are you just talking about the INCLUDE_STATIC_LIBS CMake option, or something else?
More flexibility regarding static linking whether on Linux or Windows. This includes INCLUDE_STATIC_LIBS as well as choosing the link type of other libraries at will (which includes possibly linking GLEW dynamically, which as you mentioned is a known problem).

Quote
What's broken? What would you improve?
All those previous discussions you, me and Tank have had.

Quote
"must" is used here because it has to match what's used in the code.
I meant the fvisibility thing all together including the part in Config.hpp. I find that hiding symbols isn't really needed.

Quote
He has to do it anyway, there's nothing to decide. So why not do it for them?
I know SFML isn't licensed under GPL, but the idea here is freedom. Let the user decide what is best for them. In case a new version of GLEW or one of those other libraries comes out let the user decide whether they want to use that new library or not. Or on the contrary, if he wants to use a far older version of the library that is stable and does exactly what he needs he would want to link against that himself too.

Quote
Why would I export internal classes and functions? In case you didn't notice, this flag is used only when building shared libraries.
Because it doesn't hurt if you don't provide the interface for them anyway? And not to mention you go through a lot of effort to not export them.
It's like putting a knife in a safe on a tall table rather than just leaving it on a tall table so that a child can't reach it. :D

Quote
No. The first thing has nothing to do with the second. I include dependencies in SFML static libraries so that users don't have to do it theirselves. The result is the same though.
By the way, what do you mean with "export them"? It's a static library, everything which is in it is accessible, isn't it?

Code: [Select]
#include <SFML/Window.hpp>
#include <GL/GLEW.h>

int main()
{
sf::Context context;

glewInit();
return 0;
}
This code fails to link with:
Code: [Select]
undefined reference to _imp__glewInitalthough I link to sfml-graphics-s-d and have SFML_STATIC defined.

Sifting through the nm dump of libsfml-graphics-s-d.a you find:
Code: [Select]
glew.c.o
...
00016f7c T _glewInit
...
T meaning the symbol is in the text section.
This is expected because you include GLEW into sfml-graphics, however above that entry you also find:
Code: [Select]
GLCheck.cpp.obj:
...
         U _glewInit
U meaning the symbol is undefined.
I do not know what causes glewInit to be redefined but as an answer to your question, this is how you "not export symbols" in a static library. I don't know how I would do this because I have never had to do this but this is quite annoying and it would be nice to find a fix for it.

edit: I realized I forgot to define GLEW_STATIC which makes the linker error disappear. :P And I also assume that the same symbols are used at different places, some of them being undefined until the linker resolves them inside the same static library archive. I will try to construct an example where the GLEW linking problem we had in SFGUI is displayed in a simpler way.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 16, 2012, 08:09:10 am
Quote
More flexibility regarding static linking whether on Linux or Windows. This includes INCLUDE_STATIC_LIBS as well as choosing the link type of other libraries at will (which includes possibly linking GLEW dynamically, which as you mentioned is a known problem).
This is already possible, you can change the version of GLEW that CMakes picks up. Hmm but I would have to remove the GLEW_STATIC flag then. So yes, it would require a special option.
But honestly, who would use this specific option, and for what? Is it really worth providing so many CMake options? I'm not saying it would be pointless, just trying to keep things reasonable and realistic.

Quote
All those previous discussions you, me and Tank have had.
About static linking? I don't remember issues that would have been discussed in the past.

Quote
I meant the fvisibility thing all together including the part in Config.hpp. I find that hiding symbols isn't really needed.
Quote
Because it doesn't hurt if you don't provide the interface for them anyway? And not to mention you go through a lot of effort to not export them.
It's like putting a knife in a safe on a tall table rather than just leaving it on a tall table so that a child can't reach it.
Have you read this?
http://gcc.gnu.org/wiki/Visibility
https://github.com/SFML/SFML/issues/111
Seems like the roles are inverted now, you're against a small optimization in favor of less complexity ;)

Quote
In case a new version of GLEW or one of those other libraries comes out let the user decide whether they want to use that new library or not. Or on the contrary, if he wants to use a far older version of the library that is stable and does exactly what he needs he would want to link against that himself too.
He would have to use a version which is compatible with the one that SFML uses, which implies:
- same major version
- same compiler options (GLEW_STATIC, ...)
So there's not much freedom in fact, I would rather call it constraints and unnecessary troubles for most people who just want to link SFML statically and nothing else.

Quote
I will try to construct an example where the GLEW linking problem we had in SFGUI is displayed in a simpler way.
This is the only thing we should focus on right now, philosophical discussions should happen only when the technical problem is identified :P
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Meteorhead on April 16, 2012, 10:13:29 am
Unfortunately, static link is currently required in order to avoid a SFML bug at application exit. But this will have all my attention and will hopefully be solved soon.

Laurent, I know you most likely focus on the SFML 2.0 sample apps right now, but if this is the same bug that causes SFGUI to crash at exit and you would solve this issue, could you please post a note also in: http://en.sfml-dev.org/forums/index.php?topic=6112.300 (http://en.sfml-dev.org/forums/index.php?topic=6112.300)

It would be appreciated. Thanks.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 16, 2012, 10:31:47 am
Sure, the SFGUI team will be the first to be notified when I fix this bug :P
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: binary1248 on April 16, 2012, 02:48:45 pm
Quote
Have you read this?
http://gcc.gnu.org/wiki/Visibility
https://github.com/SFML/SFML/issues/111
Seems like the roles are inverted now, you're against a small optimization in favor of less complexity ;)
I optimize for every case and only if it doesn't break anything or brings around strange behavior, and if it does then I make it purely optional. As an example, I could optimize completely for GCC but what would that mean for MSVC? Nothing so I don't do it at all.

Quote
About static linking? I don't remember issues that would have been discussed in the past.
http://en.sfml-dev.org/forums/index.php?topic=7276.0
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 16, 2012, 03:00:48 pm
Quote
I optimize for every case and only if it doesn't break anything or brings around strange behavior
And what exactly does this thing break? It just fills the hole that was behind the SFML_XXX_API macro on Linux (the Windows equivalent is mandatory, at least for VC++).

I still don't get your point. I don't have a lot of time to waste in philosophical discussions (although I'd truly like to), so please just say what you want to say -- simple and fast: what's wrong with this visibility thing?

Quote
http://en.sfml-dev.org/forums/index.php?topic=7276.0
Ah, right :)
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: binary1248 on April 16, 2012, 07:54:26 pm
Quote
And what exactly does this thing break? It just fills the hole that was behind the SFML_XXX_API macro on Linux (the Windows equivalent is mandatory, at least for VC++).

I still don't get your point. I don't have a lot of time to waste in philosophical discussions (although I'd truly like to), so please just say what you want to say -- simple and fast: what's wrong with this visibility thing?
Quite simply, it isn't supported on all compilers and if some compilers/versions export everything then you might as well export everything on all compilers. I also don't regard this is an optimization regarding performance (if it wasn't regarding performance then I didn't get the point obviously) because it is just supposed to speed up loading the shared object because of a reduction of the symbol table. Maybe this makes up for a not even noticeable speedup during the initial loading of the library but this gain gets amortized during runtime anyway. And yes I did read that GCC article and most of the points covered there cannot be applied to SFML IMHO.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 16, 2012, 08:11:10 pm
Like I said, marking exported symbols is mandatory on Windows. So I've just implemented the same feature on Linux and OS X. So actually it now works consistently across compilers.

And I still don't know how this thing relates to the initial problem. It's about shared SFML libs on Unix, whereas Mars_999 was talking about static libs and GLEW on Windows ???
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: binary1248 on April 16, 2012, 08:30:02 pm
Quote
Like I said, marking exported symbols is mandatory on Windows. So I've just implemented the same feature on Linux and OS X. So actually it now works consistently across compilers.
Please tell me you are not trying to duplicate the quirks of Windows on Linux :o. And I think you meant operating systems and not compilers ;). The fact that exported symbols have to be explicitly marked in Windows is already annoying enough. If you ask me it's much simpler the Linux way and keeping things "consistent" with Windows is a bad idea. They are the ones who follow the standards the least anyway.

Quote
And I still don't know how this thing relates to the initial problem. It's about shared SFML libs on Unix, whereas Mars_999 was talking about static libs and GLEW on Windows ???
Actually it has very little if anything at all to do with the initial problem 8). It was somewhat of a false deduction we made when trying to figure out why using GLEW in specific configurations didn't work. When I posted about it on SFGUI forums I was too lazy to dig out the logs again and was just recalling from memory. Now I have determined that the reason we don't use GLEW is because as you already stated using SFML as a static library and any other library (that also links to GLEW statically) as a dynamic library fails. Because this wasn't an option for us we opted to use GLee.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Tank on April 16, 2012, 09:12:45 pm
...and it's even something that can't be worked around in all cases, for example when using LGPL'd libs for projects that link statically to libraries mostly (i.e. link to SFML statically, but dynamically to another library using GLEW).

We're currently also thinking about adding options to our CMakeLists.txt that can be used to disable searching for and linking to external libraries (so that the end-user can decide which he wants to use and, that's also very important, which he doesn't want to search for through find_package() in SFGUI's CMakeLists.txt, for example when adding SFGUI as a submodule and building it within the project's tree so that it doesn't look for SFML if the project itself builds and links it in).

Those options can be declared ADVANCED so that it doesn't show up for "beginners" if you want to follow the "as simple and non-confusing as possible" approach. ;) But for bigger projects with quite complex build pipelines it's very very useful.

Imho it's something that CMake doesn't do right, i.e. managing dependencies in a nice and clean way. But as there's no real alternative to CMake (I tried a lot of others and CMake works best in my opinion), there should be enough options to make everybody happy.

The same could be applied to SFML I guess. It's a little bit annoying to implement because it's boring, but it enhances the usage in big projects.

Besides of that, and I hope it's okay to write that in this thread (don't want to create X threads for connected topics), I'd like to ask if all SFML-related CMake options could be prefixed with "SFML_". I recently ran into the problem where multiple sub-projects used the same CMake cache variables. This can be easily circumvented by prefixes.

Quote from: Laurent
I truly like binary1248 and Tank feedback, they are experienced C++ programers who have a valuable point of view on SFML, but I would appreciate a little less aggressiveness and biased comments. I'm always open to discussions, there's no need to be so angry...
:D Don't take it too serious. You know us long enough to know how to treat our little flame comments – probably a side-effect of being nerdy sometimes. ;) You're doing a good job generally, no doubts, so take our comments/feedback/flames as critique instead of insulting/similar.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 17, 2012, 09:10:34 am
Quote
We're currently also thinking about adding options to our CMakeLists.txt that can be used to disable searching for and linking to external libraries (so that the end-user can decide which he wants to use and, that's also very important, which he doesn't want to search for through find_package() in SFGUI's CMakeLists.txt, for example when adding SFGUI as a submodule and building it within the project's tree so that it doesn't look for SFML if the project itself builds and links it in).
Since I always try to make things as simple as possible, I don't focus on this kind of advanced use cases, so it's hard for me to imagine solutions to them.
So I think you should try these modifications first, and if you're satisfied with them we can discuss it again and consider doing the same in SFML.

Quote
Besides of that, and I hope it's okay to write that in this thread (don't want to create X threads for connected topics), I'd like to ask if all SFML-related CMake options could be prefixed with "SFML_". I recently ran into the problem where multiple sub-projects used the same CMake cache variables. This can be easily circumvented by prefixes.
Sounds like a good idea.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Laurent on April 18, 2012, 08:48:36 pm
Quote
Besides of that, and I hope it's okay to write that in this thread (don't want to create X threads for connected topics), I'd like to ask if all SFML-related CMake options could be prefixed with "SFML_". I recently ran into the problem where multiple sub-projects used the same CMake cache variables. This can be easily circumvented by prefixes.
Done.
Title: Re: GLEW and not exporting the GLEW symbols in SFML
Post by: Tank on April 19, 2012, 09:43:59 pm
Thanks.