将CMake接口库与对象库链接 [英] Linking CMake interface libraries with object libraries

查看:338
本文介绍了将CMake接口库与对象库链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to use interface libraries to define preprocessor macros. These interface libraries will then be linked to other libraries to propagate these macros. This approach has worked with shared libraries I am creating but does not work with CMake object libraries.

我知道您不能直接将接口库链接到对象库,但是您可以将 TARGET_OBJECTS 间接链接到接口库。

I understand that you cannot directly link an interface library to an object library but you can indirectly link the TARGET_OBJECTS to the interface library.

文档


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

Although object libraries may not be named directly in calls to the target_link_libraries() command, they can be "linked" indirectly by using an Interface Library whose INTERFACE_SOURCES target property is set to name $<TARGET_OBJECTS:objlib>.

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

I have tried to do this but the object files are still not compiled with the appropriate definitions. Here is the minimal working example:

// a.cpp    
int a() {
  return
#ifdef MY_DEF
  5;
#endif
    }

CMakeLists:

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)

输出:

/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

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

Based on the documentation this should be possible in CMake. I am not sure if I am doing something wrong or if this is an issue in CMake. I have been able to reproduce this in CMake version 3.6 and 3.8 on Debian and OSX.

编辑:

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

I have been able to get around this using @utopia's approach but I was curious why the approach I used in my example did not work. I did not know if I was doing this incorrectly or if this was a problem with the tool. Perhaps StackOverflow is not the correct platform for this type of question and I should file a bug report against the project.

Edit2:

从CMake(3.8)的最新版本开始,这在CMake中是不可能的(请参阅讨论)。 3.9通过合并请求可以支持此功能。对于较旧的版本,乌托邦的答案就是解决之道。

As of the most current version of CMake(3.8) this not possible in CMake(see discussion). This is something that may be supported in 3.9 via this merge request. For older versions utopia's answer is the way to go.

推荐答案

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

Just copy the compile definitions from the interface library directly via properties. The information is there, just no direct support for it via the usual commands:

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 版本可能是个好主意。

Note target_sources() was first introduced in version 3.1 not 3.0.1 it seems. It may be a good idea to update your cmake_minimum_required version.

这篇关于将CMake接口库与对象库链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆