c++ - GNU make 3.81 - 如何做 '--output-sync=target'

标签 c++ makefile gnu-make

make 的最新版本有一个选项 --output-sync 可以使每个目标的 STDOUT 成为原子的,这样来自的语句使用 make --jobs=N

时多个目标不会交错

不幸的是,我必须使用 make v 3.81,因为这是我们的 SDK 附带的。

为了确定我是否需要 --output-sync,我在我的目标周围添加了一些“保护语句”

all: $(patsubst %.cpp, %.o, $(wildcard *.cpp))


%.o: %.cpp  
    @echo BEFORE
    @echo MAKEFLAGS=$(MAKEFLAGS)
    qcc.exe $(CC_FLAGS) $@ $< 
    @echo AFTER

输出非常交错。

AFTER
BEFOREAFTER
AFTER
AFTER

有没有办法模拟--output-sync 功能?

我知道构建速度可能会受到影响,例如,如果有一种方法可以“锁定 STDOUT 互斥锁”前配方并在后配方中释放它。

如果需要的话,我可以修改我们的每个目标。

最佳答案

您可以将配方的所有输出记录在一个临时文件中,并在最后将其删除:

%.o: %.cpp
    @d=$$(mktemp) && \
    echo BEFORE >> $$d 2>&1 && \
    echo MAKEFLAGS=$(MAKEFLAGS) >> $$d 2>&1 && \
    qcc.exe $(CC_FLAGS) $@ $< >> $$d 2>&1 && \
    echo AFTER >> $$d 2>&1 && \
    cat $$d && \
    rm $$d

这不会完全阻止交错,因为如果您有多个 CPU,多个 cat 命令可以并行运行,但它应该会显着降低概率。如果您真的想完全避免交错,则必须在 cat 命令周围添加一个自旋锁。在 GNU/Linux 操作系统下,您可以查看 flock,例如:

%.o: %.cpp
    @d=$$(mktemp) && \
    echo BEFORE >> $$d 2>&1 && \
    echo MAKEFLAGS=$(MAKEFLAGS) >> $$d 2>&1 && \
    qcc.exe $(CC_FLAGS) $@ $< >> $$d 2>&1 && \
    echo AFTER >> $$d 2>&1 && \
    flock /tmp/my-lock-file cat $$d && \
    rm $$d

解释:

  • 我在单个 shell 调用中转换了您的配方(make 配方中的每一行都在不同的 shell 中执行),这样 d shell 变量在列表中的所有命令中都可用。<
  • 命令使用 && 运算符链接起来:如果一个失败,则整个列表失败并具有相同的退出状态,make 会告诉您。
  • 我没有将所有命令放在同一行,这很快就变得难以阅读了,我在除最后一行以外的所有行尾之前添加了 \。更具可读性,但仍被 make 解释为单行。
  • 列表中的第一个命令 (mktemp) 自动创建一个唯一的临时文件。使用您的环境中可用的任何等效项。注意 d=$$(mktemp) 中的双 $。需要通过 make 传递第一次展开,传递给 shell 时变成d=$(mktemp)。引用 shell 变量 d 的 shell 扩展时相同:$$d 在传递给 shell 之前首先被 make 扩展为 $d .
  • 命令输出的重定向(>> $d 2>&1 after first expansion by make)将标准输出重定向到附加模式的临时文件(>> $ d) 并使标准错误描述符成为标准输出描述符 (2>&1) 的拷贝,其效果是将标准错误附加到同一个临时文件。

关于c++ - GNU make 3.81 - 如何做 '--output-sync=target',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37949528/

相关文章:

c++ - 如何让 atoi() 函数在字符串上工作?

c++ - 在类定义之外使用 enable_if 实现函数

windows - mingw make 无法处理路径中的空格?

makefile - 在 dotfiles 存储库中管理用户的 crontab

c++ - KMP算法和LPS表构建的运行时间

java - 传递常量会自动通过引用传递吗?

c++ - 通过命令行设置 CPPFLAGS

makefile - makefile 中使用 m4 处理文件

c - 两个相同的模式规则会发生什么?

makefile - CENTOS - Linux - Make - Makefile(获取用户输入不起作用)