Distro: Gentoo-Linux Gcc: 4.3.2 without as-needed it compiles fine. Code: /bin/sh ../libtool --tag=CC --mode=link i686-pc-linux-gnu-gcc -march=athlon64-sse3 -O2 -pipe -fomit-frame-pointer -Wl,-O1 -Wl,--sort-common -Wl,--hash-style=gnu -Wl,--as-needed -o drmstat drmstat.o ../libdrm/libdrm.la /bin/sh ../libtool --tag=CC --mode=link i686-pc-linux-gnu-gcc -march=athlon64-sse3 -O2 -pipe -fomit-frame-pointer -Wl,-O1 -Wl,--sort-common -Wl,--hash-style=gnu -Wl,--as-needed -o dristat dristat.o ../libdrm/libdrm.la libtool: link: i686-pc-linux-gnu-gcc -march=athlon64-sse3 -O2 -pipe -fomit-frame-pointer -Wl,-O1 -Wl,--sort-common -Wl,--hash-style=gnu -o .libs/drmstat drmstat.o -Wl,--as-needed ../libdrm/.libs/libdrm.so libtool: link: i686-pc-linux-gnu-gcc -march=athlon64-sse3 -O2 -pipe -fomit-frame-pointer -Wl,-O1 -Wl,--sort-common -Wl,--hash-style=gnu -o .libs/dristat dristat.o -Wl,--as-needed ../libdrm/.libs/libdrm.so dristat.o: In function `drmWaitVBlank': dristat.c:(.text+0x1a3f): undefined reference to `clock_gettime' dristat.c:(.text+0x1a94): undefined reference to `clock_gettime' collect2: ld returned 1 exit status make[2]: *** [dristat] Error 1 make[2]: *** Waiting for unfinished jobs.... make[2]: Leaving directory `/var/tmp/portage/x11-libs/libdrm-2.4.11/work/libdrm-2.4.11/tests' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/var/tmp/portage/x11-libs/libdrm-2.4.11/work/libdrm-2.4.11/tests' make: *** [all-recursive] Error 1 * * ERROR: x11-libs/libdrm-2.4.11 failed. * Call stack: * ebuild.sh, line 48: Called src_compile * environment, line 3097: Called x-modular_src_compile * environment, line 3877: Called x-modular_src_make * environment, line 3916: Called die * The specific snippet of code: * emake || die "emake failed" * The die message: * emake failed
On Fedora, clock_gettime comes from librt, but that gets added in the build when linking to libdrm.la. Can you check that -lrt is actually getting added to libdrm? $ grep 'LIBADD *=' libdrm/Makefile libdrm_la_LIBADD = -lrt $ grep dependency_libs libdrm/libdrm.la dependency_libs=' -lrt' Because it links dristat correctly for me, but that's because libtool is specifically adding -lrt: gcc -DHAVE_CONFIG_H -I. -I../libdrm -I ../shared-core -I ../libdrm -g -O2 -MT dristat.o -MD -MP -MF .deps/dristat.Tpo -c -o dristat.o dristat.c mv -f .deps/dristat.Tpo .deps/dristat.Po /bin/sh ../libtool --tag=CC --mode=link gcc -g -O2 -Wl,--as-needed -o dristat dristat.o ../libdrm/libdrm.la gcc -g -O2 -Wl,--as-needed -o .libs/dristat dristat.o ../libdrm/.libs/libdrm.so -lrt creating dristat
Looks good dionysos libdrm-2.4.11 # grep 'LIBADD *=' libdrm/Makefile libdrm_la_LIBADD = -lrt dionysos libdrm-2.4.11 # grep dependency_libs libdrm/libdrm.la # Linker flags that can not go in dependency_libs. dependency_libs=' -lrt'
Created attachment 25974 [details] [review] Explicitly link test programs to $(CLOCK_LIB)
Hmm, well libtool is supposed to add the -lrt for you. You're using this right from the tarball, right? I was actually using git and generating libtool myself, but I can confirm it now when I use the tarball. It looks like what was used for the tarball was libtool-2.2.6, and it includes the debian patch to not add $dependency_libs for programs on linux. Probably the easiest way to fix this is to explicitly link the programs to $(CLOCK_LIB) in addition to -ldrm. Actually, this seems to really only be an issue for dristat since it uses internal symbols from libdrm.so. The linker reacts to this by adding all of libdrm.so to the executable. See the difference in size between dristat and drmstat even though they're essentially the same program: $ size tests/.libs/* text data bss dec hex filename 30756 864 2400 34020 84e4 tests/.libs/dristat 9581 788 104 10473 28e9 tests/.libs/drmstat When using --as-needed, the linker will skip the DT_NEEDED tags for both libdrm.so and librt.so unless -lrt is specified on the command line. I think this is actually a linker bug, but we can work around it here. See if the attached patch helps. You should just need to run automake and then ./configure.
> Hmm, well libtool is supposed to add the -lrt for you. You're using this right > from the tarball, right? Right > See if the attached patch helps. You should just need to run automake and then > ./configure. Great, the patch works! Tests compile fine. > When using --as-needed, the linker will skip the DT_NEEDED tags for both > libdrm.so and librt.so unless -lrt is specified on the command line. I think > this is actually a linker bug, but we can work around it here. I hope someone will tell them ;) Anyways, will this be integrated in upstream? I wonder whether to open a bug report about this on bugs.gentoo.org
(In reply to comment #5) > > When using --as-needed, the linker will skip the DT_NEEDED tags for both > > libdrm.so and librt.so unless -lrt is specified on the command line. I think > > this is actually a linker bug, but we can work around it here. > > I hope someone will tell them ;) I don't keep up with binutils upstream anymore, but I may try to setup a test case and see if it's reproducible. Maybe you can mention to the gentoo toolchain people. They may determine that my analysis is crack. :) > Anyways, will this be integrated in upstream? > I wonder whether to open a bug report about this on bugs.gentoo.org I can push it to libdrm git, but you'll want to open a gentoo bug if you want this release fixed. I don't know when the next libdrm release will be made.
(In reply to comment #6) > I don't keep up with binutils upstream anymore, but I may try to setup a test > case and see if it's reproducible. Maybe you can mention to the gentoo > toolchain people. They may determine that my analysis is crack. :) hehe, allrighty will do. I'll post a link if you or others are interested in following this.
Gentoo build has already been fixed, we basically run autoreconf before running configure. After digging into this for an hour straight (without knowing about this bug...), my brain hurts a bit but I'd be interested in knowing who's to blame: libtool, ld or Debian ;) Cheers
(In reply to comment #8) > After digging into this for an hour straight (without knowing about this > bug...), my brain hurts a bit but I'd be interested in knowing who's to blame: > libtool, ld or Debian ;) Just to boil down the test case. Works: gcc -Wl,--as-needed -o .libs/dristat dristat.o ../libdrm/.libs/libdrm.so -lrt Fails: gcc -Wl,--as-needed -o .libs/dristat dristat.o ../libdrm/.libs/libdrm.so There's two things going on. 1. The vanilla behavior of libtool is to add all dependency_libs in a .la file to the link command line. So, for the case of libdrm.la, this means programs will be linked explicitly to -lrt like in the Works case. With binutils ld, this is not necessary as the linker will search DT_NEEDED entries in the libraries on the command line and add them to ensure symbols are resolved. And, of course, doing what libtool is doing can be harmful as your program picks up extra NEEDED entries for libraries it doesn't directly use symbols from. Hence, overlinking. So, debian's patch makes libtool skip dependency_libs when linking a program. This should be a good thing, but here it exposes what I think is a bug in ld. 2. Here dristat is using drmOpenMinor, which is a local symbol in libdrm.so. ld seems to react to this by including the entire shared object into the executable. Compare drmstat, which does not use internal symbols, to dristat: $ nm .libs/drmstat | grep drmGetVersion U drmGetVersion $ nm .libs/dristat | grep drmGetVersion 0000000000405060 T drmGetVersion Not such a big deal, except that then ld doesn't process the DT_NEEDED entries in libdrm.so when linking dristat. Subsequently, it fails to add librt.so.1 and then fails to resolve clock_gettime. To work around this, we just explicitly link dristat to -lrt.
(In reply to comment #9) > Not such a big deal, except that then ld doesn't process the DT_NEEDED entries > in libdrm.so when linking dristat. Subsequently, it fails to add librt.so.1 and > then fails to resolve clock_gettime. I forgot to say that this part only happens when using --as-needed. Without --as-needed, ld does continue to process libdrm.so and its DT_NEEDED entries. So, Also Works: gcc -o .libs/dristat dristat.o ../libdrm/.libs/libdrm.so
Looks like this got worked out, if not please reopen.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.