嵌套makefile范例

嵌套makefile小型范例

嵌套makefile范例_第1张图片

这张图片左图和右图分别是make前后的文件夹目录变化,make之后生成了3个.o文件位于obj目录下,还生成了一个bin目录,其下生成了可执行文件test。下面是几个.cpp文件和.h文件的代码,很简单的代码,主要是为了演示嵌套makefile。

//test.h文件
#pragma once
void print();
//test.cpp
#include "../include/test.h"
#include 
void print()
{std::cout << "print()..." << std::endl;}
//eat.h
#pragma once
void eat();
//eat.cpp
#include "eat.h"
#include 
void eat()
{std::cout << "eat()..." << std::endl;}
//main.cpp
#include "../include/test.h"
#include "../src/eat/eat.h"
int main()
{
	eat();
	print();
	return 0;
}

下面是最顶层的Makefile文件内容

  1 OBJ := main.o test.o eat.o
  2 TOP_DIR := $(PWD)
  3 OBJ_DIR := $(TOP_DIR)/obj
  4 BIN_DIR := $(TOP_DIR)/bin
  5 BIN:= test
  6 SUB_DIR := main \
  7             src \
  8             src/eat \
  9             obj
 10 export OBJ TOP_DIR OBJ_DIR BIN_DIR BIN
 11
 12 all: CHECKDIR $(SUB_DIR)
 13
 14 CHECKDIR:
 15     mkdir -p $(SUB_DIR) $(BIN_DIR)
 16 $(SUB_DIR):ECHO
 17     make -C $@   #执行SUB_DIR的makefile
 18 ECHO:
 19     @echo $(SUB_DIR)
 20     @echo begin compile
 21
 22 clean:
 23     rm -rf $(OBJ_DIR)/*.o $(BIN_DIR)
 24
 25 .PHONY = all CHECKDIR ECHO clean

分行进行解析:(数字代表行数)
1.设置所有生成的.o文件
2.获取当前工作目录,PWD是makefile自带变量,PWD=$(shell pwd)
3.存放将要生成的.o文件目录
4.可执行文件目录
5.目标文件(在这里就是可执行文件test)名称
6.所有工程需要子目录名称
10.export设置全局变量,代表这些变量在下层的makefile中都可以直接使用,且值不变
25. .PHONY设置all CHECKDIR ECHO clean四个伪目标,伪目标的意思就是不会生成该文件,也可以没有依赖,在这里.PHONY其实也可以不设置,make能自行判断伪目标
12.第一个伪目标,依赖于CHECKDIR和(SUB_DIR)
14-17.生成对应的文件夹并向下执行Makefile
18-20.仅仅是打印一些信息
22、23.删除make生成的所有.o文件和可执行文件

Note:上述语句中需要注意的就是12-17几行,由于makefile中的目标与依赖文件关系,有点类似于栈的性质,拿这里举例,make发现all依赖于CHECKDIR和(SUBDIR),但是这两依赖文件都还没有,继续往下找,先找CHECKDIR怎么生成,发现了14行有目标CHENKDIR,没有依赖就执行15行的命令(如果CHECKDIR还有依赖,继续往下找);all目标的第一个依赖被解决了,继续找第二个依赖(SUB_DIR),发现其还有依赖ECHO,ECHO在18行作为目标没有依赖,所以总是先执行ECHO的打印信息,然后再执行下层的makefile,如下图所示(第一行是创建目录,第二行和第三行就是ECHO打印的信息)
嵌套makefile范例_第2张图片
再来简单的看下其他的下层Makefile

#main目录下的makefile
$(OBJ_DIR)/main.o:main.cpp
	$(CXX) -c $^ -o $@
#src目录下的makefile
$(OBJ_DIR)/test.o: test.cpp
	$(CXX) -c $^ -o $@
#src/eat目录下的makefile
$(OBJ_DIR)/eat.o: eat.cpp
	$(CXX) -c $^ -o $@
#obj目录下的makefile
$(BIN_DIR)/$(BIN):$(OBJ)
	$(CXX) $^ -o $@

你可能感兴趣的:(c++,makefile)