CMake外部文件作add_custom_command参数跨平台问题解决
CMake读取外部文件作为命令参数跨平台异常修复
问题复现
存在外部配置文件images.list,内容为:
find "file1.png" add "file2.png"
初始CMake实现逻辑如下:
- 读取文件内容到变量:
file(READ "images.list" FILE_CONTENTS)
- 拼接生成命令参数列表:
set(CMD_ARGS --raw --build-list ${FILE_CONTENTS} > "${CMAKE_BINARY_DIR}/image.h")
- 配置自定义构建命令,调用
gdk-pixbuf-csource生成目标头文件:
add_custom_command(OUTPUT "${CMAKE_BINARY_DIR}/image.h" MAIN_DEPENDENCY "${PROJECT_SOURCE_DIR}/images.list" WORKING_DIRECTORY ${DATADIR} COMMAND gdk-pixbuf-csource ARGS ${CMD_ARGS} COMMENT "Compilando GLIB resources..." )
异常表现
上述逻辑在Windows 7环境可正常运行,在Linux环境下会生成空白的image.h文件。调试参数时发现存在参数粘连、多余转义符问题,实际传入的参数为:
--raw--build-listfind \ "file1.png"
预期的正确参数格式应为:
--raw --build-list find "file1.png" add "file2.png" > "/a/nice/path/image.h"
解决方案
异常根源是file(READ)读取到的文件内容是未拆分的整段字符串,直接拼接到参数列表时,CMake不会自动按当前系统的shell规则拆分参数,跨平台场景下还会因为不同系统的转义逻辑差异生成错误的转义符。
使用separate_arguments命令搭配NATIVE_COMMAND参数,可自动将读取到的整段字符串按当前运行平台的原生shell参数规则拆分为独立参数项,实现跨平台兼容,修正后代码如下:
file(READ ${GRESOURCE_FILE_SRC} FILE_CONTENTS) separate_arguments(FILE_CONTENTS_PROCESSED NATIVE_COMMAND ${FILE_CONTENTS}) set(CMD_ARGS --raw --build-list ${FILE_CONTENTS_PROCESSED} > "${CMAKE_BINARY_DIR}/images.h")
经过上述处理后,参数不会再出现粘连、多余转义的问题,Windows、Linux环境下均可正常生成目标头文件。
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

