如何在CMake中使用"纯净"环境执行自定义命令?
解决CMake MAKEFLAGS泄露到外部gmake的问题
这个问题很典型——CMake的Unix Makefiles生成器会通过MAKEFLAGS环境变量传递自身的静默编译选项(也就是你看到的$(VERBOSE).SILENT),很容易不小心泄露给子进程里的外部gmake调用,导致日志无法记录有效输出。这里有两种简单可靠的解决方法:
方法1:显式清除MAKEFLAGS(推荐)
在add_custom_command的COMMAND中,用env MAKEFLAGS=前缀来重置环境变量,确保外部工具启动的gmake不会继承CMake的内部选项。修改你的CMake代码如下:
add_custom_command( OUTPUT "<some target name>" COMMAND env MAKEFLAGS= ${BUILDTOOL_COMMAND} # 清除MAKEFLAGS后调用外部构建工具 VERBATIM )
原理说明
env MAKEFLAGS=会在执行你的${BUILDTOOL_COMMAND}之前,将MAKEFLAGS环境变量设置为空。这样外部工具调用gmake时,就不会收到CMake传递的--silent或-s这类静默选项,日志就能正常捕获gmake的输出了。加上VERBATIM选项能保证命令被正确转义,避免shell环境下的意外问题。
方法2:过滤MAKEFLAGS中的静默选项
如果你需要保留MAKEFLAGS中的其他参数,只移除静默相关的选项,可以用shell命令过滤:
add_custom_command( OUTPUT "<some target name>" COMMAND bash -c 'export MAKEFLAGS=$(echo "$MAKEFLAGS" | sed "s/--silent//; s/-s//"); ${BUILDTOOL_COMMAND}' VERBATIM )
原理说明
这个命令会先用sed去掉MAKEFLAGS中的--silent和-s参数,再执行外部构建工具。不过这种方法依赖bash和sed,跨平台性稍差,所以更推荐第一种方法。
修改后,CMake生成的build.make文件中对应的命令会带上环境变量重置逻辑,彻底避免内部选项泄露到外部工具中。
内容的提问来源于stack exchange,提问作者Dan M.
相关产品推荐
相关产品推荐

