我一直在寻找一个小时,这些信息似乎无处可寻......
我希望能够提取(并且可能使用)通过-j选项传递的请求make“jobs”的数量,或者在Makefile中通过Make子本身来实现。
到目前为止我见过的最有希望的是$(MAKEFLAGS)变量,但在我的系统上(如果我这样做,比如make -j2),这个变量的内容只是“--jobserver-fds = 3,4 -j“。有没有办法用-j传递实际的作业数?
答案 0 :(得分:13)
我很抱歉,但无法识别并行作业的数量 - 无需编写扫描进程列表的应用程序或脚本来识别调用参数。
检查http://cvs.savannah.gnu.org/viewvc/make/main.c?revision=1.246&root=make&view=markup处的源代码。搜索job_slots > 1
。
更新:如果您可以控制操作范围,可以使用自己的程序/脚本包装make
应用程序,解析参数,设置专用环境变量并在之后调用原始make。
答案 1 :(得分:11)
实际上有一种方法可以在* nix上的makefile中完全实现。
MAKE_PID := $(shell echo $$PPID)
JOB_FLAG := $(filter -j%, $(subst -j ,-j,$(shell ps T | grep "^\s*$(MAKE_PID).*$(MAKE)")))
JOBS := $(subst -j,,$(JOB_FLAG))
ps,grep也需要安装,但它几乎是给定的。它可以进一步改进以处理 - 工作也
答案 2 :(得分:1)
哟,
我想出了一种不同的方法,我更喜欢按照已接受的答案中的建议解析命令行。我遇到的主要问题是它不能在递归调用的 makefile 中工作,因为作业参数是通过那里的 env 传递的,然后它代表作业服务器,它不告诉你它将提供多少作业令牌
所以我决定真正接受 jobserver 的事情,并制作一个小的 python 代码,它消耗来自 jobserver 的所有令牌,对它们进行计数,然后将它们放回去。
这是一个巧妙的想法,似乎非常容易实现,而且对我来说似乎非常有效。
关于如何使用它有多个注意事项:
+
前缀调用脚本,因为这样可以启用“submake”功能,该功能复制子进程的作业服务器描述符,以便能够“生成工作人员”python 脚本:
import argparse, os
def safe_int(s):
try:
return int(s)
except:
return -1
class JobserverArgs:
known_names = ["jobserver-fds","jobserver-auth"]
def __init__(self):
self.fds = "-1,-1"
@staticmethod
def from_argv():
ja = JobserverArgs()
parser = argparse.ArgumentParser()
for name in JobserverArgs.known_names:
parser.add_argument('--'+name, dest="fds")
parser.parse_known_args(namespace=ja)
return ja
def get_fds(self):
return tuple([safe_int(fd) for fd in (self.fds+",").split(",")][:2])
fd_in, fd_out = JobserverArgs.from_argv().get_fds()
if fd_in == -1 or fd_out == -1:
print(1)
else:
os.set_blocking(fd_in, False)
tokens = os.read(fd_in, 1024)
os.write(fd_out, tokens)
print(len(tokens)+1)
示例生成文件:
TARGETS := a b c d e
.PHONY: $(TARGETS)
$(TARGETS):
@for i in 1 2; do echo "$@$$i"; sleep 1; done
.PHONY: all
all: $(TARGETS)
@echo done all
$(TARGETS): | common
.PHONY: common
common:
+$(eval JOBS:=$$(shell python jobs.py $(MAKEFLAGS)))
@echo JOBS=$(JOBS)
运行:
projects/make-fun » make all -j100
JOBS=100
a1
b1
c1
d1
e1
a2
b2
c2
d2
e2
done all