一个通用的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"来彻底清除

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一个默默无闻的工程师的日常

openstack ocata部署ceilometer+gnocchi

3774
来自专栏haifeiWu与他朋友们的专栏

线上 Elasticsearch 集群健康值 red 状态问题排查与解决

之前一直运行正常的数据分析平台,最近一段时间没有注意发现日志索引数据一直未生成,大概持续了n多天,当前状态: 单台机器, Elasticsearch(下面称ES...

5012
来自专栏c#开发者

在.NET中轻松获取系统信息(1) -WMI篇

在.NET中轻松获取系统信息(1) -WMI篇 Montaque 申明: 1、个人的一点心得,仅供参考 2、转载时候,请保留原本。 ...

2767
来自专栏酷玩时刻

支付宝支付-常用支付API详解(查询、退款、提现等)

Maven项目引用JAR包可以参考 支付宝Wap支付你了解多少? 里面有详细的介绍

3812
来自专栏FreeBuf

「无文件」攻击方式渗透实验

前几天看了一个文章《全球上百家银行和金融机构感染了一种“无文件”恶意程序,几乎无法检测》,觉得powershell很是神奇,自己希望亲手实验一下,以最大程度还原...

3718
来自专栏大内老A

[原创]谈谈基于Kerberos的Windows Network Authentication - Part II

四、引入Ticket Granting  Service 通过上面的介绍,我们发现Kerberos实际上一个基于Ticket的认证方式。Client想要获取Se...

1959
来自专栏杨建荣的学习笔记

运维平台的建设思考-元数据管理(四)(r8笔记第16天)

对于服务器的一些信息,如果数据量大了之后总是感觉力不从心,需要了解,但是感觉得到的这些信息不够清晰明了。 比如我们得到一台服务器,需要知道最基本的硬件配置,内存...

38315
来自专栏小白鼠

分布式事务数据库事务CAP定理BASE理论分布式事务案例

断电了,该怎么处理?通过日志的方式!在执行事务的时候数据库首先会记录下这个事务的redo操作日志,然后才开始真正操作数据库,在操作之前首先会把日志文件写入磁盘,...

1192
来自专栏散尽浮华

centos7.4下Jira6环境部署及破解操作记录(完整版)

废话不多说,以下记录了Centos7针对Jira6的安装,汉化,破解的操作过程,作为运维笔记留存.

2524
来自专栏耕耘实录

Kubernetes中,通过Service访问Pod快速入门

版权声明:本文为耕耘实录原创文章,各大自媒体平台同步更新。欢迎转载,转载请注明出处,谢谢

1305

扫码关注云+社区