简体   繁体   English

将CMake对象库与共享库结合使用

[英]Combining CMake object libraries with shared libraries

I have the following CMakeLists.txt defining an object library and a shared library depending on the object library, as follows: 我有以下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
)

I get the following linker error when linking baz : 链接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

This is because foo.cpp is not build with -fPIC ( bar.cpp is). 这是因为foo.cpp不是用-fPIC构建的( bar.cpp是)。 This can be solved by adding: 这可以通过添加:

set_property(TARGET foo PROPERTY POSITION_INDEPENDENT_CODE ON)

Is this the right way to fix this issue? 这是解决此问题的正确方法吗? I seems to me there should be a cleaner solution for this. 在我看来,应该有一个更清洁的解决方案。 I feel CMake can be smarter here and see that the objects from foo are only used in a context where -fPIC is required. 我觉得CMake在这里更聪明,并且看到来自foo的对象仅用于需要-fPIC的上下文中。 I am using CMake 3.11. 我正在使用CMake 3.11。

Some context; 一些背景; in our project, we need to build a single shared library from a lot of sources scattered around in different directories. 在我们的项目中,我们需要从分散在不同目录中的许多来源构建单个共享库。 Right now, we create separate shared libraries for each directory. 现在,我们为每个目录创建单独的共享库。 Most of these libraries depend on Bison sources, which behind the scenes depend on add_custom_command to be build. 大多数这些库依赖于Bison源,后台依赖于要构建的add_custom_command This introduces compile time dependencies between the libraries, seriously limiting how much we can parallelize the build (see: https://gitlab.kitware.com/cmake/cmake/issues/15555 ). 这引入了库之间的编译时依赖性,严重限制了我们可以并行构建的程度(参见: https//gitlab.kitware.com/cmake/cmake/issues/15555 )。

Object libraries per directory which are then used to build the shared library seem to be a nice solution for this problem. 每个目录的对象库随后用于构建共享库似乎是解决此问题的一个很好的解决方案。

Is this the right way to fix this issue? 这是解决此问题的正确方法吗?

Yes it is. 是的。

Since bar (shared) is linked against foo (static), both of bar and foo must be compiled with position independent code. 由于bar (共享)与foo (静态)链接,因此barfoo必须使用与位置无关的代码进行编译。

CMake knows bar is a shared library, and enables position independent code by default . CMake know bar是一个共享库, 默认情况下启用与位置无关的代码 But since foo is a static object, even though it could guess it needs to be PIC 1 , it does not enable PIC by default for foo . 但由于foo是一个静态对象,即使它可能猜测它需要是PIC 1 ,它默认情况下不会为foo启用PIC。

According to SO's question What is the idiomatic way in CMAKE to add the -fPIC compiler option? 根据SO的问题,CMAKE中添加-fPIC编译器选项的惯用方法是什么?

You can set the position independent code property on all targets: 您可以在所有目标上设置与位置无关的代码属性:

 set(CMAKE_POSITION_INDEPENDENT_CODE ON) 

or in a specific library: 或在特定的图书馆:

 add_library(lib1 SHARED lib1.cpp) set_property(TARGET lib1 PROPERTY POSITION_INDEPENDENT_CODE ON) 

Reference: CMAKE_POSITION_INDEPENDENT_CODE cmake build system 参考: CMAKE_POSITION_INDEPENDENT_CODE cmake构建系统


1) This could be a suggested feature, maybe it is already. 1)这可能是一个建议的功能,也许它已经是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM