Yan Li
Yan Li

Reputation: 812

ld fails to link a static library to a dynamic library even when all files are compiled with fPIC

On a CentOS 7 x64 system, I've build the latest Boost 1.61.0 with -fPIC enabled. I'm trying to link libboost_log.a to the dynamic library I'm building so that the user of my library doesn't have to have Boost installed. That succeeded using the stock GCC 4.8.5 shipped with CentOS 7, but failed when I'm using GCC 5.2.1 from devtoolset-4.

Here's the error:

/opt/rh/devtoolset-4/root/usr/libexec/gcc/x86_64-redhat-linux/5.2.1/ld: /opt/boost/lib/libboost_log.a(attribute_name.o): relocation R_X86_64_32 against `_ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43' can not be used when making a shared object; recompile with -fPIC
/opt/boost/lib/libboost_log.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

How I built Boost: ./b2 -j6 -q -d+2 cxxflags=-fPIC cflags=-fPIC variant=release Boost uses -O3 by default. My program thus used -O3 as well.

Command for building my library: /opt/rh/devtoolset-4/root/usr/bin/c++ -fPIC -O3 -g -DNDEBUG -shared -Wl,-soname,libfoobar.so.0 -o libfoobar.so.0.5 foobar.cc.o -L/opt/boost/lib /opt/boost/lib/libboost_filesystem.a /opt/boost/lib/libboost_log.a /opt/boost/lib/libboost_program_options.a -lpthread -Wl,-rpath,/opt/boost/lib

Proof that libboost_log.a is built with fPIC:

$ objdump -r  /opt/boost/lib/libboost_log.a | grep _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43
0000000000000002 R_X86_64_32       _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43
0000000000000011 R_X86_64_32S      _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43
00000000000001a3 R_X86_64_32       _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43
00000000000001be R_X86_64_32S      _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43
000000000000001c R_X86_64_32S      _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43
0000000000000021 R_X86_64_32       _ZZN5boost3log12v2s_mt_posix3aux14lazy_singletonINS1_14attribute_name10repositoryENS_10shared_ptrIS5_EEE3getEvE29_boost_log_once_block_flag_43

Thoughts: As you can see libboost_filesystem.a seems linked fine, just libboost_log.a cannot be linked in. What things can I check now? Any hints are welcome. Thanks!

Upvotes: 1

Views: 1041

Answers (1)

J.J. Hakala
J.J. Hakala

Reputation: 6214

The compiler used /opt/rh/devtoolset-4/root/usr/bin/c++ is other than /usr/bin/c++. If those two compilers have different versions of C++ headers they may produce libraries that have different symbols for methods (name mangling). There may be also other reasons why linking may fail if the compiler versions are different.

I would recommend compiling C++ code so that at least the major version of gcc is the same when compiling each C++ library.

Upvotes: 1

Related Questions