Question

Using the flags "-Wl,--no-undefined -Wl,--no-allow-shlib-undefined" with GCC leads to the following compilation errors on the Travis CI image but not on my machine (both are Ubuntu 12.04 64-bits):

Linking CXX shared library libmocap.so
cd /tmp/_travis/build/src && /usr/bin/cmake -E cmake_link_script CMakeFiles/mocap.dir/link.txt --verbose=1
/usr/bin/g++  -fPIC --coverage -Werror  -pedantic -Wno-long-long -Wall -Wextra -Wcast-align -Wcast-qual -Wformat -Wwrite-strings -Wconversion -fvisibility=hidden -Wl,--no-undefined -Wl,--no-allow-shlib-undefined -Wl,--as-needed   -shared -Wl,-soname,libmocap.so.0.0.0 -o libmocap.so.UNKNOWN CMakeFiles/mocap.dir/abstract-marker.cc.o CMakeFiles/mocap.dir/abstract-virtual-marker.cc.o CMakeFiles/mocap.dir/color.cc.o CMakeFiles/mocap.dir/link.cc.o CMakeFiles/mocap.dir/marker-set-factory.cc.o CMakeFiles/mocap.dir/marker-set.cc.o CMakeFiles/mocap.dir/marker-trajectory-factory.cc.o CMakeFiles/mocap.dir/marker-trajectory.cc.o CMakeFiles/mocap.dir/marker.cc.o CMakeFiles/mocap.dir/mars-marker-set-factory.cc.o CMakeFiles/mocap.dir/math.cc.o CMakeFiles/mocap.dir/pose.cc.o CMakeFiles/mocap.dir/segment.cc.o CMakeFiles/mocap.dir/string.cc.o CMakeFiles/mocap.dir/trc-marker-trajectory-factory.cc.o CMakeFiles/mocap.dir/virtual-marker-one-point-measured.cc.o CMakeFiles/mocap.dir/virtual-marker-relative-to-bone.cc.o CMakeFiles/mocap.dir/virtual-marker-three-points-measured.cc.o CMakeFiles/mocap.dir/virtual-marker-three-points-ratio.cc.o CMakeFiles/mocap.dir/virtual-marker-two-points-measured.cc.o CMakeFiles/mocap.dir/virtual-marker-two-points-ratio.cc.o 
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_dl_argv@GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_rtld_global_ro@GLIBC_PRIVATE'
/usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++.so: undefined reference to `__tls_get_addr@GLIBC_2.3'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `_rtld_global@GLIBC_PRIVATE'
/lib/x86_64-linux-gnu/libc.so.6: undefined reference to `__libc_enable_secure@GLIBC_PRIVATE'
collect2: ld returned 1 exit status
make[2]: *** [src/libmocap.so.UNKNOWN] Error 1

Strangely, this does not occur on my machine and hence is a bit difficult to reproduce. What is the right way to link against the libc and libstdc++ when these flags are enabled?

(as you might guess from the output, I use CMake to generate the compilation command)

Was it helpful?

Solution

The default for the 2nd argument is "--allow-shlib-undefined". Probably if you choose that option the code will build.

This 2nd argument deals with build time checking where enabling this means checking that the library that you are linking against in turn has its dependencies wired up at build time.. And that is not necessarily the case.

The first argument makes sure that you have not forgotten to state a dependency to a runtime library (which may also be a dependency that a runtime library has to another runtime library).For example if you are calling a function where the implementation is in an example runtime library "libfunc.so" and that library in turn will call a function in another runtime library "libext.so" then by declaring a dependency to both "func" and "ext" the libfunc.so will be generated to internally include a dependency reference to libext. If you would leave out "--no undefined" and forget to add dependency declarations then the build would still succeed, trusting that your runtime linker would resolve dependencies at runtime. And since the build was successful you might trust that everything will be ok not knowing that the build has deferred responsibility to the runtime linker. But most often the runtime linker is not designed to search for unresolved references but expects to find such dependencies stated in the runtime library. And if no such reference is there you will get a runtime error. Runtime errors are typically much more costly than resolving a compile time error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top