为何LINK_LIBRARIES的生成器表达式未被解析?求解决办法及文档依据
CMake导出目标属性时LINK_LIBRARIES的生成器表达式未解析问题
问题重现
使用file(GENERATE)导出CMake目标属性时,LINK_LIBRARIES属性中的生成器表达式未被解析,而INCLUDE_DIRECTORIES、COMPILE_DEFINITIONS等其他属性的表达式均正常展开。示例代码及Debug配置输出如下:
示例代码
cmake_minimum_required(VERSION 3.10.0) project(Test) add_executable(Exec main.cpp) target_link_libraries(Exec PRIVATE Lib0 $<IF:$<CONFIG:Debug>,Lib1,Lib2>) target_include_directories(Exec PRIVATE /Dir0 $<IF:$<CONFIG:Debug>,/Dir1,/Dir2>) target_compile_definitions(Exec PRIVATE -DVALUE=Val0 -DVALUE=$<IF:$<CONFIG:Debug>,Val1,Val2>) target_compile_options(Exec PRIVATE Opt0 $<IF:$<CONFIG:Debug>,Opt1,Opt2>) set(EXPR "\ $<TARGET_PROPERTY:Exec,LINK_LIBRARIES> $<TARGET_PROPERTY:Exec,INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:Exec,COMPILE_DEFINITIONS> $<TARGET_PROPERTY:Exec,COMPILE_OPTIONS> ") file(GENERATE OUTPUT output$<CONFIG>.txt CONTENT "${EXPR}")
Debug配置输出
Lib0;$<IF:$<CONFIG:Debug>,Lib1,Lib2> /Dir0;/Dir1 VALUE=Val0;VALUE=Val1 Opt0;Opt1
解决办法
不要直接通过$<TARGET_PROPERTY:Exec,LINK_LIBRARIES>获取链接库列表,改用$<TARGET_LINK_LIBRARIES:Exec>生成器表达式。修改后的EXPR变量定义如下:
set(EXPR "\ $<TARGET_LINK_LIBRARIES:Exec> $<TARGET_PROPERTY:Exec,INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:Exec,COMPILE_DEFINITIONS> $<TARGET_PROPERTY:Exec,COMPILE_OPTIONS> ")
修改后Debug配置下的输出会变为:
Lib0;Lib1 /Dir0;/Dir1 VALUE=Val0;VALUE=Val1 Opt0;Opt1
官方文档说明
CMake官方文档明确了以下核心差异:
LINK_LIBRARIES目标属性存储的是原始未展开的链接库条目,保留未解析的生成器表达式,用于后续配置或生成阶段的动态处理。$<TARGET_LINK_LIBRARIES:target>生成器表达式的作用是展开目标的所有链接库条目,解析其中的生成器表达式,输出最终的链接库列表。
其他属性(如INCLUDE_DIRECTORIES、COMPILE_DEFINITIONS)在通过TARGET_PROPERTY获取时会自动解析生成器表达式,是因为它们的存储机制与LINK_LIBRARIES不同——这类属性在配置阶段会被部分或完全展开,而LINK_LIBRARIES则保留原始表达式直到链接阶段。
内容的提问来源于stack exchange,提问作者Maciej Dziuban
相关产品推荐
相关产品推荐

