如何通过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
相关产品推荐
相关产品推荐

