一个通用的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 " ...
随机推荐
- 数据库——MySQL——>Java篇
MySQL MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是 ...
- django的CMS系统(内容管理系统)
一.什么是CMS系统 CMS具有许多基于模板的优秀设计,可以减少开发的成本. CMS的功能并不只限于文本处理,它也可以处理图片.Flash动画.声像流.图像甚至电子邮件档案. CMS还分各个平台脚本种 ...
- 本地代码上传到GitHub---拷贝github代码
来这里: 转载请标明出处: http://blog.csdn.net/hanhailong726188/article/details/46738929 步骤: git init git add na ...
- iOS 写给iOS开发者的React Native学习路线(转)
我是一名iOS开发者,断断续续一年前开始接触React Native,最近由于工作需要,专职学习React Native也有一个多月了.网络上知识资源非常的多,但能让人豁然开朗.迅速学习的还是少数,我 ...
- http中的get和post(一)
GET和POST有什么区别?及为什么网上的多数答案都是错的. 如果有人问你,GET和POST,有什么区别?你会如何回答? 我的经历 前几天有人问我这个问题.我说GET是用于获取数据的,POST,一般用 ...
- KVO的内部实现以及使用
转载自:http://www.cocoachina.com/applenews/devnews/2014/0107/7667.html KVO是实现Cocoa Bindings的基础,它提供了一种 ...
- iOS MJRefresh上拉加载更多
1.导入MJRefresh包 2.在类中引入:#import "MJRefresh.h" 3.添加footerView 添加加载更多的UI样式: MJRefreshAutoNorm ...
- React:入门计数器
---恢复内容开始--- 把React的官网入门例子全看一遍,理解了,但自己从头开始写有点困难,这次强迫自己从头开始写,并写好注释: import React, { Component } from ...
- Jenkins 关闭和重启实现方式.
1.关闭Jenkins 只需要在访问jenkins服务器的网址url地址后加上exit.例如我jenkins的地址http://localhost:8080/,那么我只需要在浏览器地址栏上敲下http ...
- 嵌入式设计初体验:永远的hello,world
目前,xilinx的zynq系列FPGA炒的火热,SOC成为FPGA发展的必然趋势.可见所有功能均用硬件描述语言设计是不科学的.硬件逻辑独有的并行性使其在实时处理和并行算法中占尽优势,但当执行串行操作 ...