不使用CMake时,在执行前如何制作make打印命令

60

我发现这与Making cmake print commands before executing是相同的问题。

但那个答案对我不起作用。我猜那个答案只适用于cmake。有什么选项可以在没有cmake的情况下工作?

注意尝试了这些方法:

make VERBOSE=1 target
make target VERBOSE=1
VERBOSE=1 make target
make V=1 target
make target V=1
V=1 make target
make -V target
make -v target

它们都没有起作用。

make -v 返回

GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for x86_64-pc-linux-gnu

我们已经讨论过这个问题,但我刚刚发现另一个看起来非常相似的问题:有没有办法让“make”回显命令 - Reinier Torenbeek
可能是重复的问题:如何强制make/gcc显示命令? - Ciro Santilli OurBigBook.com
4个回答

145

默认情况下,make在执行每个命令之前都会打印出来。你可以通过以下一种机制之一来禁止打印:

  • 针对单个命令,可以在命令前加上@
  • 全局地,可以添加内置目标.SILENT。
  • make过程中的某个位置,可以使用-s, --silent 或者 --quiet等标志调用子 make,例如:$(MAKE) --silent -C someDir 。从那时起,在子make中将停止显示命令。

如果您的Makefile不打印命令,则可能正在使用这三种机制中的一种,您需要实际检查Makefile以找出到底是哪种机制。

为了避免这些抑制回显的机制,您可以重新定义要使用的 shell 以使用调试模式,例如 make SHELL="/bin/bash -x" target。其他 shells 也有类似的选项。使用该方法时,打印命令的不是make,而是shell本身。

如果使用标志-n--just-print,则会忽略抑制回显的机制,并始终看到make认为应该执行的所有命令 -- 但实际上它们并没有被执行,只是打印出来。这可能是了解实际上会执行哪些命令的好方法。

VERBOSE变量对于make没有标准含义,而只有在您的Makefile中解释它时才有效。


1
那么没有办法让它打印执行什么吗?-n 不起作用,因为我需要在上下文中看到它失败,而由于某种原因,执行 -n 的输出与没有 -n 不同。 - gman
4
好的,作为最后的办法,你可以通过在运行make时定义SHELL=/bin/bash -x来实现解决方法——假设你可以使用bash。由于make使用在$SHELL中找到的值来执行命令,因此这将导致由于-x标志而首先回显每个命令。我会将其添加到答案中,如果这对你有用,请告诉我。 - Reinier Torenbeek
3
很奇怪。对我来说,“make SHELL="/bin/bash -x" target”会显示所有已执行的shell命令,与makefile的样子无关。当你说“没有运气”的时候,这是否意味着你完全看不到任何不同之处,还是它输出一些东西但并非你想要的命令?如果你先执行“make clean”,然后再执行“make SHELL="/bin/bash -x" target”会怎样? - Reinier Torenbeek
更准确地说,“VERBOSE”似乎在由CMake和Autotools生成的Makefile中使用。 - Ciro Santilli OurBigBook.com
我喜欢 SHELL= 的输出,但有没有办法将该输出导向文件? - RufusVS
显示剩余6条评论

3

在我的情况下,我能够通过在我的Makefile的顶部设置以下变量来抑制输出中的命令:

# Use `make V=1` to print commands.
$(V).SILENT:

在您的 makefile 文件顶部添加上述行,当您调用任何目标时它不会打印输出。

之前:

muhasan@admins-MacBook-Pro fx.identitymanagement % make dockerstatus
cd identity.API/ && docker-compose ps 
        Name                       Command              State           Ports         
--------------------------------------------------------------------------------------
identityapi_backend_1   dotnet Identity.API.dll         Up      0.0.0.0:5000->80/tcp  
identityapi_db_1        docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp
muhasan@admins-MacBook-Pro fx.identitymanagement % 

之后:

muhasan@admins-MacBook-Pro fx.identitymanagement % make dockerstatus
        Name                       Command              State           Ports         
--------------------------------------------------------------------------------------
identityapi_backend_1   dotnet Identity.API.dll         Up      0.0.0.0:5000->80/tcp  
identityapi_db_1        docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp
muhasan@admins-MacBook-Pro fx.identitymanagement % 
 

我的 Makefile

# Use `make V=1` to print commands.
$(V).SILENT:
Path = identity.API
builddocker:
    cd devops && cp -rv Dockerfile docker-compose.yml ../${Path}/ && cd ..
installdocker:
    cd ${Path}/ && docker-compose up -d
dockerstatus:
    cd ${Path}/ && docker-compose ps    

3

对于我的make版本,我发现-n-d两个参数都很有用。

GNU Make 3.80 版权所有 (C) 2002 Free Software Foundation, Inc

  -d                          Print lots of debugging information.
  -n, --just-print, --dry-run, --recon
                              Don't actually run any commands; just print them.

当包含一堆makefile片段时,如果没有这个调试标志,行号就没有意义。
CreateProcess(....exe,...)
Reading makefile `../../../../build/Makefile.options' (search path) (don't care) (no ~ expansion)...
Makefile:361: Extraneous text after `else' directive
Makefile:368: Extraneous text after `else' directive
Makefile:368: *** only one `else' per conditional.  Stop.

1

我认为这是您想要的内容: 执行命令 MAKE_VERBOSE=1 target


3
除非您的Makefile定义并使用它,否则“MAKE_VERBOSE” make变量对于make本身没有特殊含义。 - qneill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接