You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过CMake生成器表达式判断目标的编译语言?

问题:区分CUDA和C++目标的生成器表达式写法

我想通过生成器表达式给部分目标的编译命令行添加不同文本——CUDA目标加foo,C++目标加bar,而且必须用同一个生成器表达式。本来想写类似$<IF:$<TARGET_LANGUAGE:CUDA>,foo,bar>的代码,但发现根本没有TARGET_LANGUAGE这个生成器表达式。查了目标相关的生成器表达式列表(如下),也没找到能判断目标语言的,该怎么解决?

TARGET_EXISTS
TARGET_NAME_IF_EXISTS
TARGET_NAME
TARGET_PROPERTY
TARGET_OBJECTS
TARGET_POLICY
TARGET_FILE
TARGET_FILE_BASE_NAME
TARGET_FILE_PREFIX
TARGET_FILE_SUFFIX
TARGET_FILE_NAME
TARGET_FILE_DIR
TARGET_IMPORT_FILE
TARGET_IMPORT_FILE_BASE_NAME
TARGET_IMPORT_FILE_PREFIX
TARGET_IMPORT_FILE_SUFFIX
TARGET_IMPORT_FILE_NAME
TARGET_IMPORT_FILE_DIR
TARGET_LINKER_FILE
TARGET_LINKER_FILE_BASE_NAME
TARGET_LINKER_FILE_PREFIX
TARGET_LINKER_FILE_SUFFIX
TARGET_LINKER_FILE_NAME
TARGET_LINKER_FILE_DIR
TARGET_LINKER_LIBRARY_FILE
TARGET_LINKER_LIBRARY_FILE_BASE_NAME
TARGET_LINKER_LIBRARY_FILE_PREFIX
TARGET_LINKER_LIBRARY_FILE_SUFFIX
TARGET_LINKER_LIBRARY_FILE_NAME
TARGET_LINKER_LIBRARY_FILE_DIR
TARGET_LINKER_IMPORT_FILE
TARGET_LINKER_IMPORT_FILE_BASE_NAME
TARGET_LINKER_IMPORT_FILE_PREFIX
TARGET_LINKER_IMPORT_FILE_SUFFIX
TARGET_LINKER_IMPORT_FILE_NAME
TARGET_LINKER_IMPORT_FILE_DIR
TARGET_SONAME_FILE
TARGET_SONAME_FILE_NAME
TARGET_SONAME_FILE_DIR
TARGET_SONAME_IMPORT_FILE
TARGET_SONAME_IMPORT_FILE_NAME
TARGET_SONAME_IMPORT_FILE_DIR
TARGET_PDB_FILE
TARGET_PDB_FILE_BASE_NAME
TARGET_PDB_FILE_NAME
TARGET_PDB_FILE_DIR
TARGET_BUNDLE_DIR
TARGET_BUNDLE_DIR_NAME
TARGET_BUNDLE_CONTENT_DIR
TARGET_RUNTIME_DLLS
TARGET_RUNTIME_DLL_DIRS

解决方法

可以利用TARGET_PROPERTY生成器表达式获取目标的LANGUAGE属性,再结合STREQUAL和IF表达式实现分支判断,最终写法如下:

$<IF:$<STREQUAL:$<TARGET_PROPERTY:LANGUAGE>,CUDA>,foo,bar>

原理说明

  • $<TARGET_PROPERTY:LANGUAGE>:获取当前目标的编程语言属性值,这个属性是CMake目标创建时自动或手动指定的(比如add_executable(my_target main.cpp)的LANGUAGE为C++,add_executable(my_target kernel.cu)或add_executable(my_target main.cpp LANGUAGE CUDA)的LANGUAGE为CUDA)
  • $<STREQUAL:A,B>:比较两个字符串是否相等,这里用来判断目标语言是否为CUDA
  • $<IF:condition,true_val,false_val>:根据条件结果选择对应文本

注意事项

如果你的目标是混合语言目标(同一个目标中包含CUDA和C++源文件),目标的LANGUAGE属性只会对应创建时指定的主语言,此时目标级别的表达式无法区分不同源文件的编译语言。这种情况下可以改用源文件级别的生成器表达式$<COMPILE_LANGUAGE:CUDA>,比如给单个源文件添加编译选项时:

target_compile_options(my_target PRIVATE
  $<$<COMPILE_LANGUAGE:CUDA>:foo>
  $<$<COMPILE_LANGUAGE:CXX>:bar>
)

内容的提问来源于stack exchange,提问作者einpoklum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 07:27:46