4
votes

I'm trying to build a library that makes use of boost, and while the library compiles OK, it's hitting a weird linker error that I don't understand. I built and installed Boost 1.54 (also tried 1.52), which went fine.

It claims to not be able to find __assert_fail, which I think is part of the standard library. I tried to build everything in 64-bit. I'm on Fedora 16, using gcc 4.6.3

Any ideas?

make  all-am
make[1]: Entering directory `/data/adrian/code/ext/mapper/cmappertools'
/bin/sh ./libtool  --tag=CXX   --mode=link g++  -g -O2    -o libcmappertools.la -rpath /usr/local/lib/python2.7/site-packages cmappertools.lo  
libtool: link: g++  -fPIC -DPIC -shared -nostdlib /usr/lib/gcc/x86_64-redhat-linux/4.6.3/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.6.3/crtbeginS.o  .libs/cmappertools.o   -L/usr/lib/gcc/x86_64-redhat-linux/4.6.3 -L/usr/lib/gcc/x86_64-redhat-linux/4.6.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.6.3/../../.. -lstdc++ -lm -lc -lgcc_s /usr/lib/gcc/x86_64-redhat-linux/4.6.3/crtendS.o /usr/lib/gcc/x86_64-redhat-linux/4.6.3/../../../../lib64/crtn.o  -O2   -Wl,-soname -Wl,libcmappertools.so.0 -o .libs/libcmappertools.so.0.0.0
.libs/cmappertools.o: In function `condition_variable':
/usr/local/include/boost/thread/pthread/condition_variable_fwd.hpp:69: undefined reference to `__assert_fail'
/usr/local/include/boost/thread/pthread/condition_variable_fwd.hpp:69: undefined reference to `__assert_fail'
.libs/cmappertools.o: In function `~mutex':
/usr/local/include/boost/thread/pthread/mutex.hpp:108: undefined reference to `__assert_fail'
.libs/cmappertools.o: In function `condition_variable':
/usr/local/include/boost/thread/pthread/condition_variable_fwd.hpp:69: undefined reference to `__assert_fail'
.libs/cmappertools.o: In function `~mutex':
/usr/local/include/boost/thread/pthread/mutex.hpp:108: undefined reference to `__assert_fail'
.libs/cmappertools.o:/usr/local/include/boost/smart_ptr/shared_array.hpp:194: more undefined references to `__assert_fail' follow
/usr/local/bin/ld: .libs/libcmappertools.so.0.0.0: hidden symbol `__assert_fail' isn't defined
/usr/local/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status
make[1]: *** [libcmappertools.la] Error 1
make[1]: Leaving directory `/data/adrian/code/ext/mapper/cmappertools'
make: *** [all] Error 2
2
__assert_fail is normally a part of libc. Do you have it in your /lib/libc.so.6 and/or /lib64/libc.so.6?n. 1.8e9-where's-my-share m.
Yes -- it's present in both. And the invocation of g++ does have -lc, so it should be finding it [adrian@tiger cmappertools]$ nm /lib/libc.so.6 | grep __assert_fail 4c7f2700 T __assert_fail 4c7f2550 t __assert_fail_base 4c7f2700 t __GI___assert_fail [adrian@tiger cmappertools]$ nm /lib64/libc.so.6 | grep __assert_fail 0000003e1002ef00 T __assert_fail 0000003e1002ed80 t __assert_fail_base 0000003e1002ef00 t __GI___assert_fail Adrian Heilbut
Then perhaps your libtool uses a bad link line. Try linking manually, or add -v to the linker flags to maybe see what's wrong.n. 1.8e9-where's-my-share m.
Correct me if I'm wrong, but don't I see -nostdlib in the fourth line above (immediately above the first error message)?Ken White
Yes, however -lc and -lgcc_s are specified explicitly. And I did try getting rid of the -nostdlib flag and it didn't make any difference..Adrian Heilbut

2 Answers

1
votes

several years later, on different Fedora (29), later version of boost, gcc, etc.etc. I ran into the same problem. Led more by intuition than understanding I got rid of gcc visibility pragmas (i.e. I commented out all the: #pragma GCC visibility push({whatever}) ... #pragma GCC visibility pop) and that did the trick - it compiled, linked and run successfully.

0
votes

As Tarni mentioned,

hidden symbol `__assert_fail' isn't defined

is indeed caused by #pragma GCC visibility push(hidden)

However, if you absolutely need to hide some function that calls assert macro, you should include before hiding any symbols, e.g.


// Wrong place to hide
// #pragma GCC visibility push(hidden) 

#include <assert.h>

// Right place to hide
#pragma GCC visibility push(hidden) 

void fatal_debug(int foo, int bar){
    assert(foo == bar);
}


#pragma GCC visibility pop