我们正在移植一些相当老的代码,当然我们现在想使用生成器表达式。
由configure_file
生成的.pc文件现在包含-I$<INSTALL_INTERFACE:include>
。
关于如何解析生成器表达式的唯一提示是使用
file(GENERATE
这当然是在配置步骤中执行的,因此上面的表达式被解析为空字符串。
编辑: 这是一个例子 CMakeLists.txt:
cmake_minimum_required(VERSION 3.11)
project(test CXX)
add_library(foo SHARED main.cpp)
target_include_directories(foo PUBLIC $<INSTALL_INTERFACE:include>)
# now later buried deep in some functions
get_property( _include_dirs TARGET foo PROPERTY INCLUDE_DIRECTORIES )
configure_file(config.in config.out @ONLY)
# content of config.out is "include = -I$<INSTALL_INTERFACE:include>"
file(GENERATE OUTPUT config.out2 INPUT ${CMAKE_CURRENT_BINARY_DIR}/config.out)
# content of config.out2 is "include = -I"
# most likely because the INSTALL_INTERFACE isn't used when the file is generated
config.in:
include = @_include_dirs@
而main.cpp只是空的。
答案 0 :(得分:5)
正如CMake文档所述,file (GENERATE ...)命令可以使用由生成器评估的生成器表达式。
您可以让CMake直接使用自定义代码生成文件,而无需使用configure_file命令的解决方法。
对于像 Makefiles 这样的单配置生成器,可以使用:
file (GENERATE
OUTPUT "config.out"
CONTENT "include = -I$<INSTALL_INTERFACE:include>"
)
由于我的CMake代码必须与多配置生成器和单配置生成器一起使用,所以我没有专门测试代码。
通常对于所有生成器,可以使用以下签名:
file (GENERATE
OUTPUT "config_$<CONFIG>.out"
CONTENT "include = -I$<INSTALL_INTERFACE:include>"
)
由于与诸如 Visual Studio 之类的多配置生成器有关的命令的性质,这将在此变量CMAKE_CONFIGURATION_TYPES中指定的每种构建类型的构建文件夹中生成多个文件:
如果您未指定唯一的文件名,而CMake尝试生成文件,则会因错误而停止执行。
要使用以前生成的文件,取决于您的需要。首先,文件将在 configuration 阶段之后存在。
要在具有常量名称(例如config.out)的单配置生成器方案中使用生成的文件,则无需进行其他工作。
对于多配置生成器,它略有不同。由于您必须在构建时使用generator expressions来访问适当的文件。如果您有支持生成器表达式的CMake指令,则只需使用文件名config_$<CONFIG>.out
。
但是,如果无论构建类型(例如config.out)如何都需要将文件命名为完全相同的文件,它将变得有些棘手。
首先,您必须通过使用add_custom_command并指定 OUTPUT 参数来告诉CMake应该有一个名为config.out
的文件:
add_custom_command (
COMMAND ${CMAKE_COMMAND} "-E" "copy_if_different" "config_$<CONFIG>.out" "config.out"
VERBATIM
PRE_BUILD
DEPENDS "config_$<CONFIG>.out"
OUTPUT "config.out"
COMMENT "creating config.out file ({event: PRE_BUILD}, {filename: config.out})"
)
CMake将在内部创建一个文件依赖项,每次引用文件名config.out
时,它将确保执行 add_custom_command 。
但这并不是在每种情况下都可行,因为这取决于应使用该文件的进一步说明。
根据所使用的命令,现在可以将文件config.out
指定为某些命令(例如target_sources等)的输入,并且CMake将在文件依赖级别上进行检测,以确保config.out
的存在。
如果要生成未在文件依赖级别上引用的文件(例如versioninfo.txt),则必须确保每次执行构建目标时CMake都执行 add_custom_command 通过目标依赖性:
add_custom_target ("generate_config_out" DEPENDS "config.out")
add_dependencies ("MY_LIBRARY_TARGET" "generate_config_out")
每次CMake构建MY_LIBRARY_TARGET
目标时,它都会先前构建generate_config_out
目标,而目标又取决于CMake将在文件依赖级别上处理的config.out
。