将CMake接口库与对象库链接

Uma*_*had 7 cmake

我正在尝试使用接口库来定义预处理器宏。这些接口库随后将链接到其他库,以传播这些宏。这种方法适用于我正在创建的共享库,但不适用于CMake对象库。

我了解您不能直接将接口库链接到对象库,但是可以间接地将其链接TARGET_OBJECTS到接口库。

文件

尽管对象库可能无法在target_link_libraries()命令调用中直接命名,但是可以使用INTERFACE_SOURCES目标属性设置为name 的接口库间接“链接”它们$<TARGET_OBJECTS:objlib>

我尝试这样做,但是目标文件仍未使用适当的定义进行编译。这是最小的工作示例:

// a.cpp    
int a() {
  return
#ifdef MY_DEF
  5;
#endif
    }
Run Code Online (Sandbox Code Playgroud)

CMakeLists:

cmake_minimum_required(VERSION 3.0.1)
project(my_question)

add_library(object_lib OBJECT a.cpp)

add_library(interface_lib INTERFACE)
target_compile_definitions(interface_lib INTERFACE MY_DEF)

# This does not set the MY_DEF flag
target_sources(interface_lib INTERFACE $<TARGET_OBJECTS:object_lib>)

add_library(main_lib SHARED $<TARGET_OBJECTS:object_lib>)
target_link_libraries(main_lib)
Run Code Online (Sandbox Code Playgroud)

输出:

/Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/object_lib.dir/build.make CMakeFiles/object_lib.dir/build
[ 50%] Building CXX object CMakeFiles/object_lib.dir/a.cpp.o
/Library/Developer/CommandLineTools/usr/bin/c++     -o CMakeFiles/object_lib.dir/a.cpp.o -c /Users/umar/devel/so_question/a.cpp
/Users/umar/devel/so_question/a.cpp:7:5: error: expected expression
    }
    ^
1 error generated.
make[2]: *** [CMakeFiles/object_lib.dir/a.cpp.o] Error 1
make[1]: *** [CMakeFiles/object_lib.dir/all] Error 2
make: *** [all] Error 2
Run Code Online (Sandbox Code Playgroud)

根据文档,这在CMake中应该是可能的。我不确定我是在做错什么,还是在CMake中有问题。我已经能够在Debian和OSX的CMake 3.6和3.8版中重现此内容。

编辑:

我已经可以使用@utopia的方法解决此问题,但我很好奇为什么在示例中使用的方法不起作用。我不知道我是否做错了或者这是否是工具的问题。也许StackOverflow不是解决此类问题的正确平台,我应该针对该项目提交错误报告。

编辑2:

从CMake(3.8)的最新版本开始,这在CMake中是不可能的(请参阅讨论)。3.9通过合并请求可能会支持此功能。对于旧版本,乌托邦的答案是正确的方法。

sal*_*ock 8

从 cmake 3.13 开始,对象库可以“链接”到其他库以继承它们的使用要求(doc)。

所以问题中的示例 CMakeLists.txt 应该在编译时得到正确的定义。

如果您使用它,请不要忘记设置 cmake_required(VERSION 3.13) !


uto*_*pia 5

只需直接通过属性从接口库中复制编译定义。信息就在那里,只是没有通过通常的命令直接支持它:

cmake_minimum_required(VERSION 3.1)
project(my_question)

add_library(interface_lib INTERFACE)
target_compile_definitions(interface_lib INTERFACE MY_DEF)

add_library(object_lib OBJECT a.cpp)
target_compile_definitions(object_lib PUBLIC
  $<TARGET_PROPERTY:interface_lib,INTERFACE_COMPILE_DEFINITIONS>)

add_library(main_lib b.cpp)
target_sources(main_lib PRIVATE
  $<TARGET_OBJECTS:object_lib>)
Run Code Online (Sandbox Code Playgroud)

Notetarget_sources()似乎是在 3.1 版而不是 3.0.1 版中首次引入的。更新您的cmake_minimum_required版本可能是个好主意。

  • 我很感激你的回答,我并不是要贬低你的努力。我很好奇是我做错了还是 CMake 有问题。我最近才开始以这种方式使用 CMake,我认为这是我无能的症状,而不是工具。我会更新问题,以免再次发生 (2认同)