2016-08-07 63 views
1

Auf einem CentOS 7 x64-System habe ich den neuesten Boost 1.61.0 mit aktiviertem -fPIC erstellt. Ich versuche, libboost_log.a mit der von mir erstellten dynamischen Bibliothek zu verknüpfen, damit der Benutzer meiner Bibliothek Boost nicht installieren muss. Das war erfolgreich mit dem Lager GCC 4.8.5, das mit CentOS 7 geliefert wurde, aber scheiterte, wenn ich GCC 5.2.1 von Devtoolset-4 benutze.ld kann eine statische Bibliothek nicht mit einer dynamischen Bibliothek verknüpfen, auch wenn alle Dateien mit fPIC kompiliert wurden

Hier ist der Fehler:

/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 

Wie ich Boost-gebaut: ./b2 -j6 -q -d+2 cxxflags=-fPIC cflags=-fPIC variant=release -Boost verwendet -O3 standardmäßig. Mein Programm hat also auch -O3 verwendet.

Befehl für den Aufbau meiner Bibliothek: /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

Der Nachweis, dass libboost_log.a mit fPIC gebaut:

 
$ 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 

Gedanken: Wie Sie libboost_filesystem.a scheint verknüpft fein sehen können, nur libboost_log.a kann nicht verknüpft werden in. Was kann ich jetzt überprüfen? Alle Hinweise sind willkommen. Vielen Dank!

+0

War der Compiler der gleiche, wenn Boost eingebaut wurde, also '/ opt/rh/devtoolset-4/root/usr/bin/C++'? Wenn C++ - Header in/usr und/opt/rh/devtoolset-4/root/usr vorhanden sind und sie nicht übereinstimmen, kann es zu Problemen kommen. –

+0

@ J.J.Hakala Natürlich hatte ich die sichere Version verwendet. Lass es mich beweisen, indem du die Fäden in der Bibliothek ausgibst ... Warte, wat? Boost Build respektiert nicht 'scl aktivieren devtoolset-4' ?! –

+0

@ J.J.Hakala Sie haben Recht. Ich habe überprüft, dass Boost nicht korrekt erstellt wurde. Wenn Sie eine Antwort hinzufügen können, werde ich sie als korrekt markieren. Vielen Dank! –

Antwort

1

Der Compiler /opt/RH/devtoolset-4/root/usr/bin/C++ anders als /usr/bin/C++ verwendet. Wenn diese beiden Compiler verschiedene Versionen von C++ - Headern haben, können sie Bibliotheken erzeugen, die unterschiedliche Symbole für Methoden haben (Name Mangling). Es kann auch andere Gründe geben, warum das Linken fehlschlägt, wenn die Compiler-Versionen unterschiedlich sind.

Ich würde empfehlen, C++ - Code zu kompilieren, so dass zumindest die Hauptversion von gcc beim Kompilieren jeder C++ - Bibliothek identisch ist.

+0

Ich möchte hinzufügen, dass die Ursache Boost Build (b2) ist, nicht respektieren 'scl aktivieren devtoolset-4' und immer noch'/usr/bin/g ++ '. Ich musste es dem Devtoolset-4-Compiler mitteilen, indem ich 'gcc:: path/to/gcc' in' project-config.jam' einsetzte. –