= 是最基本的赋值
:= 是覆盖之前的值
= 是如果没有被赋值过就赋予等号后面的值
+= 是添加等号后面的值
$(KBUILD_CFLAGS)是定义在根目录Makefile中的变量,它适用于整个内核树。
obj-y += disk1/kernel/
把disk1/kernel/目录下的文件编译进内核, -y是编译进内核,-m是编译成模块
obj-y:把由foo.c 或者 foo.s 文件编译得到foo.o 并连接进内核.
obj-m: 则表示该文件作为模块编译.
除了y、m以外的obj-x 形式的目标都不会被编译。
lib-y用来定义哪些文件被编成库文件
ccflags-y asflags-y和ldflags-y这三个变量的值分别对应编译、汇编、链接时的参数。
Kbuild Makefile分析
2.1 obj-y和obj-m
最简单的kbuild makefile可以仅包含:obj-
(
C
O
N
F
I
G
F
O
O
)
+
=
f
o
o
.
o
其
中
(CONFIG_FOO) += foo.o 其中
(CONFIGFOO)+=foo.o其中(CONFIG_FOO)可以等于y或者m,它的值由.config给出,如果
(
C
O
N
F
I
G
F
O
O
)
既
不
是
y
也
不
是
m
,
那
么
该
文
件
不
会
被
编
译
和
链
接
。
当
(CONFIG_FOO)既不是y也不是m,那么该文件不会被编译和链接。 当
(CONFIGFOO)既不是y也不是m,那么该文件不会被编译和链接。当(CONFIG_FOO)等于y时,上面语句等价于obj-y += foo.o,它告诉kbuild在当前目录下,有一个叫做foo.o的目标文件,它将从foo.c或则foo.S编译得到。
当$(CONFIG_FOO)等于m时,表示foo.o需要被编译成模块.
https://blog.csdn.net/luckywang1103/article/details/50673536
在Makefile使用include关键字可以把别的Makefile包含进来
make命令开始时,会把找寻include所指出的其它Makefile,并把其内容安置在当前的位置。就好像C/C++的#include指令一样。如果文件都没有指定绝对路径或是相对路径的话,make会在当前目录下首先寻找,如果当前目录下没有找到,那么,make还会在下面的几个目录下找:
1、如果make执行时,有“-I”或“–include-dir”参数,那么make就会在这个参数所指定的目录下去寻找。
2、如果目录/include(一般是:/usr/local/bin或/usr/include)存在的话,make也会去找。
有时需要连接内核源代码外部的系统头文件,但Kbuild默认的系统头文件都在内核源代码内部,如何使用外部的头文件需要借助Kbuild系统的特殊规则
EXTRA_CFLAGS+=$(ext_include_path)
在linux内核构建的过程中,要用到的编译器为"gcc", 要用到的汇编为"as", 要用到的链接器为"ld"。然而,在编译linux内核的过程中,要编译不同的文件而有的文件需要不同的编译选项。那么如果将文件的编译选项告诉给相应的编译器?
在linux内核的最顶层目录也就是根目录下面的Makefile文件中,有一个变量"KBUILD_CFLAGS",这个
(
K
B
U
I
L
D
C
F
L
A
G
S
)
中
存
放
的
是
传
递
给
g
c
c
编
译
器
的
编
译
选
项
,
如
果
被
编
译
的
文
件
在
被
g
c
c
编
译
时
,
没
有
特
殊
的
要
求
的
话
就
会
使
用
(KBUILD_CFLAGS)中存放的是传递给gcc编译器的编译选项,如果被编译的文件在被gcc编译时,没有特殊的要求的话就会使用
(KBUILDCFLAGS)中存放的是传递给gcc编译器的编译选项,如果被编译的文件在被gcc编译时,没有特殊的要求的话就会使用(KBUILD_CFLAGS)中的编译选项。
但是如果被gcc编译的文件有特殊的编译选项要求的话,使用如下的方式来指定编译选项:
ccflags-y,是指定给
(
C
C
)
的
编
译
选
项
;
a
s
f
l
a
g
s
−
y
,
是
指
定
给
(CC)的编译选项; asflags-y,是指定给
(CC)的编译选项;asflags−y,是指定给(AS)的编译选项;
ldflags-y,是指定给$(LD)的编译选项;
$(KBUILD_CFLAGS)是定义在根目录Makefile中的变量,它适用于整个内核树。
参考链接:https://blog.51cto.com/weiguozhihui/1591397
库文件和头文件的区别:
简单来说:库文件通过头文件向外导出接口。用户通过头文件找到库文件中
头文件中有函数的申明,库文件实现函数的定义。
比如,printf函数。使用时应包括stdio.h,打开stdio.h你只能看到,printf这
个函数的申明,却看不到printf具体是怎么实现的,而函数的实现在相应的C库
中。而库文件一般是以二进制形式而不是C源文件形式提供给用户使用的。程序
中包括了stdio.h这个头文件。链接器就能根据头件中的信息找到printf这个函
数的实现并链接进这个程序代码段里。
函数实现的代码从而把这段代码链接到用户程序中去。
obj-y = main.o
main-objs := a.o
b.o
c.o
将a.c b.c c.c三个文件编译后链接生成main.o
.a文件,是LINUX系统中的静态链接库文件。其实就是把若干o文件打了个包。
本质上来说库是一种可执行代码的二进制形式
#####WINDOWS下:.dll 后缀为动态库,.lib 后缀为静态库;
#####LINUX下:.so后缀为动态库,.a后缀为静态库
静态库命名格式:lib + "库名称”+ .a(后缀) 例:libadd.a就是一个叫add的静态库
-D是gcc命令行参数,定义宏,等同于在C或C++程序中#define一个宏。虽然写在Makefile中,跟Makefile没什么关系。需要注意的是该选项只在预处理阶段起作用。
例:C_DEF=-D PASSENGE_MODE
-l是gcc命令行参数,指定连接时期望连接的库的名字,第一个寻找的头文件是inc
例:INCS += -I inc
-L是gcc命令行参数,指定连接库的搜索路径
另: %.o:%.c ,即将所有的.c文件编译为同名的.o文件时,都采用g++ -c $<来进行编译。
来自
https://blog.csdn.net/sssssuuuuu666/article/details/78788369
https://blog.51cto.com/weiguozhihui/1591397
https://www.cnblogs.com/downey-blog/p/10486863.html
https://blog.csdn.net/qlexcel/article/details/51586316