如何制作“-j”?选项实际上有效吗?
从手册页:
-j [工作], --工作[=工作] 指定同时运行的作业(命令)数量。 如果有多个 -j 选项, 最后一个有效。如果-j 选项是 如果不带参数给出,make 不会限制作业数量 可以同时运行。
我知道它使用图依赖关系来了解哪些规则是独立的。
我想知道这个图表是如何构建的并了解使用的标准是什么。
谢谢。
From the man pages:
-j [jobs], --jobs[=jobs]
Specifies the number of jobs (commands) to run simultaneously.
If there is more than one -j option,
the last one is effective. If the -j
option is
given without an argument, make will not limit the number of jobs
that can run simultaneously.
I know it uses a graph dependency to know which rules are independent.
I would like to know how this graph is built and understand what are the criteria used.
thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如人们所期望的那样,依赖关系图基于为每个 Makefile 目标列出的先决条件。
make
将构建一个图,其中目标和先决条件是顶点,并且从先决条件到其目标有一条有向边。通过这种方式,传入边的数量可以告诉您目标有多少个先决条件。如果它没有传入边,则它没有先决条件。例如,
.c
和.h
文件的顶点将没有传入边。这些文件是您的源文件,不需要构建。然后,它对图执行拓扑排序以确定执行顺序。来自维基百科:
拓扑排序的要点是找到没有传入边(无依赖性)的顶点并将其放在前面。然后将它们从图中删除。现在您将拥有一组新的顶点,没有传入边(没有依赖关系)。接下来是这些。依此类推,直至完成。 (如果到达没有这样的顶点的点,则依赖关系图包含一个循环,这是一个错误条件。)
在典型的 Makefile 中,这意味着您将首先构建源文件(不需要执行任何操作)。然后是依赖于这些源文件的目标文件。然后从这些目标文件构建库和可执行文件。
在正常的非并行操作下,
make
每次迭代都会简单地选择一个目标并构建它。当它是并行的时,它将获取尽可能多的无依赖目标并并行构建它们,最多可达允许的同时作业的数量。因此,当 make 到达目标文件步骤时,图中将有大量没有传入边的顶点。它知道它可以并行构建目标文件,因此它会分叉
gcc
的 n 个副本来构建目标文件。The dependency graph is based, as one would expect, on the prerequisites listed for each Makefile target.
make
will build a graph where the targets and prerequisites are vertices and there is a directed edge from the prereqs to their targets. In this way the number of incoming edges tells you how many prereqs a target has. If it has no incoming edges, then it has no prerequisites.The vertices for the
.c
and.h
files, for example, will have no incoming edges. Those files are your source files and do not need to be built.It then performs a topological sort on the graph to determine the order of execution. From Wikipedia:
The gist of a topological sort is to find the vertices with no incoming edges (no dependencies) and put those first. Then remove them from the graph. Now you'll have a new set of vertices with no incoming edges (no dependencies). Those are next. And so on until finished. (If you ever reach a point when there are no such vertices then the dependency graph contains a cycle, which is an error condition.)
In a typical Makefile this means you'll first build the source files (nothing needs to be done). Then the object files that depend on those source files. Then the libraries and executables built from those object files.
Under normal non-parallel operation
make
will simply pick a single target each iteration and build it. When it is parallel it will grab as many dependency-less targets as it can and build them in parallel, up to the number of permitted simultaneous jobs.So when
make
gets to, say, the object file step, it will have a large number of vertices in the graph that all have no incoming edges. It knows it can build the object files in parallel and so it forks off n copies ofgcc
to build the object files.我怀疑你期待的东西比这里实际存在的更神奇。 Makefile 包含如下行:
这定义了系统中文件之间的关系;用图的说法,行上的每个空格分隔的单词隐式声明图中的一个节点,并且在冒号左侧的每个节点和冒号右侧的每个节点之间创建有向边,从后者指向前者。
从那里开始,遍历图表以查找没有传入边的节点并执行与这些节点关联的命令,然后从那里“向上”恢复图表就很简单了。
希望有帮助。
I suspect you're expecting something more magical than there actually is here. Makefiles contain lines like:
This defines a relationship between files in the system; in graph parlance, each white-space-separated word on the line implicitly declares a node in the graph, and a directed edge is created between each of the nodes to the left of the colon and each of the nodes to the right of the colon, pointing from the latter to the former.
From there it's a simple matter of traversing the graph to find nodes that have no incoming edges and executing the commands associated with those nodes, then working back 'up' the graph from there.
Hope that helps.