KBuild MakeFile介绍
makefile输出总结

makefile输出总结【原创版】目录1.Makefile 简介2.Makefile 的输出3.Makefile 输出的格式4.Makefile 输出的优点5.总结正文1.Makefile 简介Makefile 是一种构建脚本,用于自动化构建和编译软件项目。
它通常包含一系列的规则和指令,用于描述项目的构建过程。
Makefile 最早用于 Unix 系统,但现在已经广泛应用于各种操作系统和编程语言中。
2.Makefile 的输出Makefile 的输出是指在执行 Makefile 后,系统生成的文件或结果。
这些输出通常包括编译后的目标文件、可执行文件和库文件等。
Makefile 的输出可以帮助开发者快速了解项目的构建状态,以便进行调试和测试。
3.Makefile 输出的格式Makefile 的输出格式通常遵循一定的规范,例如在输出文件名前加上“@”符号,表示该文件是由 Makefile 生成的。
另外,Makefile 还可以通过设置输出变量,来控制输出的格式和内容。
4.Makefile 输出的优点Makefile 输出的优点主要体现在以下几个方面:(1)自动化:Makefile 可以自动化执行构建过程,提高开发效率。
(2)可维护性:Makefile 可以将项目的构建过程描述得非常清晰,便于维护和修改。
(3)可扩展性:Makefile 可以通过调用其他脚本和程序,来实现更复杂的构建逻辑。
(4)跨平台性:Makefile 可以在各种操作系统和编程语言中使用,具有一定的通用性。
5.总结总之,Makefile 是一种非常实用的构建脚本工具,可以帮助开发者自动化项目的构建过程,提高工作效率。
粗略走走kbuild makefile编译流程

kbuild是Linux内核源码中用于管理和构建内核的工具,而makefile 是kbuild的一种配置文件,用于定义内核的编译规则和依赖关系。
本文将对kbuild makefile的编译流程进行详细介绍,包括编译环境的搭建、makefile的结构和语法、编译过程中各个阶段的功能以及常见问题的解决方法。
一、编译环境的搭建1. 安装必要的工具和软件在开始编译之前,首先需要在系统中安装必要的工具和软件,包括gcc、g++、make等。
这些工具和软件通常可以通过系统自带的包管理工具进行安装,或者从官方全球信息湾下载安装包手动安装。
2. 下载内核源码要进行内核的编译,首先需要下载Linux内核的源码。
可以通过git clone命令从官方git仓库中下载源码,也可以从官方全球信息湾下载压缩包并解压缩到本地。
3. 配置编译环境在下载完内核源码后,需要对编译环境进行配置,包括设置环境变量、配置编译选项等。
可以通过修改bashrc文件或者使用export命令来设置环境变量,也可以通过配置.config文件来设置编译选项。
二、makefile的结构和语法1. makefile的基本结构makefile是一个文本文件,通常包含了一系列的规则、变量和注释。
makefile的基本结构如下:target: dependencies[tab] mand其中,target表示目标文件,dependencies表示target依赖的文件mand表示生成target的命令。
每条规则都必须以tab键开始,表示该规则的命令。
2. makefile的语法makefile支持一些基本的语法和操作符,包括赋值运算符、条件语句、循环语句等。
通过这些语法和操作符,可以方便地定义编译规则和依赖关系,实现自动化编译。
三、编译过程中各个阶段的功能1. 准备阶段在准备阶段,make工具会读取makefile文件,并解析其中的规则和依赖关系。
它会根据目标文件和依赖文件的时间戳来确定哪些文件需要重新编译,哪些文件可以跳过。
14_makefile

5、变量
变量与c语言中的宏定义一样,代表一个文本字符串。
定义: 使用“=”定义。如: object = test.o 引用: 在引用宏时只需在变量前加$符号,但值得注意的是,如 果变量名的长度超过一个字符,在引用时就必须加圆括号 ()。 如: $(object):test.c cc -c test.c -o $(object)
隐含变量:内嵌隐含规则的命令中,所使用的变量都是预定 义的变量。我们将这些变量称为“隐含变量”。
例如,编译.c源文件的隐含规则为:“$(CC) -c $(CFLAGS) $(CPPFLAGS)”。CC就是隐含变量,CC=cc。默认的编译命令 是“cc”,执行的命令是:“cc –c”。
6、#,@
Makefile中“#”字符后的内容被作为是注释内容(和 shell脚本一样)处理。如果此行的第一个非空字符为 “#”,那么此行为注释行。注释行的结尾如果存在反斜 线(\),那么下一行也被作为注释行。一般在书写 Makefile时推荐将注释作为一个独立的行,而不要和 Makefile的有效行放在一行中书写。当在Makefile中需要 使用字符“#”时,可以使用反斜线加“#”(\#)来实现 (对特殊字符“#”的转义),其表示将“#”作为一字符 而不是注释的开始标志。 @:不显示执行的命令行
2、makefile基本结构
Makefile是make默认读入的配置文件,以下是Makefile 的编写规则。 target ... : prerequisites ... command target是一个目标文件,可以是Object File,也可以是执 行文件。 prerequisites是要生成那个target所需要的源文件或是目 标文件。 command是make需要执行的命令。(任意的shell命令 ),command前面一定要有tab空格。 如:hello.o:hello.c hello.h gcc hello.c -o hello.o -c
kbuild与KMakefile

kbuild与KMakefilekbuild与KMakefileSoftware ? kernel ? kbuild与KMakefileFoldTable of Contents顶层Makefile关于.version用yes命令回答make oldconfigbuild and install modules$(call if_changed, xxx)FORCE顶层Makefile默认的Makefile的入口点是第一条规则。
而Linux内核的Makefile的第一条规则是这样的:除去上面一长串赋值语句,来到:PHONY := _all_all:是一条空规则。
奇怪的是,下面不远处有如下规则:ifeq ($(KBUILD_EXTMOD),)_all: allelse_all: modulesendif也就是说目标_all被写了两遍。
原因如下:一般Makefile是不允许一个目标被重复写两遍的,如:a:echo a1a:echo a2这种情况会生成一条警告,说一条规则将被忽略。
但如果第一条规则是一条空规则则是可以的,如:a:a:echo a2而且还有如下用法:b:echo ba:echo a此Makefile如果直接make将会执行echo b,因为这是第一条规则,会被当成默认规则。
但如果写成下面的样子:a:b:echo ba:echo a由于第一条空规则的存在,echo a会被当成默认规则执行。
因此Linux内核中的Makefile的_all可以做如下解释:真正的入口点是ifeq ($(KBUILD_EXTMOD),)_all: allelse_all: modulesendif这不必保证这几行代码是第一条规则,之前还可以插入任何内容,只需要保证空规则_all:是整个文件的第一条规则,正真入口点处的规则便会被当成默认规则被执行。
关于.versionmake distclean后第一次make会在顶层目录生成.version文件.内核在启动时打印出的如下第一句话Linux version 2.6.23.17-alp_nl-kzm-arm11-g5******* (kinhi@kinhi0) (gcc version 4.1.2 20081209 (Sony CE Linux 5.0.2.0)) #2 PREEMPT Thu Mar 19 09:29:53 JST 2009其中的#2 PREEMPT中的#2就是.version文件中的版本号, 表示kernel是由在make distclean之后的第几次make生成的.参考顶层Makefile中的"#Generate new vmlinux version"段. 用yes命令回答make oldconfigyes '' | make oldconfigbuild and install modulesmake modulesmake modules_install INSTALL_MOD_PATH=/target/root/fs/ (if INSTALL_MOD_PATH is not specified, modules will be installed to host machine.)$(call if_changed, xxx)参考 scripts/Kbuild.include#### if_changed - execute command if any prerequisite is newer than# target, or command line has changed# if_changed_dep - as if_changed, but uses fixdep to reveal dependencies# including used config symbols# if_changed_rule - as if_changed but execute rule instead # See Documentation/kbuild/makefiles.txt for more info和 Documentation/kbuild/makefiles.txt FORCEPage tags: makefile。
kbuild 编译过程 -回复

kbuild 编译过程-回复kbuild是一个Linux内核的编译系统,它主要用于构建和管理Linux内核的编译过程。
kbuild采用Makefile作为构建脚本的描述语言,并提供了丰富的功能和工具来帮助开发者自动化处理各种编译任务。
kbuild的编译过程主要分为以下几个步骤:准备工作、配置、编译和安装。
接下来,我将一步一步详细讲解这些步骤。
1. 准备工作:在开始编译之前,需要先准备好构建环境和所需的工具。
首先,需要确保系统安装了合适的编译器,比如GCC。
其次,还需要安装一些必要的工具,比如make和perl。
这些工具在大多数Linux发行版的默认软件仓库中都可以找到,并且可以通过命令行工具进行安装。
2. 配置:在开始编译之前,需要根据系统和硬件环境的不同进行相应的配置。
Linux 内核的配置文件通常命名为“.config”,它包含了构建内核所需的各种选项和参数。
在kbuild中,可以使用make menuconfig命令来进行配置。
执行该命令后,会弹出一个图形界面的菜单,开发者可以在其中选择和设置各种选项。
在这个过程中,可以根据自己的需求选择需要编译进内核的功能和驱动,并进行其他的相关配置。
完成配置后,配置文件会被保存为“.config”。
3. 编译:在完成配置后,就可以开始进行编译了。
为了简化编译过程,kbuild提供了许多Makefile规则和工具,可以自动地处理依赖关系、并行编译等问题。
在进行编译之前,可以通过make clean命令清理之前的编译产物。
然后,使用make命令开始编译。
make会读取Makefile文件,并根据该文件中的规则执行编译任务。
编译过程可能会持续一段时间,具体时间取决于系统的配置和硬件性能。
4. 安装:在编译完成后,可以使用make install命令将编译得到的内核安装到系统中。
该命令会将编译得到的内核镜像和相关的文件拷贝到指定的目录中,通常是“/boot”。
Kconfig原理,makefile原理

Makefile文件面对树状结构的内核源码目录,内核编译采用了各个子目录拥有自己目录相关的Makefile(被称为sub-Makefile或kbuild Makefile),内核编译依赖于各个子目录下的子makefile(sub-Makefile)文件,这些sub-Makefile定义了根据该子目录下的源码文件构建目标文件的规则,并且仅对该目录下的文件作适当的修改。
顶层Makefile采用递归的方式调用位于init/, drivers/, sound/, net/, lib/ ,usr/等目录下的各个子目录中的Makefile文件。
在递归调用之前,kbuild首先要确定是否已经满足一些必要的条件,包括在必要时更新include/Linux /version.h文件,并设置符号链接include/asm,使之指向与目标体系结构相关的文件。
例如,如果为PPC编译代码,则include /asm指向include/asm-ppc。
kbuild还要对文件include/Linux/autoconf.h和include/Linux /config进行编译。
之后,从根目录开始进行递归。
各个子Makefile文件比较简单,指出了该如何编译目标文件,例如/mm目录下的Makefile 片段:16 obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o17 obj-$(CONFIG_BOUNCE) += bounce.o18 obj-$(CONFIG_SW AP) += page_io.o swap_state.o swapfile.o thrash.o19 obj-$(CONFIG_HAS_DMA) += dmapool.o20 obj-$(CONFIG_HUGETLBFS) += hugetlb.oKconfig文件Kconfig的作用就是为了让用户配置内核,在Kconfig中定义了一些变量,用户通过设置变量的值来选择如何个性化自己的系统内核。
makefile的使用

makefile的使用一、什么是makefilemakefile是一种用来描述和指导如何编译和构建程序的文件。
它记录了源文件之间的依赖关系和编译规则,通过解析makefile文件,可以自动化地编译和构建程序。
二、为什么要使用makefile使用makefile有以下几个优点:1.自动化编译: makefile可以在编译过程中自动判断哪些文件需要重新编译,从而减少重复编译的时间和工作量。
2.简化构建流程: makefile可以将复杂的构建过程和编译命令封装成一个命令,简化构建流程,提高工作效率。
3.管理项目依赖: makefile可以记录文件之间的依赖关系,当某个文件发生变化时,只需要重新编译与之相关的文件,从而加快构建速度。
4.提高可维护性: makefile使得代码的组织结构更加清晰和可维护,便于团队协作和后续维护。
三、makefile的基本语法makefile的语法较为简单,包括以下几个基本元素:1.目标(target): 目标是构建过程中的一个步骤或者一个文件,并且有依赖关系。
在makefile中,目标通常是一个需要构建的文件,也可以是一个执行命令的动作。
2.依赖关系(prerequisites): 依赖关系是指目标所依赖的文件或者其他目标。
当一个目标的依赖发生变化时,该目标需要重新构建。
3.命令(command): 命令是指构建过程中的具体操作。
在makefile中,每个目标可以指定一个或多个命令,用于构建该目标。
4.变量(variable): 变量是makefile中定义的一个数据容器,用于存储常量或者计算结果。
可以通过引用变量来简化makefile的书写和维护。
5.规则(rule): 规则是指一个目标和其依赖关系的完整定义,包含了目标、依赖关系和命令。
下面是一个简单的makefile示例:# 定义变量CC = gccCFLAGS = -Wall -O2# 定义目标及其依赖关系和命令hello: main.o utils.o$(CC) $(CFLAGS) -o hello main.o utils.o# 定义目标的依赖关系和命令main.o: main.c utils.h$(CC) $(CFLAGS) -c main.cutils.o: utils.c utils.h$(CC) $(CFLAGS) -c utils.c四、makefile的工作流程makefile的工作流程包括以下几个步骤:1.读取makefile文件: make工具会首先读取当前目录下的makefile文件,如果没有找到,则会寻找默认的文件名(GNUmakefile、makefile或Makefile)。
kbuild 编译过程

kbuild 编译过程kbuild是用于编译Linux内核的工具链,它提供了一种简洁而高效的方式来管理和构建内核源代码。
本文将详细介绍kbuild的编译过程,并逐步解答相关问题。
一、什么是kbuild?kbuild是Linux内核源代码的编译系统,它由Makefile和一些特殊的工具组成。
它的主要作用是根据Makefile中的规则和依赖关系,自动化地完成内核的编译、链接和安装等工作。
同时,kbuild还提供了很多功能强大且灵活的特性,如支持模块化编译、优化编译过程、生成调试信息等。
二、kbuild的工作原理kbuild的工作原理基于Makefile和一系列的规则。
Makefile是一种用于自动化构建的文件,它定义了编译的规则、依赖关系和操作指令等。
以Linux内核源代码为例,其Makefile通常包含了一系列的变量和规则,如编译器选项、目标文件列表和链接选项等。
kbuild会根据这些信息来生成编译命令,并自动地执行编译、链接和安装等操作。
三、kbuild的编译过程1. 配置内核参数在编译内核之前,需要先配置内核的一些参数,如硬件支持选项、调试选项和功能模块等。
这可以通过执行`make config`或`make menuconfig`等命令来完成。
配置完成后,会生成一个.config文件,里面包含了所有的配置信息。
2. 构建编译环境在配置完成后,需要准备编译所需的工具和库文件。
这可以通过执行`make prepare`命令来自动完成,它会检查系统的环境和依赖关系,并自动下载安装所需的工具链和库文件等。
3. 编译内核源代码一切就绪后,可以执行`make`命令来编译内核源代码。
在这一步中,kbuild 会遍历整个源代码树,并根据Makefile中的规则来确定每个目标文件的编译命令。
编译过程中,kbuild会自动管理依赖关系,并根据需要执行增量编译,以提高编译效率。
4. 链接内核编译完成后,会生成一系列的目标文件。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一个Makefile只负责在他自己的文件夹中构建objects。在子文件夹中的文件应该由子文件夹中的Makefiles来照顾。如果你知道他们,build系统将会自动递归地用在子文件夹中的efile
obj-$(CONFIG_EXT2_FS) += ext2.o
ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
在这个例子中,如果$(CONFIG_EXT2_FS_XATTR)是y,则xattr.o只是混合object文件ext2.o的一部分。
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
注意这里$(CONFIG_ISDN_PPP_BSDCOMP)是m.
Note: In this example $(CONFIG_ISDN_PPP_BSDCOMP) evaluates to 'm'。
在这个例子中,模块名是isdn.o,Kbuild将会编译列在$(isdn-objs)的object文件,然后在这些文件的列表中调用"$(LD) -r"来产生isdn.o。
Kbuild使用后缀-objs,-y来识别混合的object文件。这允许Makefiles使用变量CONFIG_sambol来决定一个object是否是混合object的的一部分。
如果一个内核模块从多个源文件构建,KBuild就必须要知道你想从哪些部分构建模块。因此,你不得不设置$(<module_name>-objs)变量来告诉KBuild。
Example:
#drivers/isdn/i4l/Makefile
obj-$(CONFIG_ISDN) += isdn.o
isdn-objs := isdn_net_lib.o isdn_v110.o isdn_common.o
注意,当你构造一个objects到内核中时,上面的语法当然也能够工作。因此,如果你让CONFIG_EXT2=Y,KBuild将会为你构建一个独立的ext2.o文件,并且连接到built-in.o。
Library file goals - lib-y
用obj-*连接的Objects在指明的文件夹中被用作模块或者综合进built-in.o。也又可能被列出的objects将会被包含进一个库,lib.a。所有用lib-y列出的objects在那个文件夹中被综合进单独的一个库。列在obj-y和附加列在lib-y中的Objects将不会被包含在库中,因为他们将会被任意的存取。对于被连接在lib-m中,连续的objects将会被包含在lib.a中。值得注意的是kbuild makefile可能列出文件用作built-in,并且作为库的一部分。因此,同一个文件夹可能包含一个built-in.o和lib.a文件。
target为编译对象的名字。如果没有指定xxx-objs,这编译这个对象需要的源文件就是$(target).c或$(target).s。如果指定了$(target)-objs,则编译这个对象需要的源文件由$(target)-objs指定,并且不能有$(target).c或$(target).s文件。
目标定义
Kbuild Makefile的一个最主要功能就是指定编译什么,这个功能是通过下面两个对象指定的obj-?和xxx-objs:
obj-?
obj-?指定编译什么,怎么编译?其中的“?”可能是“y”或“m”,“y”指定把对象编译进内核中,“m”指定把对象编译为模块。语法如下;
obj-? = $(target).o
EXTRA_CFLAGS可以给Kbuild系统添加外部系统头文件,
EXTRA_CFLAGS += $(ext_include_path)
一般外部头文件可能位于外部模块源文件的目录内,如何指定呢?这可以借助$(src)或$(obj)
$(src)/$(obj)
$(src)是一个相对路径,它就是Makefile/Kbuild文件所在的路径。同样$(obj)就是编译目标保存的路径,默认就是源代码所在路径。
其中“?”可以是“y”或“m”,$(sub_target)是子目录名字。
编译器选项
尽管在大多数情况下不需要指定编译器选项,有时我们还是需要指定一些编译选项的。
ccflags-y, asflags-y and ldflags-y
这些编译选项用于指定cc、as和ld的编译选项
编译外部模块
有时候我们需要在内核源代码数的外面编译内核模块,编译的基本命令是:
obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
Loadable module goals - obj-m
$(obj-m)指明object文件作为可装载的内核模块被构建。一个模块可能从一个或者多个源文件被构建。kbuild maefile只是简单的将源文件加到%(obj-m)
Example:
#drivers/isdn/i4l/Makefile
# Makefile for the kernel ISDN subsystem and device drivers.
# Each configuration option enables a list of files.
obj-$(CONFIG_ISDN) += isdn.o
xxx-objs
xxx-objs指定了编译对象需要的文件,一般只有在源文件是多个时才需要它。
只要包含了这两行,Kbuild Makefile就应该可以工作了。
嵌套编译
有时一个对象可能嵌入到另一个对象的目录下,那个如何编译子目录下的对象呢?其实很简单,只要指定obj_?的对象为子目录的名字就可以了:
obj-? = $(sub_target)/
Example:
#arch/i386/lib/Makefile
lib-y := checksum.o delay.o
这里讲会创建一个基于checksum.o和delay.o的库文件。对于kbuild,识别一个lib.a正在被构建,这个文件夹应该被列在libs-y中。lib-y的使用方法通常被限制在lib/和arc/*/lib中。
make -C $(KERNEL_DIR) M=`pwd` modules
我们可以把这个命令集成到Makefile里,这样我们就可以只输入“make”命令就可以了。回想上一章的那个Makefile,它把Normal Makefile和Kbuild Makefile集成到一个文件中了。为了区别Kbuild Makefile和Normal Makefile,这样我们改写Makefile为如下形式,并且添加Kbuild Makefile -“Kbuild”。
obj-$(CONFIG_FOO) += foo.o
$(CONFIG_FOO)要么是y(built-in)要么是m(module)。如果CONFIG_FOO既不是y也不是m,那么文件将不会被编译也不会被连接。
Built-in object goals - obj-y
kbuild Makefiles在$(obj-y)列表中为vmlinux指明object文件。这个列表依靠内核的配置。
ifneq ($(KERNELRELEASE),)
include "Kbuild"
else
...
endif
外部头文件
有时需要连接内核源代码外部的系统头文件,但Kbuild系统默认的系统头文件都在内核源代码内部,如何使用外部的头文件呢?这个可以借助于Kbuild系统的特殊规则:
EXTRA_CFLAGS
因此,我们修改Kbuild文件添加EXTRA_CFLAGS来包含外部头文件尽管在这个驱动里没有引用外部系统头文件:
## Kbuild
MODULE_NAME = helloworld
$(MODULE_NAME)-objs := hello.o
EXTRA_CFLAGS := -I$(src)/include
八、KBuild MakeFile介绍
从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这同过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的Makefile,然后根据读到的内容第二次读取Kbuild的Makefile来编译Linux内核。
$(MODULE_NAME)-objs := hello.o
obj-m := $(MODULE_NAME).o
一般不需要在Makefile里包含如下代码,这样写完全是为了兼容老版本的Kbuild系统。KERNELRELEASE变量在Kernel Makefile里定义的,因此只有在第二次由Kbuild读取这个Makefile文件时才会解析到Kbuild的内容。
obj-m := $(MODULE_NAME).o
Goal definitions
Example:
obj-y += foo.o
告诉kbuild,在文件夹中又一个叫做foo.o的object。foo.o将会被从foo.c或者foo.S被构建。
如果foo.o被构建成一个模块,则将使用变量obj-m。Example:
modules:
make -C $(KERNEL_DIR) M=$(MODULEDIR) modules
clean distclean:
rm -f *.o *.mod.c .*.*.cmd *.ko