Makefile的二次展开

make 在执行的时候是分成两个阶段的, 第一阶段叫读入阶段, 第二阶段是更新目标阶段

在第一阶段, make读入include等文件, 并对变量进行替换, 展开隐式规则等, 这一阶段就是生成合适makefile的过程

在第二阶段是执行阶段, 根据第一阶段生成的makefile, 根据规则对需要更新的目标进行更新


但如果在规则下面的命令中, 用到了循环, 则会涉及到二次展开的问题, 所谓二次展开就是在第二阶段再展开一次
比如下面的例子:
dirs= dira, dirb, dirc
 all:
      for d in $(dirs);                        \
      do                                             \
             echo "current dir: $d";      \
       done;      

由于在规则下面的命令只能是一条一条的, 所以for循环要用 “\” 跟“;”连起来构成一条命令

上面最后的结果是输出三句话
current dir:
current dir:
current dir:
这跟我们想要的不符,我们来看看原因, 先看第一阶段的展开
 dirs= dira, dirb, dirc
 all:
      for d in dira dirb dirc;                        \
      do                                             \
             echo "current dir: $d";      \, d实际上是没有定义的,它被展开成空字符串
       done;     
由于在第一阶段的展开中, d实际上是没有定义的,它被展开成空。 这里要注意的是第一阶段它只是读跟展开,并没有执行, 所以d不会被定义成for循环中对应的现
按照上面的的展开,我们就知道为什么会有那样的输出

为了看的更清楚一点,对makefile稍微改造一下
 dirs= dira, dirb, dirc
 d=/home
 all:
      for d in $(dirs);                        \
      do                                             \
             echo "current dir: $d";      \
       done;     
我们会得到输出:
current dir: /home
current dir: /home
current dir: /home

这是因为它在第一阶段展开成如下的内容
 dirs= dira, dirb, dirc
 d=/home
 all:
      for d in dira dirb dirc;                        \
      do                                             \
             echo "current dir: /home";      \d被展开成了/home
       done;     

那么我们如何才能得到预期的目标呢? 这就要用到二次展开的概念,让它在第二阶段再展开一次
dirs= dira, dirb, dirc
 all:
      for d in $(dirs);                        \
      do                                             \
             echo "current dir: $$d";      \
       done;     
 在第一阶段后展开成
 dirs= dira, dirb, dirc
 all:
      for d in dira dirb dirc;                        \
      do                                             \
             echo "current dir: $d";      \
       done;     

这样在第二阶段执行的时候, $d就会展开成for中对应的列表了, 即dira, dirb跟dirc
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值