我有以下CMakeLists.txt定义对象库和取决于对象库的共享库,如下所示:
add_library(foo OBJECT
foo.cpp
)
add_library(bar SHARED
bar.cpp
$<TARGET_OBJECTS:foo>
)
add_executable(baz baz.cpp)
target_link_libraries(baz
PUBLIC bar
)
链接时出现以下链接器错误baz
:
/usr/bin/ld: CMakeFiles/foo.dir/foo.cpp.o: relocation R_X86_64_PC32 against symbol `_ZSt4cout@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
这是因为foo.cpp
不是使用-fPIC
(bar.cpp
is)构建的。可以通过添加以下内容来解决:
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)
这是解决此问题的正确方法吗?在我看来,应该为此提供一个更清洁的解决方案。我觉得CMake在这里可以更聪明,并且可以看到来自的对象foo
仅在需要的上下文中-fPIC
使用。我正在使用CMake 3.11。
一些背景;在我们的项目中,我们需要从分散在不同目录中的许多资源构建一个共享库。现在,我们为每个目录创建单独的共享库。这些库中的大多数都依赖于Bison源,而Bison源在后台依赖于add_custom_command
构建。这引入了库之间的编译时依赖性,严重限制了我们可以并行化构建的数量(请参阅:https : //gitlab.kitware.com/cmake/cmake/issues/15555)。
每个目录的对象库随后用于构建共享库,似乎是解决此问题的不错方法。
这是解决此问题的正确方法吗?
是的。
由于bar
(共享)与foo
(静态)链接,因此bar
和都foo
必须使用与位置无关的代码进行编译。
CMake知道这bar
是一个共享库,默认情况下启用与位置无关的代码。但是由于foo
是一个静态对象,所以即使可以猜测它必须是PIC 1,它也不会默认启用PIC foo
。
根据SO的问题,CMAKE中添加-fPIC编译器选项的惯用方式是什么?
您可以在所有目标上设置与位置无关的代码属性:
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
或在特定的库中:
add_library(lib1 SHARED lib1.cpp) set_property(TARGET lib1 PROPERTY POSITION_INDEPENDENT_CODE ON)
1)这可能是建议的功能,也许已经。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句