如何从另一个Makefile调用Makefile?


125

我收到一些意外的结果,从另一个调用一个生成文件。我有两个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都是在告诉我它正在进入当前工作目录。在第一种情况下,它认为它没有工作(在执行时),在第二种情况下,它能够找到适当的指令(当输出告诉我它在错误的目录中查找时),但是它尝试rm/path/to/project而不是中运行命令/path/to/makefile/gtest-1.4.0/make/

我是否缺少一些互相调用makefile的基础知识?我是否犯了严重的概念错误,还是遇到了常见的陷阱?如何有效地更改目录并从第一个生成文件中调用第二个生成文件?我的理解是,只需打电话make -f <name>就足够了。

这是bash中的make / gmake 3.81。


3
我认为,与其说make -f gtest-1.4.0/make/Makefile clean您更好,不如说$(MAKE) -C gtest-1.4.0/make clean。为什么没有定义虚假目标?
dma_k 2010年

Answers:


112

我不太清楚您要问的是什么,但是使用-f命令行选项仅指定一个文件-它不会告诉make更改目录。如果要在另一个目录中进行工作,则需要cd转到该目录:

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

请注意,其中的每一行都在Makefile单独的外壳程序中运行,因此无需将目录改回。


67
您应该使用的选项,而不是手动cd转到gtest-1.4.0目录。-Cmake
塔德

29
或者至少,您绝对应该&&在cd和make命令之间使用。否则,如果cd失败,它将仍然make clean在错误的目录中运行!同样$(MAKE),在递归make时,您应始终仅使用(而不是裸词)。就像这样: cd gtest-1.4.0 && $(MAKE) clean
MadScientist 2012年

3
@Tader:-C不在规格中
Janus Troelsen

1
这个关于gnu-make的问题-C在规范中:gnu.org/software/make/manual/make.html#Recursion
Cas

122

取而代之的是-fmake,你可能要使用的-C <path>选项。首先,将更改为路径“ <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

1
这种方式似乎是最好的。使用的其他答复cd会导致终端进入无限循环。
gbmhunter 2013年

$(MAKE)-C gtest-1.4.0 / make clean对我不起作用。我认为应该是$(MAKE)-C gtest-1.4.0 clean
Arigion


1

似乎很清楚,$(TESTS)因此您的1.4.0 makefile有效

all: 

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

确实,所有事情都无关。和清洁完全按照它所说的rm -f gtest.a ...


$(TESTS)由a wildcard和a 定义patsubst,但是由于未有效更改目录,它们从主makefile返回空值。好眼睛
克里斯·汤金森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.