如何从另一个 Makefile 调用 Makefile?

Posted

技术标签:

【中文标题】如何从另一个 Makefile 调用 Makefile?【英文标题】:How to call Makefile from another Makefile? 【发布时间】:2011-01-13 10:47:41 【问题描述】:

我从另一个 makefile 调用一个 makefile 得到了一些意想不到的结果。我有两个makefile,一个叫/path/to/project/makefile,一个叫/path/to/project/gtest-1.4.0/make/Makefile。我试图让前者调用后者。在 /path/to/project/makefile 中,我有

dev: $(OBJ_FILES)
  $(CPPC) $(LIBS) $(FLAGS_DEV) $(OBJ_FILES) -o $(BIN_DIR)/$(PROJECT)
  $(MAKE) -f ./gtest-1.4.0/make/Makefile

clean:
  rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o
  rm -f ../svn-commit.tmp~
  rm -f $(BIN_DIR)/$(PROJECT)
  make -f gtest-1.4.0/make/Makefile clean

/path/to/project/gtest-1.4.0/make/Makefile 我有

all: $(TESTS)

clean:
  rm -f $(TESTS) gtest.a gtest_main.a *.o

发布以下内容:

cd /path/to/project
make

输出:

make -f ./gtest-1.4.0/make/Makefile
make[1]: Entering directory `/path/to/project'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `/path/to/project'

但是,当我发出这些命令时:

cd /path/to/project
make clean

我明白了:

make -f gtest-1.4.0/make/Makefile clean
make[1]: Entering directory `/path/to/project'
rm -f  gtest.a gtest_main.a *.o
make[1]: Leaving directory `/path/to/project'

我不明白:在这两种情况下,/path/to/project/makefile 都告诉我它正在进入当前工作目录。在第一种情况下,它认为它没有工作要做(当它有工作时),在第二种情况下,它能够找到适当的指令(当输出告诉我它在错误的目录中查找时)但它会尝试在/path/to/project 中运行rm 命令,而不是/path/to/makefile/gtest-1.4.0/make/

我是否错过了相互调用 makefile 的基本内容?我是否犯了一个严重的概念错误,或者遇到了一个常见的陷阱?如何有效地更改目录并从第一个 makefile 中调用第二个?我的理解是,只需调用make -f <name> 就足够了。

这是 bash 中的 make/gmake 3.81。

【问题讨论】:

我认为,与其说make -f gtest-1.4.0/make/Makefile clean,不如说$(MAKE) -C gtest-1.4.0/make clean。为什么你没有定义虚假目标? ***.com/questions/3494999/… 【参考方案1】:

我不太清楚你在问什么,但使用-f 命令行选项只是指定一个文件 - 它不会告诉 make 更改目录。如果你想在另一个目录下工作,你需要cd到这个目录:

clean:
    cd gtest-1.4.0 && $(MAKE) clean

请注意,Makefile 中的每一行都在单独的 shell 中运行,因此无需将目录改回来。

【讨论】:

您应该使用make-C 选项,而不是手动cd'ing 到gtest-1.4.0 目录。 或者至少,你绝对应该在 cd 和 make 命令之间使用&&。否则如果 cd 失败,它仍然会在错误的目录中运行make clean...!!此外,在递归时,您应该始终只使用$(MAKE),而不是裸词make。比如:cd gtest-1.4.0 && $(MAKE) clean @Tader: -C 不在the spec中 这个关于 gnu-make 和 -C 的问题在规范中:gnu.org/software/make/manual/make.html#Recursion【参考方案2】:

您可能希望使用-C <path> 选项,而不是make-f。这首先将路径更改为'<path>',然后在那里调用make

例子:

clean:
  rm -f ./*~ ./gmon.out ./core $(SRC_DIR)/*~ $(OBJ_DIR)/*.o
  rm -f ../svn-commit.tmp~
  rm -f $(BIN_DIR)/$(PROJECT)
  $(MAKE) -C gtest-1.4.0/make clean

【讨论】:

这种方式似乎是最好的。使用cd 的其他回复会导致终端进入无限循环。 $(MAKE) -C gtest-1.4.0/make clean 对我不起作用。我认为应该是 $(MAKE) -C gtest-1.4.0 clean【参考方案3】:

http://www.gnu.org/software/make/manual/make.html#Recursion

 subsystem:
         cd subdir && $(MAKE)

或者,等效地,这个:

 subsystem:
         $(MAKE) -C subdir

【讨论】:

感谢官方文档的参考。【参考方案4】:

很明显$(TESTS) 是空的,所以你的 1.4.0 makefile 是有效的

all: 

clean:
  rm -f  gtest.a gtest_main.a *.o

的确,一切都无关紧要。并且 clean 完全按照rm -f gtest.a ... 所说的那样做

【讨论】:

$(TESTS) 是用 wildcardpatsubst 定义的,但是它们从主 makefile 返回空,因为目录没有被有效地更改。好眼力。

以上是关于如何从另一个 Makefile 调用 Makefile?的主要内容,如果未能解决你的问题,请参考以下文章

如何创建用于从子目录中的其他 Makefile 编译多个驱动程序的 Makeflow

从另一个makefile在Makefile中追加/替换字符串

通过 makefile 链接文件

Makefile文件的基本单元 —— 规则

重建后的Makefile重新编译代码需要很多时间

源码编译安装MySQL8.0.20