自动化构建 - make&Makefile - recipe 执行原理

背景

  • 在Makefile recipe中执行另外一个目录下的Makefile,图简单使用了cd命令,但是测试发现cd命令未生效,示例代码如下:
test:
    cd workspace
    make
    cd -
  • 常规做法是使用-C选项,如下,
test:
    make -C workspace
  • 以上代码首先会切换到workspace目录,再执行此目录下的Makefile,且会有以下打印,workspace下的Makefile执行完后,会切换回原来的目录和Makefile。
make[1]: Enter directory 'xxxxx'
.....
make[1]: Leaving directory 'xxxxx'

cd 命令不生效原因

  • 从网上可找到答案:cd只有在当前行有效,所以代码需要更改为:
test:
    cd workspace && make && cd -
  • 使用strace工具分析下面Makefile的执行调用
命令:
strace make

Makefile:
all:
	cd test
	mkdir test

strace 结果:
...
read(3, "\n\nall:\n\tcd test\n\tmkdir test\n", 4096) = 28
read(3, "", 4096)                       = 0
close(3)                                = 0
stat("RCS", 0x7ffd29716440)             = -1 ENOENT (No such file or directory)
stat("SCCS", 0x7ffd29716440)            = -1 ENOENT (No such file or directory)
stat("Makefile", {st_mode=S_IFREG|0664, st_size=28, ...}) = 0
stat("all", 0x7ffd29714240)             = -1 ENOENT (No such file or directory)
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 37), ...}) = 0
write(1, "cd test\n", 8cd test
)                = 8
pipe([3, 4])                            = 0
close(4)                                = 0
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
rt_sigprocmask(SIG_BLOCK, [HUP INT QUIT TERM XCPU XFSZ], NULL, 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1c96ff5a10) = 5471
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 5471
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=5471, si_uid=994, si_status=0, si_utime=0, si_stime=0} ---
rt_sigreturn({mask=[]})                 = 5471
write(1, "mkdir test\n", 11mkdir test
)            = 11
rt_sigprocmask(SIG_BLOCK, [HUP INT QUIT TERM XCPU XFSZ], NULL, 8) = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f1c96ff5a10) = 5472
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
wait4(-1, mkdir: cannot create directory ‘test’: File exists
[{WIFEXITED(s) && WEXITSTATUS(s) == 1}], 0, NULL) = 5472
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=5472, si_uid=994, si_status=1, si_utime=0, si_stime=0} ---
...
  • 从strace结果可知:
  1. 执行make命令时,make程序读取Makefile文件。
  2. 将读取到的数据按字符串形式通过TAB符号拆分处理,每次执行一行命令
  3. 执行每一行命令都是通过clone一个子进程并等待其处理完,该操作非常类似于通过system函数执行命令,因此每一次执行只会影响当前进程,不会影响父进程。

总结

  • 写Makefile时需要注意每一行的独立性。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值