如何在带有“未污染”环境的CMake中执行自定义命令?

时间:2019-10-09 13:27:28

标签: makefile cmake gnu-make

问题: 我有一个add_custom_command,它调用一个外部工具,该工具通过gmake建立一些外部库。 gmake输出将记录到日志文件中。

CMake使用Unix Makefile作为生成器目标,并设置$(VERBOSE).SILENT。 该选项以某种方式被gmake继承(可能通过MAKEFLAGS),该工具从在add_custom_command生成的顶级make文件中执行的工具中调用。因此,该日志文件不包含任何有用的信息。

这不是理想的-二手CMake生成器及其内部选件无意间泄漏到了我的外部工具中。有什么办法可以防止这种情况?

这是CMakeLists中的代码,可以更好地说明问题:

...
add_custom_command(OUTPUT "<some target name>"
                   COMMAND ${BUILDTOOL_COMMAND} # i.e. buildtool <buildtool args>
                   VERBATIM)
...

CMake为此生成build.make文件,其内容如下:

...
# Suppress display of executed commands.
$(VERBOSE).SILENT:

...

<some target name>: 
    buildtool <buildtool args>
...

2 个答案:

答案 0 :(得分:0)

因此,这里可能发生的情况是VERBOSE变量的值正在导出到子级环境中,包括您的“ buildtool”(无论如何)。而且,由buildtool 调用的makefile也使用相同的变量来控制详细输出,因此CMake中VERBOSE变量的设置导致在调用buildtool的makefile中具有相同的冗长设置

我对“ buildtool”一无所知,所以我不知道您可能有什么资源来解决此问题。

如果您直接调用make,则可以在命令行上覆盖它,例如:

add_custom_command(OUTPUT "<some target name>"
                   COMMAND make VERBOSE=1
                   VERBATIM)

无论环境设置如何,都强制VERBOSE=1

您将必须弄清楚如何用我期望的“ buildtool”来做类似的事情。如果“ buildtool”将变量设置转发到make,则也许可以做到这一点。

答案 1 :(得分:0)

VERBOSE=1传递给sub-make无效。当您的自定义命令是任何类型的make时,它将通过MAKEFLAGS从顶部的Makefile(由cmake生成的命令)中接收其静默设置。通过在调用--silent之前显式设置MAKEFLAGS来摆脱make,即:

$ cat Makefile
all:
        env -i MAKEFLAGS=$(subst s,,$(MAKEFLAGS)) make -f Makefile2

$(VERBOSE).SILENT:
$ cat Makefile2
all:
        echo "In Makefile2: $@"
        echo "MAKEFLAGS = $(MAKEFLAGS)"

输出({-k仅用于检查是否仅剥离-s标志):

$ make -k
echo "In Makefile2: all"
In Makefile2: all
echo "MAKEFLAGS = k"
MAKEFLAGS = k

请注意,顶层Makefile仍然保持沉默,而照常打印子Makefile。

您可以尝试相应地更新COMMAND中的add_custom_command。工作示例:

$ cat CMakeLists.txt
add_custom_command(
    OUTPUT bar
    COMMAND env "MAKEFLAGS=$(subst s,,$(MAKEFLAGS))" make -f ../Makefile2
    VERBATIM
    )

add_custom_target(foo DEPENDS bar)

输出:

$ cmake .
...
$ make foo
[100%] Generating bar
make[4]: Entering directory '/path/to/dir'
echo "In Makefile2: all"
In Makefile2: all
echo "MAKEFLAGS = w"
MAKEFLAGS = w
make[4]: Leaving directory '/path/to/dir'
[100%] Built target foo