cmake-command target_source 踩坑
target_source BASE_DIRS和FILES的联动
FILES选项
An optional list of files to add to the file set. Each file must be in one of the base directories, or a subdirectory of one of the base directories.
cmake文档中说明FILES选项列出的文件必须是相对于base directories的,即BASE_DIRS。
BASE_DIRS
An optional list of base directories of the file set. Any relative path is treated as relative to the current source directory (i.e. CMAKE_CURRENT_SOURCE_DIR). If no BASE_DIRS are specified when the file set is first created, the value of CMAKE_CURRENT_SOURCE_DIR is added.
文档说明在如果不给出该选项则默认值为CMAKE_CURRENT_SOURCE_DIR。
note: 如果是相对路径,依然是相对于CMAKE_CURRENT_SOURCE_DIR。
遇到的问题
configure_file(config.h.in config.h @ONLY)
add_executable(Main main.cpp)
target_sources(
Main
PRIVATE
FILE_SET HEADERS
#BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
)
configure_file的output的文件是相对于CMAKE_CURRENT_BINARY_DIR的,所以我在上面的代码里写得是FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
Path to the output file or directory. A relative path is treated with respect to the value of CMAKE_CURRENT_BINARY_DIR. If the path names an existing directory the output file is placed in that directory with the same file name as the input file. If the path contains non-existent directories, they are created.
这就造成了一个问题,上面的cmake代码是搜索不到config.h的
fatal error: config.h: No such file or directory
1 | #include "config.h"
原因
Target properties related to include directories are also modified by target_sources(FILE_SET) as follows:
INCLUDE_DIRECTORIES
If the TYPE is HEADERS, and the scope of the file set is PRIVATE or PUBLIC, all of the BASE_DIRS of the file set are wrapped in $<BUILD_INTERFACE> and appended to this property.
INTERFACE_INCLUDE_DIRECTORIES
If the TYPE is HEADERS, and the scope of the file set is INTERFACE or PUBLIC, all of the BASE_DIRS of the file set are wrapped in $<BUILD_INTERFACE> and appended to this property.
target_source会通过BASE_DIRS选项追加INCLUDE_DIRECTORIES和INTERFACE_INCLUDE_DIRECTORIES。上方的代码将BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}注释掉,就会造成INCLUDE_DIRECTORIES默认为CMAKE_CURRENT_SOURCE_DIR,而CMAKE_CURRENT_BINARY_DIR是不在搜索范围内的。
通过以下代码打印一下
include(CMakePrintHelpers)
cmake_print_properties(
TARGETS Main
PROPERTIES INCLUDE_DIRECTORIES
)
- 有
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
Properties for TARGET Main:
Main.INCLUDE_DIRECTORIES = "$<BUILD_INTERFACE:/home/xxx/CMake/cookbook/second_chapter/recipe_05/build>"
- 无
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR}
Properties for TARGET Main:
Main.INCLUDE_DIRECTORIES = "$<BUILD_INTERFACE:/home/xxx/CMake/cookbook/second_chapter/recipe_05/build>"
浙公网安备 33010602011771号