1、文件结构
├── include
│ └── test.h
├── main
│ ├── main.c
│ └── Makefile
├── Makefile
├── obj
│ └── Makefile
├── src
│ ├── eat
│ │ ├── eat.c
│ │ ├── eat.h
│ │ └── Makefile
│ ├── Makefile
│ └── test.c
└── test.h
2、源码文件
test.h文件
#include<stdio.h>
#include<stdlib.h>
int testPrint();//将test.c文件中函数的实现与声明分开
int mainPrint();//将main.c文件中函数的实现与声明分开
int callEatPrint();//调用eat.c文件中的eatprint()
main.c
#include"../include/test.h"
int mainPrint()
{
printf("In main.c implementation mainPrint\n");
}
int main()
{
printf("In main.c file\n");
mainPrint();
testPrintf();
callEatPrint();
return 0;
}
test.c
#include"../include/test.h"
#include"./eat/eat.h"
int testPrint()
{
printf("In test.c implementation testPrint\n");
return 0;
}
int callEatPrint()
{
printf("In test.c implemetation callEatPrint\n");
eatPrint();
return 0;
}
eat.h
#include"../include/test.h"
int eatPrint();
eat.c
#include"eat.h"
int eatPrint()
{
printf("In eat.c implementation eatPrint\n");
return 0;
}
3、各makefile文件的实现
3.1、顶层makefile
CC = gcc #设置编译器
OBJ := main.o test.o eat.o#设置所有会生成的目标文件,为最后一步连接可执行文件
TOP_DIR := $(PWD)#获取当前文件的目录,将其存入变量中
OBJ_DIR := $(TOP_DIR)/obj#设置目标文件存放的目录
BIN_DIR:=$(TOP_DIR)/bin#设置可执行文件存放的目录
BIN:=test#设置可执行文件名字
SUB_DIR:=main \
src \
src/eat \
obj#保存所有子目录下的Makefile的路径。只要子目录有makefile存在,就在这个地方添加相对顶层Makefile的路径
export CC SRC INCLUDE OBJ TOP_DIR OBJ_DIR BIN_DIR BIN#将1~6行的变量设置成全局变量,在子目录的makefile里面可以直接使用这些变量
all:CHECKDIR $(SUB_DIR)#让多个目标操作顺次执行
CHECKDIR:
mkdir -p $(SUB_DIR) $(BIN_DIR)#创建一大堆目录,目录存在就不创建了
$(SUB_DIR):ECHO
make -C $@#遍历make所有目录下面的makefile
ECHO:
@echo $(SUB_DIR)
@echo begin compile
clean:
rm -rf $(OBJ_DIR)/*.o $(BIN_DIR)#执行make clean 就会执行clean部分
执行逻辑:
首先查找依赖部分“ECHO”,就是一些打印信息,echo前面的‘@’符号不加也是可以的。
接着就是执行:make -C $(SUB_DIR) (-C是大写的C,小写的c编译出目标文件)
-C 参数的含义: -C DIRECTORY, --directory=DIRECTORY Change to DIRECTORY before doing anything.
翻译过来就是:在离开这个目录前做点什么。
加上-C 选项意思就是:在$(SUB_DIR) 目录下面执行make
make -C $(SUB_DIR) 展开就是:make -C main/ src/ src/eat/ obj/ :按顺序对各个目录下面的makefile,make一下。
3.2、src目录下makefile
$(OBJ_DIR)/test.o:test.c
$(CC) -c $^ -o $@
3.3、main目录下makefile
$(OBJ_DIR)/main.o:main.c
$(CC) -c $^ -o $@
3.4、obj目录下makefile
$(BIN_DIR)/$(BIN):$(OBJ)
$(CC) $^ -o $@
3.5、eat目录下makefile
$(OBJ_DIR)/eat.o:eat.c
$(CC) -c $^ -o $@
4、编译后目录结构
.
├── bin
│ └── test
├── include
│ └── test.h
├── main
│ ├── main.c
│ └── Makefile
├── Makefile
├── obj
│ ├── eat.o
│ ├── main.o
│ ├── Makefile
│ └── test.o
└── src
├── eat
│ ├── eat.c
│ ├── eat.h
│ └── Makefile
├── Makefile
├── test.c
└── test.o
5、编译结果
In main.c file
In main.c implementation mainPrint
In test.c implementation testPrint
In test.c implemetation callEatPrint
In eat.c implementation eatPrint
参考:https://blog.csdn.net/sinat_29830917/article/details/55506309