Makefile:需要明确环境变量和make变量的混合使用

Makefile:需要明确环境变量和make变量的混合使用,makefile,Makefile,我基本上是在研究一个有缺陷的makefile,这让我对下面的场景感到困惑 default: echo "Build started with $@ at $(ENV_VAR)";\ ENV_VAR=$(NEW_DIR); \ cd $(ENV_VAR); \ $(MAKE); 程序员的目标: 基本上,程序员打算用一个新值(目录路径)new_DIR覆盖环境变量ENV_VAR,然后在该目录内递归执行make 此生成文件中的错误: 我看到的错误是编码器使用了“

我基本上是在研究一个有缺陷的makefile,这让我对下面的场景感到困惑

default:
     echo "Build started with $@ at $(ENV_VAR)";\
     ENV_VAR=$(NEW_DIR); \
     cd $(ENV_VAR); \
     $(MAKE);
程序员的目标:

基本上,程序员打算用一个新值(目录路径)new_DIR覆盖环境变量ENV_VAR,然后在该目录内递归执行make

此生成文件中的错误:

我看到的错误是编码器使用了“cd$(ENV\u VAR)”而不是“cd$(ENV\u VAR)”。因此,我们实际上没有为“cd”命令使用重写的make变量,而是在执行$(make)之前仍然使用环境变量的值。由于路径不存在,cd命令也失败了。最后我们做了一个递归make

我有一些问题

正如我在上面提到的,我们处于递归生成的场景中。有趣的是,我看到的是,当第二次调用同一个目标时,我看到$(ENV_VAR)来反映NEW_DIR的重写值。这让我感到困惑

样本输出:

假设:

新目录=/新目录旧目录=/旧目录

输出:

Build started with default at /old-dir
bin/sh /old-dir: no such file (or) directory
Build started with default at /new-dir
请对此提出任何建议。

你是对的,
$(ENV_VAR)
是不正确的。但是
$$(ENV_VAR)
也不正确

Make展开命令中的变量,然后将命令传递给shell,shell自行展开。所以

default:
     echo "Build started with $@ at $(ENV_VAR)";\
     ENV_VAR=$(NEW_DIR); \
     cd $(ENV_VAR); \
     $(MAKE);
成为shell命令

echo "Build started with $@ at /old_dir";\
ENV_VAR=/new_dir; \
cd /old_dir; \
make
该命令尚未执行;任务还没有完成,已经太晚了

提议的解决方案也行不通。这:

default:
     echo "Build started with $@ at $(ENV_VAR)";\
     ENV_VAR=$(NEW_DIR); \
     cd $$(ENV_VAR); \
     $(MAKE);
变成这样:

echo "Build started with $@ at /old_dir";\
ENV_VAR=/new_dir; \
cd $(ENV_VAR); \
make
这看起来不错,但请注意
cd$(ENV_VAR)是Make语法,而不是shell语法(至少不是bash)。正确的shell语法是
cd$ENV_VAR
,因此规则应该是:

default:
     echo "Build started with $@ at $(ENV_VAR)";\
     ENV_VAR=$(NEW_DIR); \
     cd $$ENV_VAR; \
     $(MAKE);
根据“默认情况下,只有来自环境或命令行的变量才会传递给递归调用”(但如果您选择,可以重写此行为)。由于
ENV_VAR
是一个环境变量,它将被传递给sub make,如果您在命令shell中修改它,sub make将收到修改后的值

最后,我建议你这样做:

default:
    echo "Build started with $@ at $(ENV_VAR)";
    Make -C $(NEW_DIR) ENV_VAR=$(NEW_DIR);

很好的解释!!谢谢