不评估 CMake 生成器表达式

CMake generator expression is not evaluated

我不明白我做错了什么。 我总是得到字符串 "$<TARGET_FILE:tgt1>" 而不是库的路径。

我已经创建了虚拟项目。

这是我的根CMakeLists.txt

cmake_minimum_required (VERSION 3.0) # also tried 2.8 with the same result
set(PROJECT_NAME CMP0026)

add_subdirectory(src)

set(TGT_PATH $<TARGET_FILE:tgt1>)
message(STATUS "${TGT_PATH}")

这是我的 src/CMakeLists.txt

add_library(tgt1 a.c)

文件 a.c 已创建且为空

我尝试了以下生成器:Visual Studio 2013 Win64、Ninja 和 MingW Makefile。最后两个我使用了 Android 工具链,从 here

下载

我希望最后的 message(STATUS 命令会打印库的完整路径。但是,所有变体都会打印字符串 $<TARGET_FILE:tgt1>.

生成器表达式不会在配置时进行评估(当 CMake 正在解析 CMakeLists,执行 add_target()message() 等命令时)。此时,生成器表达式只是一个文字字符串 - 字符 $ 后跟 <,然后是 T,然后是 ...

生成器表达式的计算发生在 generate 时间(这就是它们被称为 "generator expressions" 的原因)。生成时间发生在解析和处理所有 CMake 代码之后,CMake 开始作用于其中的数据以生成构建系统文件。只有 then 才具有计算生成器表达式所需的所有信息。

因此,您只能真正将生成器表达式用于生成时或之后发生的事情(例如构建时)。一个人为的例子是这样的:

add_custom_target(
  GenexDemo
  COMMAND ${CMAKE_COMMAND} -E echo "$<TARGET_FILE:tgt1>"
  VERBATIM
)

在配置时,CMake 会记录文字字符串 $<TARGET_FILE:tgt1> 作为 COMMAND 的参数。然后在生成时(当每个配置都知道 tgt1 的位置并保证不再更改时),它将用它代替生成器表达式。