GNU make 3.81 - 怎么做' - output-sync = target'

时间:2016-06-21 16:12:43

标签: c++ makefile gnu-make

最新版本的make有一个选项--output-sync,可以使每个目标的 STDOUT 成为原子,以便在使用{{1}时不会交错来自多个目标的语句}}

不幸的是,我必须使用make --jobs=N,因为这是我们SDK附带的版本。

为了确定我是否需要make v 3.81,我添加了一些'保护声明'围绕我的目标

--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 功能?

据我所知,如果有一种方法可以锁定STDOUT互斥锁,那么构建速度可能会受到影响。预配方并在配方后发布。

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

1 个答案:

答案 0 :(得分:0)

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

%.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展开。
  • 命令输出的重定向(在make首次扩展后>> $d 2>&1)将标准输出重定向到追加模式(>> $d)中的临时文件,并使标准错误描述符成为标准输出描述符(2>&1),同时将标准错误附加到同一个临时文件中。