一个通用的Makefile(二)
1、各级子目录的Makefile:
- obj-y += file.o
- obj-y += subdir/
“obj-y += file.o” 表示把当前目录下的file.c编进程序里。
“obj-y += subdir/”表示进入subdir这个子目录下去寻找文件来编进子程序中;
2、顶层目录的Makefile:
CROSS_COMPILE = #如果要交叉编译的话,就是:CROSS_COMPILE = arm-linux-
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
export AS LD CC CPP AR NM #把上面定义的变量用export导出来,后面的子目录就能用:
export STRIP OBJCOPY OBJDUMP
CFLAGS := -Wall -O2 -g
CFLAGS += -I $(shell pwd)/include -I 。。。。 # -I 指定到哪个目录去搜索头文件。
LDFLAGS := -lm 。。。。。
export CFLAGS LDFLAGS #把这两个也导出来。
TOPDIR := $(shell pwd) #顶层目录
export TOPDIR
TARGET := show_file #目标
- obj-y += main.o
- obj-y += 目录名如package/
- obj-y += framework/
all :
make -C ./ -f $(TOPDIR)/Makefile.build
$(CC) $(LDFLAGS) -o $(TARGET) built-in.o
clean:
rm -f $(shell find -name "*.o")
rm -f $(TARGET)
distclean:
rm -f $(shell find -name "*.o")
rm -f $(shell find -name "*.d")
rm -f $(TARGET)
我们这个工程顶层有:main.c,还有package,framework等子目录
framwork子目录下又有libs、manager、services等子目录;
编译过程:
Makefile是先从子目录下开始执行的:
1> 执行顶层目录的makefile程序时,先进入顶层目录,发现有些文件和目录,将会进入如DSVICICOMSVC/
2> 进入子目录后,又会发现又有子目录的makefile,DSVICICOMSVC、DSVICICOMMGR,执行子目录的makefile;
3> 把test.c编译成test.o,把test目录下的.o文件打包成build_in.o
4> 经过多个子目录后,回到顶层目录.把main.c 编译成main.o ,并与各个子目录的build-in.o打包成最终的build-in.o.
make -C ./ -f Makefile.build
3、顶层目录的Makefile.build:
这是最复杂的部分,它的功能就是把某个目录及它的所有子目录中、需要编进程序去的文件都编译出来,打包为built-in.o;
PHONY := __build
#假目标
__build:
obj-y :=
subdir-y :=
include Makefile #包含当前目录的makefile,才知道目标是哪些目标和目录
# obj-y := a.o b.o c/ d/
# $(filter %/, $(obj-y)) : c/ d/
# __subdir-y :
c d
# subdir-y :
c d
__subdir-y :=
$(patsubst %/,%,$(filter %/, $(obj-y)))
subdir-y +=
$(__subdir-y)
# c/built-in.o d/built-in.o
subdir_objs := $(foreach
f,$(subdir-y),$(f)/built-in.o)
# a.o b.o
cur_objs := $(filter-out %/, $(obj-y))
dep_files := $(foreach f,$(cur_objs),.$(f).d) #(foreach var,list,text) 结果是由空格隔开的‘text’ 在‘list’中多次扩展的字组成的新的‘list’
dep_files := $(wildcard $(dep_files))
ifneq ($(dep_files),)
include
$(dep_files)
endif
PHONY += $(subdir-y)
__build : $(subdir-y) built-in.o
$(subdir-y):
make -C $@ -f
$(TOPDIR)/Makefile.build
built-in.o : $(cur_objs)
$(subdir_objs)
$(LD)
-r -o $@ $^ #打包
dep_file = .$@.d
%.o
: %.c
$(CC) $(CFLAGS) -Wp,-MD,$(dep_file) -c -o $@ $<
.PHONY
: $(PHONY)
4、怎么使用这套Makefile:
1.把顶层Makefile, Makefile.build放入程序的顶层目录
2.修改顶层Makefile
2.1 修改工具链
2.2 修改编译选项、链接选项
2.3 修改obj-y决定顶层目录下哪些文件、哪些子目录被编进程序
2.4 修改TARGET,这是用来指定编译出来的程序的名字
3. 在各一个子目录下都建一个Makefile,
形式为:
obj-y += file1.o
obj-y += file2.o
obj-y += subdir1/
obj-y += subdir2/
执行"make"来编译,执行"make
clean"来清除,执行"make distclean"来彻底清除
一个通用的Makefile(二)的更多相关文章
- 编写一个通用的Makefile文件
1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...
- Linux C编程学习之开发工具3---多文件项目管理、Makefile、一个通用的Makefile
GNU Make简介 大型项目的开发过程中,往往会划分出若干个功能模块,这样可以保证软件的易维护性. 作为项目的组成部分,各个模块不可避免的存在各种联系,如果其中某个模块发生改动,那么其他的模块需要相 ...
- 一步一步写一个简单通用的makefile(二)
这一篇源代码沿用上一篇的源代码hellomake.c hellofunc.c hellofunc.h makefile 但是代码内容和结构有变化,如下: . ├── include │ └── h ...
- 一个通用的Makefile (转)
据http://bbs.chinaunix.net/thread-2300778-1-1.html的讨论,发现还是有很多人在问通用Makefile的问题,这里做一个总结.也作为以后的参考. ...
- 14、编写一个通用的Makefile
编译test_Makefile的方法:a. gcc -o test a.c b.c对于a.c: 预处理.编译(C文件转换成汇编).汇编(汇编转换成机器码)对于b.c:预处理.编译.汇编最后链接优点:命 ...
- 一步一步写一个简单通用的makefile(四)--写一个通用的makefile编译android可执行文件
通常要把我们自己的的代码编译成在android里面编译的可执行文件,我们通常是建一个文件夹 . ├── Android.mk ├── Application.mk ├── convolve.cl ├─ ...
- 一个通用的makefile(一)
最近在编写Android编译系统时,需要遍历每一个目录下每一个文件夹下的makefile,网上的方法有些繁琐 :就直接贴上自己遍历子目录深度为1:(for temporary)(之后会继续更新) 下 ...
- 一个通用的Makefile框架
先做一个简单的记录,后续有时间再慢慢完善补充细节. 先上一个整体图片: 其中,最重要的文件就是:program_template.mk. 下面是program_template.mk最重要的内容: $ ...
- 一个通用的makefile
# ESDK the makefile setting file - chenwg@20131014 # you can modify "PC = 1" such as " ...
随机推荐
- [UI列表]LoopScrollRect无限滑动不卡顿
应用场景 对于背包界面,排行榜列表,聊天消息,等有大量的UI列表的界面,常规做法是为每一条数据生成一个格子,在数据量越大的情况下,会生成越来越多的Gameobject,引起卡顿. 这篇文章讲述的就是解 ...
- MPSOC之7——开发流程uramdisk
用petalinux的预编译目录里有rootfs文件,选择rootfs.tar.gz作为初始输入. 1.原始文件-->uramdisk 1.1 解压原始rootfs.tar.gz,得到若干文件 ...
- MyBatis_查询缓存01
一.查询缓存 查询缓存的使用,主要是为了提高查询访问速度.将用户对同一数据的重复查询过程简单化,不在每次均从数据库中查询获取结果数据,从而提高访问速度. MyBatis的查询缓存机制,根据缓存区的作用 ...
- 配置SQL Server on Linux(1)
1. 背景 SQL Server一般是在安装过程中进行相关的配置,安装完成之后,再去修改有一些配置就比较麻烦,比如更改SQL Server实例级别的排序规则.但在Linux下,安装过程并没有很多可以配 ...
- Web前端开发好学吗?谈谈一位学姐的前端工程师之路
我的第一篇博客....... 我是一名工科女,因高考失利与理想的院校擦肩而过,从而选择了机电专业.毕业后找工作时才发现机电专业的工作并不太适合我.我的父母也支持我转专业求职,但这个过程有时会让我迷茫. ...
- 在Eclipse中创建Django项目
在以前的分享中,我们是在命令行模式下创建Django项目的,那么,如何在IDE中使用Django呢? 本文将介绍如何在Eclipse中创建Django项目. 首先,新建Django项目mysite,如 ...
- 【ANT】创建删除目录,复制移动重命名文件
一.创建目录: <?xml version="1.0"?> <project default="test_mkdir"> <tar ...
- web前端优化整理(转)
如今浏览器能够实现的特性越来越多,并且网络逐渐向移动设备转移,使我们的前端代码更加紧凑,如何优化,就变得越来越重要了. 开发人员普遍会将他们的代码习惯优先于用户体验.但是很多很小的改变可以让用户体验有 ...
- iOS屏幕适配(尺寸适配)
屏幕尺寸适配:一 在.pch中加入以下代码,在定义每个尺寸值的时候都调用下边的宏 //以iphone7为例 定义 view相关的宽高宏#define IPHONEHIGHT(b) [UIScreen ...
- python变量字符拼接
cpu = instances['vcpus_current'] cpu1 = str(cpu) + '核' memory = instances['memory_current'] / 1024 m ...