控制 make 的详细程度

发布于 2025-01-06 11:03:28 字数 575 浏览 1 评论 0原文

我正在使用 makefile 来编译由许多 .c 文件组成的程序,并且任何时候 make 被调用时,它只编译上次运行后修改的那些文件(没什么特别的)直到这里)。

为了避免屏幕混乱,我在每个 $(CC) 调用的开头添加 @,并在其之前打印一条自定义的 echo 消息。例如:

%.o: %.c $(h1) $(h3) %.h
    @echo -e "\tCompiling <" $< 
    @$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)

我的问题是:如何以更“动态的方式”控制 make 的详细程度,以便能够:

  1. 正常行为:仅自定义为每个执行的 makefile 规则打印消息。
  2. 详细行为:打印每个 makefile 规则实际执行的命令(就好像根本没有使用 @)。

I'm using a makefile to compile a program made of many .c files, and any time make is invoked it only compiles those files modified after the last run (nothing special until here).

To avoid cluttering my screen, I prepend @ at the beginning of each $(CC) call, and before it I print a customized echo message. For example:

%.o: %.c $(h1) $(h3) %.h
    @echo -e "\tCompiling <" 
lt; 
    @$(CC) $(CFLAGS) -c 
lt; -o $(libDir)$@$(MATHOPTS)

My question is: how can I control the verbosity of make in a more "dynamic way", in order to be able to:

  1. Normal behaviour: only a customized message is printed for every makefile rule executed.
  2. Verbose behaviour: print the command actually executed by every makefile rule (as if the @ wasn't used at all).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

旧伤还要旧人安 2025-01-13 11:03:28

我会按照 automake 的方式来做:

V = 0
ACTUAL_CC := $(CC)
CC_0 = @echo "Compiling 
lt;..."; $(ACTUAL_CC)
CC_1 = $(ACTUAL_CC)
CC = $(CC_$(V))

%.o: %.c $(h1) $(h3) %.h
        $(CC) $(CFLAGS) -c 
lt; -o $(libDir)$@$(MATHOPTS)

如果您需要在规则中执行其他命令,我喜欢下面的代码片段。写$(AT)而不是@,当V=0时不显示,而当V=1时打印>。

AT_0 := @
AT_1 := 
AT = $(AT_$(V))

I'd do it the way automake does:

V = 0
ACTUAL_CC := $(CC)
CC_0 = @echo "Compiling 
lt;..."; $(ACTUAL_CC)
CC_1 = $(ACTUAL_CC)
CC = $(CC_$(V))

%.o: %.c $(h1) $(h3) %.h
        $(CC) $(CFLAGS) -c 
lt; -o $(libDir)$@$(MATHOPTS)

If you need to execute other commands in your rules, I like the following snippet. Write $(AT) instead of @ and it will be silent when V=0 but printed when V=1.

AT_0 := @
AT_1 := 
AT = $(AT_$(V))
送你一个梦 2025-01-13 11:03:28

另一种解决方案(我喜欢它,因为它很灵活)

ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif

%.o: %.c
    $(vecho) "-> Compiling $@"
    $(Q)$(CC) $(CFLAGS) -c 
lt; -o $@

您可以跳过 vecho 内容,但它有时确实会派上用场。

Another solution (one which I like because it's flexible)

ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif

%.o: %.c
    $(vecho) "-> Compiling $@"
    $(Q)$(CC) $(CFLAGS) -c 
lt; -o $@

You can skip the vecho stuff, but it does come in handy at times.

小傻瓜 2025-01-13 11:03:28

您可以省略“@”并将“-s”选项传递给 make 命令,而不是使用“@gcc”进行编译。 (保留“@echo”原样。)然后“make -s”将是简短的 make 命令,“make”将是详细命令。

要制作的“-s”或“--silent”标志可防止所有回显,就好像所有食谱都以“@”开头一样。

来自 GNU Make 手册页

(其他答案更好回答你的问题,但这种方法值得一提。)

Instead of using "@gcc" to compile, you can omit that "@" and pass the "-s" option to your make command instead. (Leave "@echo" as it is.) Then "make -s" would be your brief make command, and "make" would be verbose.

The ‘-s’ or ‘--silent’ flag to make prevents all echoing, as if all recipes started with ‘@’.

From the GNU Make manual pages

(The other answers better answer your question, but this approach deserves a mention.)

烟若柳尘 2025-01-13 11:03:28

我将创建一个函数,它接受一个命令来执行并决定是否回显它。

# 'cmd' takes two arguments:
#   1. The actual command to execute.
#   2. Optional message to print instead of echoing the command
#      if executing without 'V' flag.
ifdef V
cmd = $1
else
cmd = @$(if $(value 2),echo -e "$2";)$1
endif

%.o: %.c $(h1) $(h3) %.h
    $(call cmd, \
        $(CC) $(CFLAGS) -c 
lt; -o $(libDir)$@$(MATHOPTS), \
        Compiling 
lt;)

那么普通 make 调用的结果将类似于:

Compiling foo.c

make V=1 将给出:

gcc -Wall -c foo.c -o foo.o ...

I would create a function which takes a command to execute and decides whether to echo it.

# 'cmd' takes two arguments:
#   1. The actual command to execute.
#   2. Optional message to print instead of echoing the command
#      if executing without 'V' flag.
ifdef V
cmd = $1
else
cmd = @$(if $(value 2),echo -e "$2";)$1
endif

%.o: %.c $(h1) $(h3) %.h
    $(call cmd, \
        $(CC) $(CFLAGS) -c 
lt; -o $(libDir)$@$(MATHOPTS), \
        Compiling 
lt;)

Then the result of plain make invocation will be something like:

Compiling foo.c

Whereas make V=1 will give:

gcc -Wall -c foo.c -o foo.o ...
抚你发端 2025-01-13 11:03:28

由于我无法评论 AT = $(AT_$(V)) 建议,请注意 Automake 确实提供了一个标准宏,其功能与 AT 相同,称为AM_V_at

您还会发现它还有另一个非常有用的 AM_V_GEN 变量,该变量要么解析为空,要么解析为 @echo " GEN " $@;,具体取决于详细程度。

这允许您编写如下代码:

grldr.mbr: mbrstart
    $(AM_V_GEN)
    $(AM_V_at)-rm -f grldr.mbr
    $(AM_V_at)cat mbrstart > grldr.mbr

其输出将是(禁用详细程度):

  GEN    grldr.mbr

或(启用详细程度):

rm -f grldr.mbr
cat mbrstart > grldr.mbr

非常方便,这消除了定义您自己的宏的需要。

Since I can't comment on the AT = $(AT_$(V)) suggestion, note that Automake does provide a standard macro that does the same thing as AT, which is called AM_V_at.

You will also find that it has another very useful AM_V_GEN variable, that resolves either to nothing or to @echo " GEN " $@;, depending on the verbosity.

This allows you to code something like this:

grldr.mbr: mbrstart
    $(AM_V_GEN)
    $(AM_V_at)-rm -f grldr.mbr
    $(AM_V_at)cat mbrstart > grldr.mbr

The output of which will be either (verbosity disabled):

  GEN    grldr.mbr

or (verbosity enabled):

rm -f grldr.mbr
cat mbrstart > grldr.mbr

Pretty convenient, and this removes the need to define your own macros.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文