如何在Makefile中打印所有当前正在运行的目标?
Makefile并行执行时打印当前运行目标的可行思路
思路1:修改目标规则统一注入打印逻辑
- 给所有自定义目标加前置钩子,利用Make的
SHELL变量或者模式规则注入打印逻辑 - 可以在Makefile开头加如下规则,每次目标启动、结束时都会向指定临时文件写入状态:
# 定义状态存储文件,每次执行make时生成独立的临时文件 MAKE_RUNNING_LOG := $(shell mktemp /tmp/make_running.XXXXXX) # 进程退出时自动清理日志文件 .DELETE_ON_ERROR: $(MAKE_RUNNING_LOG) .INTERMEDIATE: $(MAKE_RUNNING_LOG) # 重写SHELL变量,每个目标的命令执行前先记录当前目标名 OLD_SHELL := $(SHELL) SHELL = @echo "START $@" >> $(MAKE_RUNNING_LOG); $(OLD_SHELL) -c 'trap "echo END $@ >> $(MAKE_RUNNING_LOG)" EXIT; $$0' "$$@"
- 需要查看当前运行的目标时,直接执行
awk '/START/{a[$2]=1}/END/{delete a[$2]}END{for(k in a)print k}' $(MAKE_RUNNING_LOG)即可过滤出还没写END记录的活跃目标
思路2:利用Make的调试选项过滤日志
- 运行make时加上
-d调试参数,将日志重定向到文件,并行执行时的目标启动信息会固定打印Must remake target 'xxx'的日志 - 执行命令时的写法:
make -j100 -d 2>&1 | tee make_debug.log - 查看当前运行目标时过滤日志即可,结合进程状态过滤已经执行完成的目标即可得到正在运行的目标列表
思路3:通过进程名反向匹配目标
- Make执行每个目标的命令时,默认会把目标相关信息作为shell进程的参数之一,可通过ps命令过滤关联的进程信息
- 直接执行
ps fH | grep -A2 make可以看到当前所有关联的make子进程树,再结合正在执行的命令内容就能匹配到对应的正在执行的目标
注意事项
- 并行执行时写入日志要注意原子性,避免多进程同时写文件出现内容错乱,上文的单行追加写操作在大多数POSIX系统下是原子操作,不会出现内容乱序
- 如果你的Makefile中已经自定义了
SHELL变量,需要调整思路1的注入逻辑,避免和原有逻辑冲突
内容的提问来源于stack exchange,提问作者lmy860
相关产品推荐
相关产品推荐

