最新版本的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互斥锁,那么构建速度可能会受到影响。预配方并在配方后发布。
我可以修改每个目标,如果需要的话。
答案 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
<强>说明:强>
d
shell变量。&&
运算符链接命令:如果一个失败,整个列表将以相同的退出状态失败,make会告诉您。\
,但最后一行。更具可读性,但仍被make解释为单行。mktemp
)以原子方式创建唯一的临时文件。使用您环境中可用的任何等效项。请注意$
中的双d=$$(mktemp)
。需要通过make传递第一个扩展,并在传递给shell时成为d=$(mktemp)
。在引用shell变量d
的shell扩展时也是如此:$$d
在传递给shell之前首先由make $d
展开。>> $d 2>&1
)将标准输出重定向到追加模式(>> $d
)中的临时文件,并使标准错误描述符成为标准输出描述符(2>&1
),同时将标准错误附加到同一个临时文件中。