简体   繁体   中英

How can I compile SDL2 and GLEW applications statically on Linux?

I am attempting to compile an OpenGl application that uses SDL2 and GLEW in such a way that it will run on any version of Linux it may find itself -- not just where it was originally compiled. To do this, I have tried several things none of which work.

I have tried directly linking to .a files produced by running make in the extracted root directory of GLEW and SDL from each library's website download. This produces the following errors:

/usr/bin/ld: /opt/SDL2-2.0.4/build/.libs/libSDL2.a(SDL_syssem.o): undefined reference to symbol 'sem_getvalue@@GLIBC_2.2.5'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line

I have tried building as I do with dynamically linked libraries, which works fine except for the cross-platform capabilities, (with pkg-config --libs sdl2 and pkg-config --libs glew ) but adding -static , at which point I get the following errors:

/usr/bin/ld: cannot find -lGLEW
/usr/bin/ld: cannot find -lGL

When I change the previous scenario to point to my statically compiled GLEW libraries, I get undefined reference errors to OpenGl functions along with undefined reference errors like the following from many SDL functions. Adding -lGL does not change anything.

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadObject_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_LoadFunction_REAL':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_sysloadso.o): In function `SDL_UnloadObject_REAL':

When I try using pkg-config --libs --static <library name> for all libraries, I get the following error:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libSDL2.a(SDL_dynapi.o): In function `SDL_InitDynamicAPI':
/usr/bin/ld: cannot find -lasound
/usr/bin/ld: cannot find -lpulse-simple
/usr/bin/ld: cannot find -lpulse
/usr/bin/ld: cannot find -lsndio
/usr/bin/ld: cannot find -lwayland-egl
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libwayland-cursor.a(libwayland_cursor_la-xcursor.o): In function `XcursorImagesDestroy':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libXcursor.a(file.o):(.text+0x7d0): first defined here
/usr/bin/ld: cannot find -lGLEW
/usr/bin/ld: cannot find -lGL
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(GetDflt.o): In function `GetHomeDir.part.0':
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libX11.a(xim_trans.o): In function `_XimXTransSocketINETConnect':
collect2: error: ld returned 1 exit status

NOTE: All of the output above is from the command g++ -o /path/to/outputExecutable <list of object files>.o <libraries as described above>

NOTE: I do not think this question is a duplicate of any other question on the Stack Exchange network because I have been trying to figure this out for about one and a half months and I have seen a very large number of these questions and tried everything in them, thus, even if the symptoms are the same the underlying problem is different.

NOTE: This is a closed-source application so dynamic linking is not an option for it requires distributing the source code to allow users to build the binaries on their own systems.

NOTE: I am currently trying to get this to compile with Linux via g++, but, I do intend to use mingw to distribute this application for Windows as well. Any advice that works there is preferable to Linux only advice, but, I can ask another question if I can't figure out that part from what will end up here.

NOTE: I am using Ubuntu 16.04 LTS x64 to compile.

Thank you in advance for even getting this far in this question. Sorry for the wall of text, but, I wanted to provide as much information as possible. I look forward to any answers!

Older Loki games did full static linking. Probably not worth it anymore, and far more difficult if you use external libraries.

Libraries are often not self-sufficient, requiring other libraries, .... Dynamic library have dependency information built-in, but static library is just an archive of .o files - it may depend on something but there is no special section that describes what extra libraries should be used. Your first error says that libSDL2.a uses symbol sem_getvalue@@GLIBC_2.2.5 ( sem_getvalue function, marked with glibc version) that cannot be resolved - most likely because you didn't add -lpthread to your linker flags. ( libSDL.so depends on some version of pthrtead among other things - that's why you don't need to manually link with it if you don't use it directly).

GLEW should have no problems with static linking. You need to be more specific on errors you're getting. Maybe you got your libraries order wrong and linker cannot resolve GL functions. Need to see actual linking line and some 'undefined reference' errors to be more specific.

pkg-config 's --static flag should give you dependencies list (eg -lpthread should be in the output of sdl2-config --static-libs among many others), but it does not by itself produce static linking with given library. To request static linking, there are -static gcc flag that generates static executable (hard!) and -Bstatic linker flag to use static version for all libraries specified after it (so that way you can use some static libraries and some dynamic). -Bdynamic is a counterpart, asking to use dynamic libraries. Eg to use static SDL and GLEW but dynamic GL linking line should be something like (if you use gcc to link, not ld directly) gcc ${OBJECT_FILES} -Wl,-Bstatic -lSDL2 -lGLEW -Wl,-Bdynamic -lGL -lpthread -ldl -lm <everything else SDL2 requires - query with sdl2-config> .

Your /usr/bin/ld: cannot find -lasound lines may have two reasons - static linking or related to the fact that you don't have development libraries installed (eg libasound2-dev , libpulse-dev , ... - at least they called that on debian, it is unlikely ubuntu have different names). 'User' libraries usually contains eg libasound.so.2 but linker will not find this library as it have a version in it. Development package contains headers and symlink libasound.so -> libasound.so.2 - that way linker knows what to use. If you use it indirectly via SDL2 - you don't need that, shared SDL2 already have a link to versioned library.

However there may be little point in doing so at all. You can distribute requred shared libraries with your software and use them either via rpath or LD_LIBRARY_PATH environment variable (maya, steam, etc... - almost everyone doing these this days). Moreover, even with static SDL2 end user can override SDL2 with their own (this is a feature intentionally implemented in SDL2). If there is a bug (or just very different environment) and your software is no longer gets updates - there is a chance that problem may be fixed by just replacing shared libraries. Would you really mind people running your program on wayland or mir if your original SDL2 had only X11 support?

in such a way that it will run on any version of Linux it may find itself -- not just where it was originally compiled is far more complicated, and honestly almost unrealistic (unless you have quite small program and use only very limited set of libraries with a good forward/backward compatibility - but even then it may be hard). One of big problems is glibc; usually it is a good idea to use lowest possible version of glibc to compile your program.

To sum it up, it is possible, but it does not help much.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM