linux源码Makefile详解(完整)

Linux内核是开源软件,它的源代码可以从官方网站或者 GitHub 上获取得到,源代码根据不同的版本被组成不同的目录树,每个目录下都有一个 Makefile 文件,这个 Makefile 文件是内核构建及编译的基石。下面将详细介绍 Linux 内核中的 Makefile 文件。

#### 1. Makefile 工作原理

在 Linux 中,使用 Makefile 进行源码编译是非常常见的。Makefile 的作用就是将需要编译的源文件以一定顺序进行编译,并将编译出的目标文件链接成可运行的二进制程序或者库文件。Makefile 文件格式非常简单,它的主要工作就是对编译生成的目标文件进行处理。

在 Makefile 中,主要包含三个部分:

1. 宏定义:宏定义包含了一系列变量以及元素,比如编译器的路径、编译时的参数、源文件和目标文件的名称等;

2. 目标:目标指代编译的目标文件,目标文件一般包含多个依赖文件和生成规则;

3. 依赖关系:依赖关系是指一个目标文件编译所需要的源文件或者依赖文件。

在 Makefile 的工作流程中,首先会遍历所有的目标文件,对每个目标文件进行源文件的分析,判断源文件是否修改过,如果源文件被修改过,那么就重新编译这个目标文件;如果源文件没有被修改过,那么就不需要重新编译这个目标文件。

#### 2. Linux 内核 Makefile

在 Linux 内核中,Makefile 文件是整个内核源代码编译的基石,它负责整个 Linux 内核的编译工作。在内核的开发者进行开发时,只需要将自己的代码添加到指定的目录中即可,然后在相应的 Makefile 文件中添加对应的编译规则和依赖关系。

Linux 内核的 Makefile 文件包含了多个子 Makefile 文件,每个子 Makefile 负责对应的子目录的编译工作。子 Makefile 文件通常包含了如下几个部分:

```makefile

# 常量和变量定义

TOPDIR := $(shell pwd)

export TOPDIR

# 目标文件声明

targets := vmlinux

# 源文件声明

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

drivers-y := drivers/ sound/ firmware/

net-y := net/

libs-y := lib/

modules-y := $(core-y) $(drivers-y) $(net-y) $(libs-y)

# 编译规则

$(vmlinux): $(head-y) $(init-y) $(core-y) $(net-y) $(libs-y) $(drivers-y) FORCE

$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@

# 依赖关系

$(init-y) $(vmlinux-dirs): prepare scripts FORCE

$(init-y) $(vmlinux-dirs): $(version_h) $(utsrelease_h) $(asm_headers) $(autoconf_h)

$(vmlinux-dirs): $(version_h) $(autoconf_h)

$(vmlinux-dirs): $(header-dirs) $(real-prereqs)

$(core-y): $(headers_install)

```

上面的 Makefile 文件包含了常量和变量定义、目标文件声明、源文件声明、编译规则以及依赖关系等几个部分。其中,常量和变量定义主要用于指定环境变量、编译器、编译过程的选项、源代码路径、输出路径等信息;目标文件声明用于指定要生成的目标文件和目标文件的类型;源文件声明指定了内核的源代码路径和模块,同时也指定了对应的编译规则和依赖关系。

在内核的编译过程中,依次编译每个子目录下的 Makefile 文件,然后进行链接,最终生成内核镜像文件和各个模块的 .ko 文件。

#### 3. Linux 内核 Makefile 的使用方法

要使用 Linux 内核的 Makefile 进行编译,需要先安装好相应的编译工具链和依赖库。在 Ubuntu 系统上,可以使用如下命令进行安装:

```bash

sudo apt-get install build-essential kernel-package libncurses5-dev

```

在安装完成编译工具链和依赖库之后,就可以开始进行内核的编译工作了。进入到内核源码目录下,可以使用如下命令进行编译:

```bash

make [OPTIONS]

```

其中, 可以是内核镜像文件 vmlinux、bzImage,也可以是其他的目标文件;[OPTIONS] 是可选的编译选项,可以指定内核版本号、编译工具链、调试信息、指定目标 CPU 等选项。

如果需要编译成为 RPM 包,可以使用如下命令:

```bash

make rpm

```

在编译完成之后,可以使用如下命令进行内核的安装:

```bash

make modules_install install

```

这个命令会将编译好的内核模块和内核镜像文件安装到系统的默认路径下,同时也会自动更新 boot loader 等必要的配置信息。

#### 4. Linux 内核 Makefile 的案例说明

下面我们以一个具体的案例来说明 Linux 内核的 Makefile。该案例将定义如下几个目标:

- all:编译整个内核;

- clean:清除编译生成的中间文件和目标文件;

- install:安装内核;

```makefile

# 定义内核镜像文件名

IMAGE_NAME ?= vmlinuz

# 常量定义

KERNEL_VERSION := $(shell uname -r)

SYSTEM_MAP := System.map-$(KERNEL_VERSION)

USR_SRC := /usr/src/linux-$(KERNEL_VERSION)

obj-m := simple.o

# all 选项的编译规则

all:

make -C $(USR_SRC) M=$(shell pwd) modules

$(CC) -o simple simple.c

# clean 选项的编译规则

clean:

make -C $(USR_SRC) M=$(shell pwd) clean

rm -f simple

# install 选项的编译规则

install:

install -m 644 $(IMAGE_NAME) /boot

install -m 644 $(SYSTEM_MAP) /boot

/sbin/depmod -a $(KERNEL_VERSION)

```

上述案例中,首先定义了一些常量,比如内核版本号、内核镜像文件名、内核源代码路径等。然后针对 all、clean、install 三个选项分别定义了编译规则,通过 make 命令来执行对应的编译规则。在 all 选项的编译规则中,使用 make 命令和 -C 选项来进入内核源代码目录进行编译,使用 obj-m 宏定义来引用本模块的源码文件。在 clean 选项的编译规则中,使用 make 命令和 -C 选项来进入内核源代码目录进行清理。在 install 选项的编译规则中,使用 install 命令来将编译出的内核镜像文件和 System.map 文件安装到 /boot 目录下,并使用 depmod 命令将内核模块的依赖关系加入到模块数据库中,以供系统加载时使用。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.37seo.cn/

点赞(72) 打赏

评论列表 共有 2 条评论

浮梦儿 12月前 回复TA

生活有起有落,有顺有逆,愿我们,逆风可独立,迎风可悦喜。

滚你的爱情! 1年前 回复TA

所谓的幸运,就是当你准备好了的时候,机会来了。

立即
投稿
发表
评论
返回
顶部