ValveSoftware / voglperf

Benchmarking tool for Linux OpenGL games. Spews frame information, logs frametimes.
Other
201 stars 31 forks source link

voglperf tries to link static library to its dynamic LD_PRELOAD libary #4

Closed eero-t closed 10 years ago

eero-t commented 10 years ago

voglperf build tries to link libSDL2 library statically to voglperf's LD_PRELOAD library.

LD_PRELOAD is shared library. Shared libraries are compiled as position independent code, with -fPIC. Static libraries (in general) aren't, in the distributions. Because of this, voglperf compile fails, GCC doesn't (anymore) allow shared objects to have TEXT relocations.

I guess by static linking you try to avoid conflicts with Steam games that also link libSDL2, but the correct solution is just not using SDL2 in the LD_PRELOAD.

Your preload library is really simple, there's nothing that needs SDL2, all that functionality is already easily available in C library.

Of the SDL functionality you're using, these are just wrappers for libc functions:

And rest are trivial to change to use standard C-library POSIX functions:

drivers-valve commented 10 years ago

Hi eero-t.

Is there a reason static libraries aren't generally compiled with -fPIC? Means the static libraries are only really meant to work with the executables and I don't fully understand that. I talked to the SDL maintainer and he's up for adding -fPIC, but I'd like to understand why other libraries don't do this before I submit that patch.

And you're right - it would be trivial right now to remove our dependency on SDL2. However I did it this way thinking we might port this code to other platforms - so I'd like to see if we can make that work first before going in and adding that code to voglperf for all the platforms.

Thanks!

eero-t commented 10 years ago

The use-case for static libraries is making (huge, but) portable applications, and small performance improvement from avoiding library symbol lookups. -fPIC means losing one register so there's a small performance and code size impact. Static linking is really nasty from distribution maintenance/security perspective, so I can also understand distros doing "damage control" by making static linking usage in shared libraries less convenient. :-)

Nanosleep, dlopen and dlsym are standard POSIX functions, rest are standard ANSI-C functions. With ANSI-C functions you shouldn't have any portability problems to systems that are still relevant, and as to first three functions, you can just copy that small functionality from libSDL, it's pretty stable stuff in OSes, so I don't think it's going to need any changes later on. In any case, your main problem in portability will be lack of LD_PRELOAD functionality.

Also, when doing LD_PRELOAD, you really should be familiar with how symbol loading works at lower level, you shouldn't be relying on some portability library that hasn't been designed LD_PRELOAD use-case in mind.

mikesart commented 10 years ago

It's oftentimes never as easy as "just call nanosleep". For example, SDL_Delay() handles EINTR - there are often little gotchas like that on various platforms that I was trying to leverage.

I'm also fairly familiar with LD_PRELOAD: SDL is a very clean C only library, I built it with -fPIC, linked it statically, investigated the exports & dependencies in the final binary, made a linker script to hide all but the three we need, and then tested it on several games. SDL was also built to be statically linked and update-able:

https://plus.google.com/+RyanGordon/posts/TB8UfnDYu4U

I'll take a look at removing the dependency though as it will be a pain if the distros aren't building with fPIC.

mikesart commented 10 years ago

Should be fixed in f1d4184. One thing this definitely did was drop the size of our binary down a lot: from over 1.5M to <50k. So this is good. Thanks eero-t.