Makefile-例程讲解
来源:互联网 发布:什么软件是写小说的 编辑:程序博客网 时间:2024/06/05 16:10
我们已经在Makefile语法和Makefile常用函数这两篇文章中讲解了makefile编写的一些基本语法和规则,下面就让我们实战一下吧。
今天我们主要讲一下makefile文件递归式写法。
我们先看一下我们将要用到的源码:
1.主文件test/main.c:
//path: ..src/main.c#include <stdio.h>#include "add.h"#include "sub.h"int main(){ int a=10,b=12; float x=1.23456,y=9.87654; printf("int a+b IS:%d\n",add_int(a,b)); printf("int a-b IS:%d\n",sub_int(a,b)); printf("float x+y IS:%f\n",add_float(x,y)); printf("float x-y IS:%f\n",sub_float(x,y)); return 0;}
2.减法的头文件
//path: ../inc/sub/sub.h#ifndef _SUB_H_#define _SUB_H_extern float sub_float(float a, float b);extern int sub_int(int a, int b);#endif
3.浮点数减法的实现
//path: ../src/sub/sub_float.cfloat sub_float(float a, float b){ return a-b;}
4.实现int型的减法函数定义文件:
//path: ../src/sub/sub_int.cint sub_int(int a, int b){ return a-b;}
5.加法声明的头文件:
//path: ../inc/add/add.h#ifndef _ADD_H_#define _ADD_H_extern int add_int(int a, int b);extern float add_float(float a, float b);#endif
6.浮点数加法的实现
//path: ../src/add/add_float.cfloat add_float(float a, float b){ return a+b;}
7.整数加法的实现
//path: ../src/add/add_int.cint add_int(int a, int b){ return a+b;}
我们的目录结构如下:
.├── inc│ ├── add│ │ └── add.h│ └── sub│ └── sub.h├── Makefile└── src ├── add │ ├── add_float.c │ ├── add_int.c │ └── Makefile ├── main.c ├── Makefile └── sub ├── Makefile ├── sub_float.c └── sub_int.c
我们可以看到顶层目录有两个文件夹inc和src,分别用来包含头文件和源文件;还有一个顶层Makefile。inc目录就不细说了。src子目录下有2个深层子目录用来分别存储不同模块的源代码,还有一个main.c和Makefile文件:main.c实现该工程的入口以及主要功能;Makefile是用来管理src/目录下编译的文件。两个子目录./sub
和./add分别实现加法和减法,也有自己独立的Makefile。
接下来看看怎么写Makefile文件。
递归式
为了实现每个目录下的代码具有独立的Makefile,且根目录下的Makefile可以一次执行子目录下的Makefile,就有了递归式的方法来写父目录下的Makefile了,该方法的实现是使用的$(MAKE)变量,使用格式如下:
dd: cd add && $(MAKE)
也可以这样写:
add: $(MAKE) -C add
这样就可以递归调用子目录add下面make命令来执行add目录下的Makefile文件,我们先把add和sub两个子目录下的makefile文件写好来,如下:
./add/Makefile
OBJS = add_int.o add_float.oCFLAGS = -O2all:$(OBJS)$(OBJS):%.o:%.c $(CC) -c $< -o $(OBJS_DIR)/$@ $(CFLAGS)
OBJS = sub_int.o sub_float.oCFLAGS = -O2all:$(OBJS)$(OBJS):%.o:%.c $(CC) -c $< -o $(OBJS_DIR)/$@ $(CFLAGS)
./src/Makefile内容:
# 取得当前子目录深度为1的所有目录名称SRC_DIRS := $(shell find . -maxdepth 1 -type d)SRC_DIRS := $(basename $(patsubst ./%,%,$(SRC_DIRS)))SRC_DIRS := $(filter-out $(EXCLUDE_DIRS),$(SRC_DIRS)).PHONY: $(SRC_DIRS)# 子目录执行默认make target$(SRC_DIRS): $(SRC_DIRS) main.o $(MAKE) -C $@main.o: %.o:%.c $(CC) -c $< -o $(OBJS_DIR)/$@ $(CFLAGS) $(INCS_DIRS)
接下来就是写主目录makefile_common_project下面的Makefile文件了,使用前面递归调用格式,Makefile文件如下:
CC = gccCFLAGS = -O2CXXFLAGS =TARGET = outfileBIN_DIRS := binINCS_DIRS := inc# 需要排除的目录EXCLUDE_DIRS := inc bin# INCLUDE DIRECTORYINCS_DIRS := $(shell find $(shell pwd)/$(INCS_DIRS) -maxdepth 1 -type d)INCS_DIRS := $(basename $(patsubst ./%,%,$(INCS_DIRS)))INCS_DIRS := $(foreach inc_tmp,$(INCS_DIRS),-I $(inc_tmp))export INCS_DIRS# 取得当前子目录深度为1的所有目录名称ALL_DIRS := $(shell find . -maxdepth 1 -type d)ALL_DIRS := $(basename $(patsubst ./%,%,$(ALL_DIRS)))ALL_DIRS := $(filter-out $(EXCLUDE_DIRS),$(ALL_DIRS))# 避免clean子目录操作同名,加上 _clean_ 前缀SUB_DIRS := $(ALL_DIRS)CLEAN_DIRS := $(addprefix _clean_,$(SUB_DIRS))export OBJS_DIR = ${shell pwd}/.objs.PHONY: $(TARGET) $(SUB_DIRS) clean# 执行默认make target$(SUB_DIRS): mkdir -p $(OBJS_DIR) $(MAKE) -C $@ $(CC) -o $(TARGET) $(OBJS_DIR)/*.o$(TARGET): $(SUB_DIRS)# 执行clean#$(CLEAN_DIRS):# $(MAKE) -C $(patsubst _clean_%,%,$@) clean# @,为不回显的命令#clean: $(CLEAN_DIRS)# find ./# /( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' /# -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' /# -o -name '*.symtypes' /) /# -type f -print | xargs rm -f#clean: $(CLEAN_DIRS)clean: -$(RM) -r $(OBJS_DIR) $(OBJS_DIR)/*.o
“
递归式的测试结果:
aaron@aaron-Inspiron-5520:~/tmp/makefile_test/makefile_common_project$ makemkdir -p /home/aaron/tmp/makefile_test/makefile_common_project/.objsmake -C srcmake[1]: 正在进入目录 `/home/aaron/tmp/makefile_test/makefile_common_project/src'make[1]: 放弃循环依赖 sub <- sub 。make[1]: 放弃循环依赖 add <- sub 。make[1]: 放弃循环依赖 add <- add 。cc -c main.c -o /home/aaron/tmp/makefile_test/makefile_common_project/.objs/main.o -I /home/aaron/tmp/makefile_test/makefile_common_project/inc -I /home/aaron/tmp/makefile_test/makefile_common_project/inc/sub -I /home/aaron/tmp/makefile_test/makefile_common_project/inc/addmake -C addmake[2]: 正在进入目录 `/home/aaron/tmp/makefile_test/makefile_common_project/src/add'cc -c add_int.c -o /home/aaron/tmp/makefile_test/makefile_common_project/.objs/add_int.o cc -c add_float.c -o /home/aaron/tmp/makefile_test/makefile_common_project/.objs/add_float.o make[2]:正在离开目录 `/home/aaron/tmp/makefile_test/makefile_common_project/src/add'make -C submake[2]: 正在进入目录 `/home/aaron/tmp/makefile_test/makefile_common_project/src/sub'cc -c sub_int.c -o /home/aaron/tmp/makefile_test/makefile_common_project/.objs/sub_int.o cc -c sub_float.c -o /home/aaron/tmp/makefile_test/makefile_common_project/.objs/sub_float.o make[2]:正在离开目录 `/home/aaron/tmp/makefile_test/makefile_common_project/src/sub'make[1]:正在离开目录 `/home/aaron/tmp/makefile_test/makefile_common_project/src'gcc -o outfile /home/aaron/tmp/makefile_test/makefile_common_project/.objs/*.o
总结:
本人也是初学Makefile的编写,上面的Makefile虽然能够遍历所有目录,并最终生成可执行代码。但是看编译过程还是有问题,先记录下,再改进吧!
- Makefile-例程讲解
- GCC的makefile例程
- makefile编写例程
- windows7下makefile例程
- makefile讲解...
- makefile讲解
- makefile讲解
- Makefile讲解
- 应用程序的makefile编写例程
- makefile文件讲解
- makefile常用讲解(2)
- Android Makefile 文件讲解
- 通用Makefile讲解【转】
- Android Makefile 文件讲解
- Makefile使用讲解
- 通用makefile讲解
- makefile常用讲解二
- makefile常用讲解三
- 第十四周【项目一-(4)平衡二叉树】
- 详细介绍 Python-__builtin__与__builtins__和builtins的区别与关系
- appstore开发者 名称修改
- 实时显示textarea输入多少字
- list的remove方法中的陷阱
- Makefile-例程讲解
- Matplotlib -多组线用不同的线性、颜色、节点绘制
- Android-- 隐藏显示软键盘
- cocos-js的一些问题
- [Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated c
- 学习编程常用网址
- asp.net mvc5中使用缓存依赖SqlCacheDependency
- js中substr,substring,indexOf,lastIndexOf,split 的用法
- eclipse springsource-tool-suite相关问题