1.Makefile的作用

(1)决定编译哪些文件

(2)怎样编译这些文件

(3)怎样连接这些文件,最重要的是它们的顺序如何

2.Linux内核Makefile分类

*********************************************************************

顶层Makefile:它是所有Makefile文件的核心,从总体上控制着内核的编译、

连接

.config    :配置文件,在配置内核时生成,所有Makefile文件(包括顶层

目录及各级子目录)都是根据.config来决定使用哪些文件

arch/$(ARCH)/Makefile:对应于体系结构的Makefile,它用来决定哪些体系结

构相关的文件参与内核的生成,并提供一些规则来生成

特定格式的内核映像

scripts/Makefile.* : Makefile共用的通用规则、脚本等

kbuild Makefile :各级子目录下的Makefile,被上一层Makefile调用来编译

当前目录下的文件

*********************************************************************

3.根据Makefile的作用分析这5类文件

(1)决定编译哪些文件

Linux内核的编译过程从顶层Makefile开始,然后递归地进入各级子目录调用它们的Makefile,分为3个步骤:

(1)顶层Makefile决定内核根目录下哪些子目录将被编译进内核

在顶层Makefile中有如下内容:

init-y       := init/

drivers-y := drivers/ sound/ firmware/

net-y     := net/

libs-y       := lib/

core-y       := usr/

......................

core-y      += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

顶层Makefile将这13个子目录分为5类,除去include目录和后面不包

含内核源码的目录外,还有一个arch目录在arch/$(ARCH)/Makefile中被包

含进内核,在顶层Makefile中直接包含了这个Makefile,如下所示:

452   include $(srctree)/arch/$(SRCARCH)/Makefile

(2)arch/$(ARCH)/Makefile决定arch/$(ARCH)目录下哪些文件、哪些目录将

被编译进内核

在arch/arm/Makefile中有如下内容:

100   head-y      := arch/arm/kernel/head$(MMUEXT).o

arch/arm/kernel/init_task.o

...............................................

196   core-y  += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/

197   core-y  += $(machdirs) $(platdirs)

198   core-$(CONFIG_FPE_NWFPE)  += arch/arm/nwfpe/

199   core-$(CONFIG_FPE_FASTFPE)   += $(FASTFPE_OBJ)

200   core-$(CONFIG_VFP)    += arch/arm/vfp/

...............................................

204   libs-y    := arch/arm/lib/ $(libs-y)

第100行中MMUEXT在arch/arm/Makefile前面定义,对于没有MMU的处

理器,使用文件head-nommu.S;对于有MMU的处理器,使用head.S文件

CONFIG_XXXX在配置内核时定义,它的值有3种:y、m或空

编译内核时将依次进入init-y、core-y、libs-y、drivers-y和net-y

所列出的目录中执行它们的Makefile,每个子目录都会生成一个

built-in.o(libs-y所列的目录下,有可能生成lib.a文件)。最后,head-y

所表示的文件将和这些built-in.o、lib.a一起被连接成内核映像文件

vmlinux

(3)各级子目录下的Makefile决定所在目录下哪些文件将被编译进内核,哪

些文件将被编译成模块(驱动程序),进入哪些子目录继续调用它们的

Makefile

在配置内核时,生成配置文件“.config”,根据.config中定义的各

个变量决定编译哪些文件,Makefile使用如下语句间接包含.config文

件(因为包含的是"include/config/auto.conf"文件):

486   -include include/config/auto.conf

在"include/config/auto.conf"文件中,变量的值为y或m

1)obj-y用来定义哪些文件被编进(built-in)内核

obj-y中定义的.o文件由当前目录下的.c或.S文件编译生成,

它们连同下级子目录的built-in.o文件一起被组合成(使用

“$(LD)-R”命令)当前目录下的built-in.o文件,这个built-in.o

文件被它的上一层Makefile使用

2)obj-m用来定义哪些文件被编译成可加载模块(Loadable module)

obj-m中定义的.o文件由当前目录下的.c或.S文件编译生成,

它们被编译成模块,一个模块可以由一个或几个.o文件组成,对于

有多个源文件的模块,除在obj-m中增加一个.o文件外,还要定义

一个<module_name>-objs变量来告诉Makefile这个.o文件由哪些

文件组成

例如:

obj-$(CONFIG_ISDN) += isdn.o

isdn-objs := isdn_net_lib.o  isdn_v110.o  isdn_common.o

3)lib-y用来定义哪些文件被编成库文件

liy-y中定义的.o文件由当前目录下的.c或.S文件编译生成,

它们被打包成当前目录下的一个库文件:lib.a ;同时出现在

obj-y和lib-y中的.o文件,不会被包含进lib.a中,要把这个

lib.a编译进内核中,需要在顶层Makefile中libs-y变量中列出

当前目录

4)obj-y、obj-m还可以指定要进入的下一层子目录

obj-$(CONFIG_JFFS2_FS)   +=  jffs2/

(2)怎样编译这些文件----编译选项、连接选项是什么

这些选项可分为3类:

1)全局的

适用于整个内核代码,在顶层Makefile和arch/$(ARCH)/Makefile中

定义,这些选项的名称为CFLAGS(编译C文件的 选项)、AFLAGS(编译汇编

文件的选项)、LDFLAGS(连接文件的选项)、 ARFLAGS(制作库文件的选项)

2)局部的

在各个子目录中定义,针对当前Makefile中的所有文件,名称分别

为:EXTRA_CFLAGS、EXTRA_AFLAGS、EXTRA_LDFLAGS、EXTRA_ARFLAGS

3)个体的

仅适用于某个文件,如果想针对某个文件定义它的编译选项,可以使

用CFLAGS_$@, AFLAGS_$@,前者用于编译某个C文件,后者用于编译某

个汇编文件。$@表示某个目录文件

(3)怎样连接这些文件,它们的顺序如何

在顶层Makefile中,目录名的后面直接加上built-in.o或lib.a,表示

要连接进内核的文件,如下所示:

init-y      := $(patsubst %/, %/built-in.o, $(init-y))

core-y      := $(patsubst %/, %/built-in.o, $(core-y))

drivers-y   := $(patsubst %/, %/built-in.o, $(drivers-y))

net-y       := $(patsubst %/, %/built-in.o, $(net-y))

libs-y1     := $(patsubst %/, %/lib.a, $(libs-y))

libs-y2     := $(patsubst %/, %/built-in.o, $(libs-y))

libs-y      := $(libs-y1) $(libs-y2)

patsubst是个字符串处理函数,它的用法如下:

$( patsubst  pattern, replacement, text)

表示寻找“text”中符合格式“pattern”的字,用“replacement”代替

它们,比如init-y的初值为“init/”,经过变换后变为“init/built-in.o”

再如下所示:

vmlinux-init := $(head-y) $(init-y)

vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y)

vmlinux-all  := $(vmlinux-init) $(vmlinux-main)

vmlinux-lds  := arch/$(SRCARCH)/kernel/vmlinux.lds

vmlinux-all表示所有构成映象文件vmlinux的目标文件,可知这些目标文件的顺序为head-y、init-y、core-y、libs-y、drivers-y、net-y

4.总结

(1)配置文件.config中定义了一系列的变量,Makefile将结合它们来决定哪些

文件被编译进内核、哪些文件被编译成模块、涉及哪些子目录

(2)顶层Makefile和arch/$(ARCH)/Makefile决定根目录下哪些子目录、

arch/$(ARCH)目录下哪些文件和目录将被编译进内核

(3)各级子目录下的Makefile决定所在目录下的哪些文件将被编译进内核,哪些

文件被编译成模块(即驱动程序),进入哪些子目录继续调用它们的Makefile

(4)顶层Makefile和arch/$(ARCH)/Makefile设置了可以影响所有文件的编译、

连接选项,即全局选项

(5)各级子目录下的Makefile中可以设置影响当前目录下所有文件的编译、连接

选项,即局部选项

(6)顶层Makefile按照一定的顺序组织文件,根据连接脚本arch/$(ARCH)

kernel/vmlinux.lds生成内核映象文件vmlinux

linux源码Makefile详解的更多相关文章

  1. linux源码Makefile详解(完整)【转】

    转自:http://www.cnblogs.com/Daniel-G/p/3286614.html 随着 Linux 操作系统的广泛应用,特别是 Linux 在嵌入式领域的发展,越来越多的人开始投身到 ...

  2. linux源码Makefile详解(完整)

    转自:http://www.cnblogs.com/Daniel-G/p/3286614.html 随着 Linux 操作系统的广泛应用,特别是 Linux 在嵌入式领域的发展,越来越多的人开始投身到 ...

  3. linux 源码安装详解

    ./configure是用来检测你的安装平台的目标特征的.比如它会检测你是不是有CC或GCC,并不是需要CC或GCC,它是个shell脚本.make是用来编译的,它从Makefile中读取指令,然后编 ...

  4. NopCommerce源码架构详解--初识高性能的开源商城系统cms

    很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从中学习很多企业系统.软件开发的规范和一些新的技术.技巧,可以快速地提高我们 ...

  5. NopCommerce源码架构详解

    NopCommerce源码架构详解--初识高性能的开源商城系统cms   很多人都说通过阅读.学习大神们高质量的代码是提高自己技术能力最快的方式之一.我觉得通过阅读NopCommerce的源码,可以从 ...

  6. Nop--NopCommerce源码架构详解专题目录

    最近在研究外国优秀的ASP.NET mvc电子商务网站系统NopCommerce源码架构.这个系统无论是代码组织结构.思想及分层都值得我们学习.对于没有一定开发经验的人要完全搞懂这个源码还是有一定的难 ...

  7. Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览

    一.设计原理 1.Hadoop架构: 流水线(PipeLine) 2.Hadoop架构: HDFS中数据块的状态及其切换过程,GS与BGS 3.Hadoop架构: 关于Recovery (Lease ...

  8. Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立

    该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 关于RPC(Remote Procedure Call),如果没有概念,可以参考一下RMI(Remot ...

  9. Hadoop3.1.1源码Client详解 : 入队前数据写入

    该系列总览: Hadoop3.1.1架构体系——设计原理阐述与Client源码图文详解 : 总览 紧接着上一篇: Hadoop3.1.1源码Client详解 : 写入准备-RPC调用与流的建立 先给出 ...

随机推荐

  1. [css]兼容性

    div +input 输入框 , 在微信中  有问题 块级元素 行内元素

  2. MVC 使用 FluentScheduler 定时器计划任务

    MVC 使用 FluentScheduler 定时器计划任务 MacBook Pro 只有四个 USB Type-C 接口是否错了? 一项新技术的诞生总会对已存在的事物造成冲击或影响,如果大家都害怕冲 ...

  3. c语言关于二进制的输出

    c语言中的二进制输出是没有占位符的,不像八进制:%o: 和十六进制:x%: c中二进制的输出 //右移31位,从最高为开始和1做&运算,得到每一位的二进制数值 void printbinry( ...

  4. (转)assert()函数用法总结

    assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h>void assert( in ...

  5. Halcon学习笔记之缺陷检测(二)

    例程:detect_indent_fft.hdev 说明:这个程序展示了如何利用快速傅里叶变换(FFT)对塑料制品的表面进行目标(缺陷)的检测,大致分为三步: 首先,我们用高斯滤波器构造一个合适的滤波 ...

  6. Careercup - Facebook面试题 - 5188884744896512

    2014-05-02 07:18 题目链接 原题: boolean isBST(const Node* node) { // return true iff the tree with root 'n ...

  7. 关于MDK中:RO-data、RW-data、ZI-data

    最近在LPC2109上调试ENC28J60,协议栈使用的是UIP,刚开始用的telnet服务,能够正常编译运行.然后换成webserver提示: enc28j60.axf: Error: L6406E ...

  8. 在云服务器搭建WordPress博客(四)WordPress的基本设置

    前面说了 如何安装WordPress,接下来我们需要快速熟悉WordPress,以及进行一些必要的基本设置. 开始设置之前,建议大家先点击一篇左边菜单栏的每一个选项,看看到底是做什么用的.下面开始说一 ...

  9. c++ void,内存操作函数

    void的含义 void的字面意思是“无类型”, void * 则为“无类型指针”, void * 可以指向任何类型的数据 void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变 ...

  10. Unix守护进程

    问题描述:         Unix守护进程 问题解决:     Unix守护进程没有控制终端,终端名设置为问号(?),终端前台进程组ID设置(TPGID)为-1 守护进程编写规则:      (1) ...