我有以下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
)
Run Code Online (Sandbox Code Playgroud)
链接时我收到以下链接器错误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
Run Code Online (Sandbox Code Playgroud)
这是因为foo.cpp不是用-fPIC(bar.cpp是)构建的.这可以通过添加:
set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)
Run Code Online (Sandbox Code Playgroud)
这是解决此问题的正确方法吗?在我看来,应该有一个更清洁的解决方案.我觉得CMake在这里可以变得更聪明,并且看到来自的对象foo仅用于-fPIC需要的上下文中.我正在使用CMake 3.11.
一些背景; 在我们的项目中,我们需要从分散在不同目录中的许多来源构建单个共享库.现在,我们为每个目录创建单独的共享库.大多数这些库依赖于Bison源,后台依赖于add_custom_command构建.这引入了库之间的编译时依赖性,严重限制了我们可以并行构建的程度(参见:https://gitlab.kitware.com/cmake/cmake/issues/15555).
每个目录的对象库随后用于构建共享库似乎是解决此问题的一个很好的解决方案.
这是解决此问题的正确方法吗?
是的.
由于bar(共享)对被链接foo(静态),两者的bar和foo必须与位置无关的代码进行编译.
CMake know bar是一个共享库,默认情况下启用与位置无关的代码.但由于它foo是一个静态对象,即使它可能猜测它需要是PIC 1,它默认情况下不启用PIC foo.
根据SO的问题,CMAKE中添加-fPIC编译器选项的惯用方法是什么?
您可以在所有目标上设置与位置无关的代码属性:
Run Code Online (Sandbox Code Playgroud)set(CMAKE_POSITION_INDEPENDENT_CODE ON)或在特定的图书馆:
Run Code Online (Sandbox Code Playgroud)add_library(lib1 SHARED lib1.cpp) set_property(TARGET lib1 PROPERTY POSITION_INDEPENDENT_CODE ON)
1)这可能是一个建议的功能,也许它已经是.
| 归档时间: |
|
| 查看次数: |
1527 次 |
| 最近记录: |