target_include_directories 上的生成器表达式的用例是啥?

Posted

技术标签:

【中文标题】target_include_directories 上的生成器表达式的用例是啥?【英文标题】:What is the use case for generator expression on target_include_directories?target_include_directories 上的生成器表达式的用例是什么? 【发布时间】:2019-11-06 11:34:03 【问题描述】:

我在多个地方看到了在定义包含目录时使用生成器表达式的引用,因此您可以在编译和安装期间为包含定义不同的位置。例如:

# Define headers for this library. PUBLIC headers are used for
# compiling the library, and will be added to consumers' build
# paths.
target_include_directories(lib PUBLIC
    $<BUILD_INTERFACE:$CMAKE_CURRENT_SOURCE_DIR/include>
    $<INSTALL_INTERFACE:include>
    PRIVATE src)

我正在构建一个库项目,由于我使用的是标准路径(lib/ 用于静态库,include/ 用于公共标头),我希望通过设置 CMAKE_INSTALL_PREFIX 并使用简单的install()调用,如:

set(CMAKE_INSTALL_PREFIX "$MY_INSTALL_DIR")
install(TARGETS myLibrary ARCHIVE PUBLIC_HEADERS)

我的期望是 DESTINATION 将是两者的默认值,所以我只是告诉 CMake 安装这类文件。当然它不起作用,我需要明确设置库和头文件的目标。

所以问题仍然存在:如果我似乎无法使用INSTALL_INTERFACE,那么一开始的生成器表达式的用例是什么?


这是我的示例 CMakeLists.txt:

cmake_minimum_required(VERSION 3.12.1)
project(my_library C)

FILE(GLOB SOURCE_FILES src/*.c)
add_library(my_library $SOURCE_FILES)
target_include_directories(my_library PUBLIC
    $<BUILD_INTERFACE:$CMAKE_CURRENT_SOURCE_DIR/include>
    $<INSTALL_INTERFACE:include>)

set(OUTPUT_DIR "$CMAKE_BINARY_DIR/output")
set(INSTALL_DIR "$OUTPUT_DIR/my_library")
set(INSTALL_LIB_DIR "$INSTALL_DIR/lib")
set(INSTALL_INC_DIR "$INSTALL_DIR/include")
set(CMAKE_INSTALL_PREFIX "$INSTALL_DIR")
install(TARGETS my_library ARCHIVE DESTINATION lib)
install(DIRECTORY "$CMAKE_CURRENT_SOURCE_DIR/include" DESTINATION include)
# I was hoping I could do, after setting the headers with the INSTALL_INTERFACE generator expression
#install(TARGETS my_library ARCHIVE PUBLIC_HEADERS)

【问题讨论】:

I need to explicitly set the destination for both libraries and header files - 你能展示代码你是怎么做到的吗? Kamil Cuk,我将使用我的 CMakeLists.txt 的准系统来编辑问题。 【参考方案1】:

CMake 使用类似生成器的表达式 $&lt;BUILD_INTERFACE&gt;$&lt;INSTALL_INTERFACE&gt; 来区分事物,对于构建树安装树是不同的。

在构建项目本身时,使用$&lt;BUILD_INTERFACE&gt;,但不使用$&lt;INSTALL_INTERFACE&gt;

使用install(EXPORT) 命令创建导出文件时,$&lt;INSTALL_INTERFACE&gt; 中列出的内容将包含在其中,但$&lt;BUILD_INTERFACE&gt; 中的内容不会。

但是使用export 命令创建导出文件使用$&lt;BUILD_INTERFACE&gt;,但不使用$&lt;INSTALL_INTERFACE&gt;

未使用其他用于区分构建和安装树的表达式 $&lt;BUILD_INTERFACE&gt;$&lt;INSTALL_INTERFACE&gt;

例如$&lt;INSTALL_INTERFACE&gt;不会影响install(TARGETS .. PUBLIC_HEADERS) 命令。

【讨论】:

以上是关于target_include_directories 上的生成器表达式的用例是啥?的主要内容,如果未能解决你的问题,请参考以下文章

target_include_directories 上的生成器表达式的用例是啥?

在CMake中如何使`TARGET_LINK_LIBRARIES'禁止第三方库代码发出警告?

CMake:包括外部库头文件

如何删除 cmake 静态库的编译依赖项?

如何将编译器标志仅限于(我的)本地库?

从 CMake 中使用的库继承包含目录