这次是对makefile模版做出相应修改后,用来编译自己的代码
先看一下我所举例子的目录结构
mydemo
---------- --------------------------------------------------------------------------------
-----------------------------------------------
| | | | | | | |
main_ add_ sub_ mul_ div_ include scripts_ Makefile
------ ------
------ ------ ------ ----- ------- (总控makefile)
| | | | | | | | | | | |
| Makefile |
Makefile | Makefile | Makefile | Makefile ma.h Makefile
src_ src_
src_ src_ src_ (脚本makefile)
| | | | |
main.c add.c sub.c mul.c div.c
带短下划线“_”的是目录,在mydemo目录下有main add sub mul div scripts等子目录以及总控Makefile脚本文件
加 减 乘 除
main.c里面代码如下:
#include "../../include/ma.h"
int main()
{
printf("HELLO !\n");
printf("add = %d\n",add(24,6));
printf("sub = %d\n",sub(24,6));
printf("mul = %d\n",mul(24,6));
printf("div = %d\n",div(24,6));
return 0;
}
ma.h 自己写的头文件,在include目录下
#ifndef MYHEAD_H_
#define MYHEAD_H_
#include <stdio.h>
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
int div(int a, int b);
#endif
add.c里面内容如下
int add(int a, int b)
{
return(a + b);
}
sub.c mul.c div.c 里面内容大致相同
先看脚本目录下Makefile,在scripts目录下,它的作用是
定义一些变量,
#脚本makefile
CC := gcc #总控Makefile中出现CC的地方表示gcc指令
CFLAGS := -Wall -O3 #
CFLAGS表示编译时 开所有警告,三级优化
Libs = -L./include/ma.h #Libs是指定目录下头文件,
Target := demo #目标文件名,通过make想产生的目标 (也就是最终生成的可执行文件)
Source := $(wildcard src/*.c)
#返回src目录下所有.c文件,此时source相当于“XX.c”字符
Objs := $(patsubst %.c,%.o,$(Source)) #把soruc所表示的字符中 .c换成 .o Objs相当于“XX.o“字符
Modules += add sub mul div main #Modules可以表示“add”、“ sub”、“ mul”、"div"、“ main” 等字符
AllObjs := $(addsuffix /src/*.o,$(Modules)) # 经过前面的处理,这里的
AllObjs 就相当于 " **/src/*.o "字符, ** 可能是main add sub mul div
在总控Makefile里面将要用到这些变量
总控Makefile内容如下,它的作用主要有两个:
一是到各个功能目录下执行make指令
二是把各个子目录下的 .o 文件生成可执行文件
#主控makefile
include scripts/Makefile #包含
scripts目录下Makefile文件
modules_make = $(MAKE) -C $(1); #在执行make之前先转到
$(1)表示的文件夹中,$(1)可以看作是形参,在调用modules_make时会给$(1)传递参数
modules_clean = $(MAKE) clean -C $(1);
#在执行make clean 之前先转到
$(1)表示的文件夹中,$(1)可以看作是形参,在调用modules_make时会给$(1)传递参数
.PHONY: all mm mc clean #伪指令
all: $(Target) #目标与依赖,
Target是前面定义过的变量,目标可执行文件demo
mm:
@ $(foreach n,$(Modules),$(call modules_make,$(n))) #该语句的作用是依次将
Modules表示的add、sub、mul、div、main 赋给n ,然后运行表达式(call modules_make,$(n),也就是
#到main ,sub ,mul,div 目录下执行make 指令
mc:
@ $(foreach n,$(Modules),$(call modules_clean,$(n))) #同上
$(Target) : mm
#目标与依赖
$(CC) $(CFLAGS) -o $(Target) $(AllObjs) $(Libs) #相当于 gcc -Wall -O3 -o demo **/src/*.o
-L./include/ma.h
@ echo $(Target) make done! #显示 demo
make done!
clean : mc
#目标与依赖
rm -rf $(Target) #删除demo
@ echo clean done!
#显示 clean
done!
各个子目录下的Makefile 内容如下
include ../scripts/Makefile
all : $(Objs)
clean :
rm -rf $(Objs)
在demo目录下执行make,就能对自动代码进行编译生成可执行文件,而不用到各个子目录下单独执行make指令,
方便而高效。根据自己的工程对模版做出相应更改后,也可以用来管理自己的工程
建议以后自己的工程以这种层次建立,这样有利于对快速makefile做出一点修改后就可以用来管理代码