并行输出

发布于 2024-10-25 09:41:10 字数 398 浏览 4 评论 0 原文

当使用多个进程(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。我想说当多个进程同时写入标准输出时会发生这种情况。

我知道我可能很迂腐,但是有什么(简单的)解决办法吗? ;)

When running a CMake generated Makefile with multiple processes (make -jN), the output often gets messed up like this:

[  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

I'm not sure, but I think this behavior is also there for Makefiles not generated by CMake. I'd say it happens when multiple processes write to stdout at the same time.

I know I'm probably being pedantic, but is there any (simple) fix to this? ;)

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

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

发布评论

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

评论(6

半步萧音过轻尘 2024-11-01 09:41:10

如果您使用的是 GNU make,则可以通过重新定义 SHELL 来实现,这样命令就会被一个简单的实用程序包装起来,从而确保打印到标准输出的信息的原子性。 这里更详细的说明,包括包装器实用程序的示例源代码。

If you're using GNU make, you can do it by redefining SHELL such that commands are wrapped by a trivial utility that ensures atomicity of information printed to standard output. Here's a more detailed description, including sample source for the wrapper utility.

半山落雨半山空 2024-11-01 09:41:10

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

I tried to get the CMake people to fix this, but apparently they don't want to. See http://www.cmake.org/Bug/view.php?id=7062.

染年凉城似染瑾 2024-11-01 09:41:10

与使用 -jN 且 N>1 交错 make 输出相关的特定 CMake 错误是 CMake 错误 0012991:“并行构建输出混乱”。它仍然处于“积压”状态,等待修复。

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

The specific CMake bug related to interleaved make output using -jN with N>1 is CMake bug 0012991: "Parallel build output mess". It is still open in the "backlog" state waiting to be fixed.

This bug is actually annoying enough that it's a strong reason to switch to Ninja instead of make. Plus the fact that Ninja is faster than make. Ninja also uses an appropriate number of parallel jobs based on the number of CPU cores present. Also cool is how Ninja is, by default, very quiet: all progress happens on a single line in the terminal unless the build process emits messages or a build step fails. If a build step fails, Ninja prints the full command line that invoked it and displays the output. It's really nice since it makes any warning or error messages stand out. Although currently there is no colored terminal output: that would be a nice improvement but for me the advantages of Ninja over make are tremendous.

未蓝澄海的烟 2024-11-01 09:41:10

看起来它已经修复了。在命令行中添加 -Oline 参数:

make -j 8 -Oline

make 版本:

GNU Make 4.3
Built for x86_64-pc-msys

Looks like it is already fixed. Add a -Oline parameter to the command line:

make -j 8 -Oline

Version of make:

GNU Make 4.3
Built for x86_64-pc-msys
花开半夏魅人心 2024-11-01 09:41:10

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

Sun's (now Oracle's) dmake available on Linux and Solaris takes care of that.
See here and there.

残花月 2024-11-01 09:41:10

下面是一个使用 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} /"

Here is a simple working example of using a wrapper for Make. I'm not sure if I'd encourage it's use, but it's an idea.

# Makefile
SHELL = /tmp/test/wrapper

test: test1 test2

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

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

and this:

#!/usr/bin/env bash
# wrapper
bash $@ | sed -e "s/^/${TARGET} /"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文