我正在尝试使用接口库来定义预处理器宏。这些接口库随后将链接到其他库,以传播这些宏。这种方法适用于我正在创建的共享库,但不适用于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通过此合并请求可能会支持此功能。对于旧版本,乌托邦的答案是正确的方法。
只需直接通过属性从接口库中复制编译定义。信息就在那里,只是没有通过通常的命令直接支持它:
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版本可能是个好主意。
| 归档时间: |
|
| 查看次数: |
5464 次 |
| 最近记录: |