1概述:
能读懂, 编写makefile应该是每一个Linux程序猿都必须拥有的基本素质,因为makefile是大型的工程中绕不过去的,你能不能写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则:
从上面的例子可以看出 , makefile是一个"自动化编译器",你只需要写好一个makefile, 然后执行一个make命令 , 整个工程就会自动按照规则编译了,极大提高了我们程序猿的效率。
2编写Makefile:
2.1 单文件Makefile:
//Makefile
test: test.o #(test)是目标文件 (:)是依赖的文件或者命令 (test.o) 是test依赖的文件
gcc -o test test.c
.PHONY: clean #(.PHONY)是伪目标标记, 伪目标标记后的命令,不会和目录下文件重复,\
也就是说clean如果没有伪目标标记的话,目录下有一个clean的文件\
make clean将不会正确执行!
clean:
rm -fr *.o test
引用一段百度百科结合我上面的例子,说明一下吧
1 冒号(:)左边的test是目标文件 , 目标文件依赖于冒号(:)右边,
2 冒号右边即可以是文件test.o,也可以是目标,后面多文件多目录编译会讲到实例
3 第二行的gcc很明显是一个命令, 命令必须要以tab开头隔开 , Makefile里的命令可以是任何的shell命令
//test.c
#include
int main(void) {
printf("once_file_makefile ...\n");
return 0;
}
运行结果:
2.2 多目录下Makefile编写
首先我建立一个Makefile的根目录如下图(1):
根目录下的Makefile如下:
CC := gcc
SUBDIR := d1\
d2\
test\
obj#子目录文件夹
OBJS := d1.o d2.o test.o#生成目标文件所需的依赖
OBJS_DIR := obj#所有目标文件依赖的.o文件存放的目录
BIN := myapp#最终的目标文件
BIN_DIR := app#存放目标文件的目录
export CC OBJS OBJS_DIR BIN BIN_DIR#export关键字,导出CC等变量到子目录,让次级目录下的Makefile可以识别
all: CHECK_DIR $(SUBDIR) #分别执行CKECK_DIR和$(SUBDIR)两个依赖,这里的依赖是目标而不是文件
CHECK_DIR:
@mkdir -p $(BIN_DIR) #创建存放目标文件的目录
$(SUBDIR): ECHO
@make -C $@ #在所有的子目录下执行make
ECHO:
@echo start compile ...
.PHONY:clean
clean:
@rm -fr $(OBJ)/*.o $(BIN_DIR)
d1/Makefile
../$(OBJS_DIR)/d1.o:d1.c #OBJS_DIR是从根目录通过export关键字传过来的变量\
也就等同于../obj/d1.o依赖于当前目录下d1.c
$(CC) -c $^ -o $@ #gcc -c 依赖(d1.c) -o 目标(d1.o) $^表示所有依赖, $@表示目标
d2/Makefile
../$(OBJS_DIR)/d2.o: d2.c
$(CC) -c $^ -o $@
test/Makefile
../$(OBJS_DIR)/test.o: test.c
$(CC) -c $^ -o $@
obj/Makefile
../$(BIN_DIR)/$(BIN):$(OBJS)
$(CC) -o $@ $^
include/include.h
// include/include.h
#ifndef __INCLUDE_H__
#define __INCLUDE_H__
#include
#define DEBUG(f, arg...) printf("file:[%s] " " line:[%d] :"f"\n",\
__FILE__, __LINE__, ##arg)
#endif //__INCLUDE_H__
d1/d1.c d2/d2.c test/test.c
// d1/d1.c
#include "../include/include.h"
void d2(void) {
DEBUG("Massage from d2");
}
// d2/d2.c
#include "../include/include.h"
void d1(void) {
DEBUG("Massage from d1");
}
// test/test.c
#include "../include/include.h"
int main(void) {
d1();
d2();
return 0;
}
运行结果: