I have already written about the solution to GLIBC_2.4 dependencies. The solution is still valid, but I wanted to share this bit of frustration that made me question if it worked in Ubuntu.
This past weekend, I participated in the 48 hour game development competition known as Ludum Dare #11. You can see my submission.
I found out that my submission had a GLIBC_2.4 dependency. How embarrassing! Since I wasn’t using my laptop at the time, I used my Debian-based desktop and built the game. No dependency existed in this build, so I uploaded it. I wasn’t sure why the previous build didn’t work since the build scripts and code should all be the same.
When I used my laptop, which runs Ubuntu, I found that the binary that gets produced has the GLIBC_2.4 dependency. I can see that it has the dependency using objdump -x BINARY_NAME | grep GLIBC_2\.4
. You can see it in the following output:
$ objdump -x source/ld11-minimalist.bin | grep GLIBC_2\.4
0x0d696914 0x00 10 GLIBC_2.4
00000000 F *UND* 00000046 __stack_chk_fail@@GLIBC_2.4
I double and triple checked, and I am using -fno-stack-protector in all of the right places. The build still works on my Debian system just fine. What else could be going wrong?
After spending a few hours gutting out all of the code and making it link to the bare minimum of game classes and libraries, I found that it kept requiring GLIBC_2.4, and I was getting frustrated. I compared my Ludum Dare project’s build scripts with my Killer Kittens from Katis Minor build scripts, which should be roughly the same. The only major difference was that my LD entry wasn’t using the Kyra Sprite Engine. I didn’t see anything else that was different.
Getting desperate, I added Kyra to see if it might help. It didn’t.
I learned that the .o files didn’t have the dependency, so the problem gets introduced when it is all linked together. After another hour or two, I finally saw something odd:
LIBS := -static-libgcc -L. -L${LIB_INSTALL_DIR}/lib $(shell ${LIB_INSTALL_DIR}/bin/sdl-config --libs) -lSDL_image -lSDL_mixer #-L/usr/X11R6/lib -lX11
Do you see the “-L.” right after “-static-libgcc”? What’s the purpose of it? Well, it turns out that my build scripts provide a link to the static libstdc++.a library file, so -L. allows it to link. When I remove -L., it still builds the game, but now the game depends on libstdc++.so.6. While I don’t have GLIBC_2.4 symbols, I now have CXXABI_1.3 and GLIBCXX_3.4 symbols.
I learned that when I built my Killer Kittens project on my laptop, it also has those dependencies. See, for some reason Kyra prevents it from linking to libstdc++ statically, so it has a dependency on libstdc++. On my Debian system, the dependency doesn’t exist. It builds it just fine.
When I run objdump -x BINARY_NAME
I see different results depending on the system I built the game on:
My Debian Testing system:
Dynamic Section:
NEEDED libkyra.so.0
NEEDED libSDL-1.2.so.0
NEEDED libpthread.so.0
NEEDED libSDL_mixer-1.2.so.0
NEEDED libm.so.6
NEEDED libc.so.6
NEEDED ld-linux.so.2
NEEDED libengine.so.0
My Ubuntu Feisty system:
Dynamic Section:
NEEDED libkyra.so.0
NEEDED libSDL-1.2.so.0
NEEDED libpthread.so.0
NEEDED libSDL_mixer-1.2.so.0
NEEDED libstdc++.so.6
NEEDED libm.so.6
NEEDED libc.so.6
NEEDED libengine.so.0
Why is there a discrepancy? It turns out that Ubuntu and Debian differ in their implementation in terms of using stack protection when building software. Debian’s default is “Do not use stack protection.” Ubuntu’s maintainers decided that stack protection was better even if things wouldn’t be completely compatible with Debian.
In my case, since I am trying to link to the system’s libraries statically, my binary is taking in stack protection and so depends on GLIBC_2.4. If I don’t statically link to libstdc++, my binary now depends upon my system’s version of libstdc++.so. Since -fno-stack-protector is a compile-time flag, it has no effect at link time when the system’s GLIBC_2.4-depending libraries are linked in to my binary.
Essentially, Ubuntu’s decision to use stack protection by default has made it very difficult for me to create a binary compatible build for older systems on my laptop. I would like for my build to work the same across systems, but I guess until I find a better way, I will need to make sure I deploy my games from my Debian-based desktop system.
I guess this example is just one more reason why people have a tough time creating games for GNU/Linux, or at least why C++ isn’t as popular as C or Python.
For more information:
- My GLIBC_2.4 dependency solution
- Enabling SSP for added security
- Ubuntu’s GCC SSP wiki page explaining the rationale behind the decision to implement the OS differently from Debian
One reply on “Linux Game Development: Frustrations with GLIBC_2.4 and Ubuntu”
[…] Reading Books 2008 | « Thousander Club Update: April 21st Linux Game Development: Frustrations with GLIBC_2.4 and Ubuntu […]