组合CMake对象库和共享库

范·范·休维尔

我有以下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不是使用-fPICbar.cppis)构建的可以通过添加以下内容来解决:

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)。

每个目录的对象库随后用于构建共享库,似乎是解决此问题的不错方法。

YSC

这是解决此问题的正确方法吗?

是的。

由于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)

参考:CMAKE_POSITION_INDEPENDENT_CODE cmake构建系统


1)这可能是建议的功能,也许已经。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章