并行输出

时间:2011-03-22 13:38:31

标签: build-process makefile cmake

当运行带有多个进程(make -jN)的CMake生成的Makefile时,输出通常会像这样搞乱:

[  8%] [  8%] [  9%] Building CXX object App/CMakeFiles/App.dir/src/File1.cpp.o
Building CXX object App/CMakeFiles/App.dir/src/File2.cpp.o
Building CXX object App/CMakeFiles/App.dir/src/File3.cpp.o

我不确定,但我认为这种行为也适用于不是由CMake生成的Makefile。我会说当多个进程同时写入stdout时会发生这种情况。

我知道我可能很迂腐,但有没有(简单)解决这个问题? ;)

6 个答案:

答案 0 :(得分:9)

如果您正在使用GNU make,则可以通过重新定义SHELL来完成此操作,以便命令由一个简单的实用程序包装,该实用程序可确保打印到标准输出的信息的原子性。 Here's更详细的描述,包括包装器实用程序的示例源。

答案 1 :(得分:5)

我试图让CMake的人解决这个问题,但显然他们不想这样做。请参阅http://www.cmake.org/Bug/view.php?id=7062

答案 2 :(得分:2)

与使用make并且N> 1的交错-jN输出相关的特定CMake错误是CMake bug 0012991: "Parallel build output mess"。它仍然在"积压"国家等待修复。

这个错误实际上很烦人,因此有必要切换到Ninja而不是 make 。此外, Ninja 的速度比 make 更快。 Ninja还根据存在的CPU核心数使用适当数量的并行作业。同样很酷的是Ninja默认情况下非常安静:除非构建过程发出消息或构建步骤失败,否则所有进度都会在终端中的一行上发生。如果构建步骤失败,Ninja将打印调用它的完整命令行并显示输出。它非常好,因为它会使任何警告或错误消息脱颖而出。虽然目前没有彩色终端输出:这将是一个很好的改进,但对我来说, Ninja 优于 make 的优势是巨大的。

答案 3 :(得分:0)

Linux和Solaris上提供的Sun(现在的Oracle)dmake可以解决这个问题。 请参阅herethere

答案 4 :(得分:0)

这是一个使用包装器进行Make的简单工作示例。我不确定是否要鼓励使用它,但这是一个主意。

# Makefile
SHELL = /tmp/test/wrapper

test: test1 test2

test1:
    $(eval export TARGET=$@)
    env

test2:
    $(eval export TARGET=$@)
    env

这:

#!/usr/bin/env bash
# wrapper
bash $@ | sed -e "s/^/${TARGET} /"

答案 5 :(得分:0)

看起来已经是fixed。在命令行中添加一个-Oline参数:

make -j 8 -Oline

制造版本:

GNU Make 4.3
Built for x86_64-pc-msys