Зачем мне явно связывать pthread и rt с новыми gcc и binutils?

Ситуация

У меня есть большой проект с несколькими библиотеками на С++, который до сих пор был скомпилирован на Debian Squeeze с его родным компилятором gcc 4.4. Теперь я хотел воспользоваться более новой версией gcc и ее оптимизацией для конкретной архитектуры, чтобы иметь возможность использовать инструкции FMA и AVX на моей целевой платформе. Я скомпилировал gcc 4.9.1 из исходного кода, и мне также пришлось скомпилировать новый binutils, потому что компоновщик, я думаю, не поддерживал набор инструкций.

Проблема

С новыми gcc и ld мне теперь пришлось изменить систему сборки на основе cmake, чтобы также связать библиотеки, такие как pthread, rt или crypto, которые мне не нужно было указывать явно раньше. Как так? Изменилось ли что-то в последних версиях gcc или компоновщика, о чем мне следует знать? Есть ли способ вернуть «старое» поведение, когда не нужно быть таким конкретным? Необходимость указывать эти связывающие зависимости делает мой файл CMakeLists.txt менее читаемым из-за того, что он загроможден специфичными для платформы операторами if.

Версии

Система gcc и ld:

$ /usr/bin/g++ -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.4.5-8' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.4 --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.4.5 (Debian 4.4.5-8)

$ /usr/bin/ld -v
GNU ld (GNU Binutils for Debian)
2.20.1-system.20100303

Пользовательские gcc и ld:

$ /usr/local/bin/g++-4.9 -v
Using built-in specs.
COLLECT_GCC=/usr/local/bin/g++-4.9
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.9.1/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ../gcc/configure --enable-languages=c++ --enable-threads --enable-threads=posix --enable-shared --with-system-zlib --without-included-gettext --enable-clocale=gnu --enable-checking=release --program-suffix=-4.9 --enable-bootstrap
Thread model: posix
gcc version 4.9.1 (GCC)

$ /usr/local/bin/ld -v
GNU ld (GNU Binutils) 2.24.51.20140916

person oxygene    schedule 19.09.2014    source источник
comment
Я нашел следующую ссылку: wiki.debian.org/ToolChain/DSOLinking. Значит ли это, что мне с этим жить и не стоит пытаться обойти это новое поведение?   -  person oxygene    schedule 19.09.2014


Ответы (1)


На самом деле правильная сборка CMake приложения с поддержкой потоков должна включать обнаружение библиотеки Threads, которая действительно выполняет тесты, зависящие от платформы, а затем заполняет соответствующие переменные. См. это для получения дополнительной информации.

Что касается других библиотек в вопросе, я думаю, что эти библиотеки зависят от платформы, поэтому вам нужно добавлять их только на определенной платформе. И действительно, они необходимы на этих платформах. Почему с вашим предыдущим компилятором программа не нуждается в этих библиотеках, по крайней мере, явно указанных? Может быть, потому что они неявно связаны. Попробуйте gcc -dumpspecs для обеих версий компилятора и сравните вывод.

person user3159253    schedule 19.09.2014