看到关于Makefile的必要性评论,遽然想起自己干过一些风趣的的工作。
一个目录下有一大堆同质或不同质的程序,要测验体系处理并发使命的功率不得不写一个使命分发器(work load manager),用C写对新手来说仍是有点大条的,使用make -j能够模仿一个简略的wlm。代码大约如下:
binaries := $(foreach ccode, \
$(shell for cfile in `ls *.c`; do echo $cfile; done),\
$(ccode:.c=))
$(binaries): %:%.c
@echo BLD $@
@gcc -o $@ $《 》/dev/null 2》&1
to_run := $(foreach ccode, \
$(shell for cfile in `ls *.c`; do echo $cfile; done),\
to_run_$(ccode:.c=))
run: clean $(to_run)
to_run_%: %
@to_run=$@; \
echo ${to_run##to_run_};
clean:
@echo -n “——————————– CLEAN ”
@echo “——————————–”
@echo RMV $(binaries)
@rm -f $(binaries)
.PHONY: run clean
运转 make -jN 即可
简而言之便是:
1. default 的 target 是 run,run 依赖于 clean 和 to_run
run: clean $(to_run)
2. to_run 是由一段 shell 发生的
to_run := $(foreach ccode, \
$(shell for cfile in `ls *.c`; do echo $cfile; done),\
to_run_$(ccode:.c=))
3. 假定目录下有 1.c 2.c 3.c 4.c 。。. 100.c 这100个c程序, 那段 shell 生成的变量 to_run 等于这样的一串: to_run_1 to_run2 。。. to_run_100
4. to_run_%: % 那一段 rule 的意思是关于某个方针 to_run_73 依赖于 73,当 73 不存在或许 73.c 被更新过, make 就按照上面声明的 binaries 的规矩去(从头)生成它:
$(binaries): %:%.c
@echo BLD $@
@gcc -o $@ $《 》/dev/null 2》&1
5. 73 生成今后就运转它,示例里用的是 echo
@to_run=$@; \
echo ${to_run##to_run_};
实际上能够是
@to_run=$@; \
。/${to_run##to_run_};
这样 73 就在恰当的时分被运转了。
假定输入 make -j32 run,成果便是可执行文件 1, 2, 3 。。. 32 一起被运转,其间的某个完毕后 make 会主动发动后边的 33, 34 。。. 直至一切的运转完毕,这就模仿了一个简略的本地 work load manager。
这个make脚本的别的一个变种能够是:你有一个程序(假定叫 EXEC0),在一台16核的机器上你期望并行地运转32个带不同参数的 EXEC0 实例,一共运转 1024 个实例来测验体系或许 EXEC0 的运转功率,Makefile大约能够这样写:
ifeq ($(MAX),)
MAX=1024
endif
parameter0=0
parameter1=11
parameter2=22
parameter3=33
prerequisites := $(foreach num, \
$(shell i=0; while [ $$i -lt $(MAX) ]; \
do \
echo $$i; \
i=$$((i + 1)); \
done), \
target_$(num))
run:$(prerequisites)
EXEC0: EXEC0.c
gcc -o $@ $《
target_%:EXEC0
@./EXEC0 $(parameter$(shell expr $(subst target_,,$@) % 4))
.PHONY: run
一个无聊的EXEC0.c 能够是:
int
main(int argc, char **argv)
{
sleep(atoi(argv[1]));
printf(“%s %d\n”, argv[0], atoi(argv[1]));
return 0;
}
然后make -j32 MAX=1024
/////////////////////////////////////////////////////////////////////////////////////////////////////////
实验记载:
testcase := $(shell for test in `ls 。。/tests/`; do echo $$test; done)
to_run := $(foreach test, \
$(shell for test in `ls 。。/tests/`; do echo $$test; done), \
to_run_$(test))
run : $(to_run)
to_run_%:
@to_run=$@; \
run_test $${to_run##to_run_};
#$(shell grep -rn “Error” 。/$${to_run##to_run_}/irun.log 》》 error.log)
clean:
@echo -n “————————– CLEAN”
@echo “————————–”
@echo RMV $(testcase)
@rm -rf $(testcase)
.PHONY: run clean