我正在尝试使用接口库来定义预处理器宏。然后,这些接口库将链接到其他库以传播这些宏。这种方法适用于我正在创建的共享库,但不适用于CMake对象库。
据我所知,您不能直接将接口库链接到对象库,但可以间接将TARGET_OBJECTS
链接到接口库。
Docs:
虽然在调用
target_link_libraries()
命令时可能无法直接命名对象库,但可以使用其INTERFACE_SOURCES
目标属性设置为名称{{1}的接口库间接地“链接”它们。 }。
我尝试过这样做,但目标文件仍未使用适当的定义进行编译。这是最小的工作示例:
$<TARGET_OBJECTS:objlib>
CMakeLists:
// a.cpp
int a() {
return
#ifdef MY_DEF
5;
#endif
}
输出:
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)
根据文档,这应该可以在CMake中实现。我不确定我做错了什么,或者这是否是CMake的一个问题。我已经能够在Debian和OSX上的CMake版本3.6和3.8中重现这一点。
编辑:
我已经能够使用@utopia的方法解决这个问题,但我很好奇为什么我在我的例子中使用的方法不起作用。我不知道我是否这样做不正确,或者这是否是该工具的问题。也许StackOverflow不是这类问题的正确平台,我应该针对该项目提交错误报告。
EDIT2:
截至最新版本的CMake(3.8),这在CMake(see discussion)中是不可能的。这可以通过this合并请求在3.9中得到支持。对于旧版本,乌托邦的答案是要走的路。
答案 0 :(得分:2)
直接通过属性从接口库复制编译定义。信息在那里,通过常用命令没有直接支持:
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>)
注意target_sources()
最初是在3.1版而不是3.0.1中引入的。更新cmake_minimum_required
版本可能是个好主意。
答案 1 :(得分:0)
从cmake 3.13开始,对象库可以“链接”到其他库以继承其使用要求(doc)。
因此问题的示例CMakeLists.txt应该在编译时获得正确的定义。
如果使用它,别忘了设置cmake_required(版本3.13)!
答案 2 :(得分:-1)
要使 OBJECT 库本身使用特定的编译定义,您应该:
将这些定义添加到库目标本身:
target_compile_definitions(object_lib PUBLIC MY_DEF)
或将库链接到另一个库,这需要这些定义:
target_link_libraries(object_lib interface_lib)
在那里, OBJECT 库与CMake中的其他类型的库没有区别。
来自CMake文档的引文:
虽然在调用
target_link_libraries()
命令时可能无法直接命名对象库,但可以使用其INTERFACE_SOURCES
目标属性设置为名称{{1}的接口库间接地“链接”它们。 }。
解释了传播如何将 OBJECT 库中的定义编译到另一个库中。关于如何将定义传播到 OBJECT 库本身
。