交叉编译linux内核源码-Linux 基础知识。 交叉编译工具链、makefile

1. 十字工具链轮廓

1.什么是交叉工具链? 什么是交叉编译

2.安装交叉工具链方法,结合环境变量PATH和工具链选项

3.Makefile的用法、Makefile的编写规则

4.嵌入式静态库/动态库制作,如何使用库?

2.什么是交叉工具链? 什么是交叉编译

回顾一下编译过程

编译

高级语言(xxxx.c)------>目标程序(xxxx)

编译器:GCC

编译过程:预处理、编译、汇编、链接

gec@ubuntu:~$ which gcc --> gcc编译器本身也是一个linux命令

/usr/bin/gcc

gec@ubuntu:~$ man 1 gcc --> 查询gcc编译器选项及参数使用情况

GCC编译器特点: 在主机A上编译,在主机A上运行 --> GCC编译器也称为本地编译器。

乌班图 乌班图

什么是交叉编译?

无论是本地编译还是交叉编译,都是将高级语言变成目标程序的过程!

所谓交叉编译:在主机A上编译,在主机B上运行 --> 对应的编译器就是交叉编译器,也叫交叉工具链。

Ubuntu开发板

什么是交叉工具链?

纯净版的Linux系统没有交叉工具链,需要用户自行配置。

交叉工具链原材料:arm-2009q3.tar.bz2

3、如何配置交叉工具链?

首先将下载的工具链存放在Linux共享目录中,并切换到共享目录创建跨工具链安装包。

sudo mkdir /usr/arm —> 初始权限受超级用户umask影响

sudo chmod 777 /usr/arm 直接将工具链对应的安装包解压到安装路径。

tar jxvf arm-2009q3.tar.bz2 -C /usr/arm

结果:工具链路径为/usr/arm/arm-2009q3/bin/arm-none-linux-gnueabi-gcc

示例:交叉编译helloworld程序

本地编译命令:gcc umask.c -o umask

结果:

文件掩码:

umask: ELF 32位LSB可执行文件,Intel 80386 --> 该程序的运行平台

,版本 1 (SYSV),

交叉编译命令:/usr/arm/arm-2009q3/bin/arm-none-linux-gnueabi-gcc umask.c -o umask

结果:

文件掩码:

umask: ELF 32位LSB可执行文件,ARM --> 该程序的运行平台

,版本 1 (SYSV)交叉编译linux内核源码

结论: 可执行程序的运行平台由谁来决定?  --> 由编译器决定。

练习1:编写一个helloworld程序并交叉编译它!

练习 2:为工具链指定一个新名称“arm-linux-gcc”

sudo ln -s arm-none-linux-gnueabi-gcc arm-linux-gcc

别名arm-linux-gcc='arm-none-linux-gnueabi-gcc'

练习3:可以在任何时间、任何路径使用交叉工具链“arm-linux-gcc”

思路:如果想在任意路径下使用,方法就是将所在目录添加到PATH中。

arm-linux-gcc /usr/arm/arm-2009q3/bin

	临时修改:export PATH=$PATH:/usr/arm/arm-2009q3/bin 
	永久修改:~/.bashrc

4.工具链版本号/位数/参数选项

查看工具链版本号

gec@ubuntu:~$arm-linux-gcc -v

gcc 版本 4.4.1 (Sourcery G++ Lite 2009q3-67) --> 当前版本 4.4.1

要在64位系统(18.04/16.04)上安装32位工具链,还必须安装32位兼容包

命令: sudo apt-get install libc6:i386

安装完成后,工具链即可正常使用。

常用选项

-E:预处理

-S:编译

-c:组装

-v:查看版本号

-o filename:指定编译后的程序名称

-I include_path:告诉编译器指定头文件的路径

-L lib_path:告诉编译器指定库文件的路径

5.Makefile项目管理文件

makefile 的含义是什么?

Makefile 在项目源代码项目中被称为“项目管理文件”。 makefile内部会有一组用户自定义的规则,makefile执行时会按照makefile的规则进行处理。

什么时候使用makefile? 有必要写makefile吗?

当一个工程有很多文件(.c源程序文件、.h头文件、.so库文件)时,编译命令会变得非常复杂,一般使用makefile来提高编译效率。

makefile 不一定存在于项目源代码中!

项目构成

源程序文件main.c --> 包含main函数的.c文件

函数程序文件 fun.c --> 不包含 main 函数的 .c 文件

头文件head.h --> 函数程序文件function的声明文件

库文件libxxxx.so --> 封装功能程序文件的文件

项目管理文件makefile --> 用于编译整个项目代码的文件

程序写好后,用户可以自行编译:gcc main.c fun.c -o main

任务:学习makefile,让makefile帮我们处理“gcc main.c fun.c -o main”

6.Makefile编写规则

makefile的核心:依赖关系和目标

依赖:一般指.c文件main.c fun.c

Target:最终要获取的文件,一般指可执行程序main

Makefile的编写规则

1)确定“依赖”和“目标”是谁?

2)按照以下格式编写makefile:

Target:依赖(如果有多个依赖,各个依赖文件用空格分隔)

编译规则

注意:

1)。 不等于“四个空格”。 编译规则之所以能运行,是因为Tab键。

2)。 常用变量:

$^:代表相当于“main.c fun.c”的所有依赖项

$@:代表相当于“main”的目标

makefile 的 helloworld 版本

target: --> 依赖文件可以不写,但是target一定要写。

echo “helloworld” --> 用户编写的规则。 当执行make时,就会执行这组规则。

结果:

echo “helloworld” --> 默认情况下,会复制编译规则

你好世界

目标:

@echo “helloworld” --> 在规则后面添加@,结果中不会输出编译命令

结果:

你好世界

练习时间: 写一个makefile,实现编译出main

确定“依赖”和“目标”是谁?

依赖项: main.c fun.c

目标:主要

回答:

主要:main.c fun.c

海湾合作委员会 $^ -o $@

再次执行make

gec@ubuntu:/mnt/hgfs/GZ1917/03 交叉工具链/project$ make

make:“main”是最新的。 --> 如果makefile检测到源程序文件与上次相同,则不会编译!

一个makefile可以有多个目标,make时可以指定执行某个目标的规则。

gec@ubuntu:/mnt/hgfs/GZ1917/03 交叉工具链/project$ make main --> 指定main目标对应的规则。

gec@ubuntu:/mnt/hgfs/GZ1917/03 cross tool chain/project$ make --> 默认执行makefile的第一个目标

例子:

主要:main.c fun.c

海湾合作委员会 $^ -o $@

干净的:

rm 主

当执行“make clean”时,只会执行clean的规则,而忽略main的规则。

7. makefile的变量类型

自定义变量—>默认为字符串类型

规则:

1)只能由数字、字母、下划线组成

2) 区分大小写

3)#=不能出现

4)给出变量参数时,等号两边可以有空格,但是shell编程中给出环境变量参数时,等号两边不能有空格!

5)引用变量时交叉编译linux内核源码,只需在变量后面添加$,或者添加括号将变量括起来。 $A $(A)

6) 赋值中的“”可以省略

例子:

A = 你好相当于 A = “你好”

一个=你好

B=世界

C = $A $(B)

例子:

C_SOURCE=main.c fun.c

主要:$(C_SOURCE)

海湾合作委员会 $^ -o $@

干净的:

rm 主

系统预设变量

有些变量已经在系统中定义了,不需要我们用户再次定义。 常用变量

CC:编译器名称,默认为cc cc相当于gcc

RM:删除内容变量,默认为rm -f

例子:

C_SOURCE=main.c fun.c

CC=arm-linux-gcc

主要:$(C_SOURCE)

$(CC) $^ -o $@

干净的:

$(RM) 主要

自动化变量 --> 变量的值不是固定的,而是变化的!

$^:代表所有依赖

$@:代表目标

8.Makefile指令

假设makefile有一个目标规则:clean:

$(RM) 主要

当我们执行make clean时,就会执行这组规则。 如果当前有一个名为 clean 的文件,

然后执行make clean时会提示:make: `clean' is up to date。

解决方案:在指令中添加 clean 关键字

添加代码:

.PHONY:干净

例子:

.PHONY:干净

干净的:

$(RM) 主要

例子:

C_SOURCE=main.c fun.c

CC=arm-linux-gcc

主要:$(C_SOURCE)

$(CC) $^ -o $@

.PHONY:干净

干净的:

$(RM) 主要

=============================================== Makefile ==== =======================================

1.什么是Makefile

什么是 makefile? 也许很多Winodws程序员不知道这个东西,因为这些Windows IDE已经帮你做了这个工作。

但我认为,要成为一名优秀的专业程序员,还是需要了解makefile。 就好像现在有很多 HTML 编辑器一样。

但如果你想成为专业人士,尤其是在Unix下编译软件时,你就必须编写自己的makefile。

会不会写makefile从一个侧面体现了一个人是否有能力完成小项目。 因为makefile关系到整个项目的编译规则。

项目中的源文件不计算在内。 它们根据类型、功能和模块被放置在几个目录中。 makefile 定义了一系列规则来指定哪些文件需要首先编译。

哪些文件需要后编译,哪些文件需要重新编译,甚至是更复杂的功能操作,因为makefile就像一个Shell脚本。

也可以执行操作系统命令。 makefile的好处是——“自动编译”。 一旦写入,只需要一个make命令。

整个项目完全手动编译,大大提高了软件开发的效率。 Make是一个命令工具,它解释makefile中的指令。

一般来说,大多数IDE都有这个命令,比如Delphi的make、Visual C++的nmake、Linux下GNU的make。 可见makefile已经成为工程中的一种编译方法。

2. 关于程序的编译和链接

在这里,我想多谈谈程序编译的一些规范和技巧。 一般来说,无论是C、C++还是pas,首先都要将源文件编译成中间代码文件。

在Windows下是.obj文件,在UNIX下是.o文件,即Object File。 这个动作称为编译。 然后大量的Object Files被合成为可执行文件。 此操作称为链接。

编译时,编译器需要正确的句型以及正确的函数和变量声明。 对于前者,通常需要告诉编译器头文件的位置(头文件应该只是声明,定义应该放在C/C++文件中),

只要所有句型都正确,编译器就可以编译出中间目标文件。 一般来说,每个源文件应该对应一个中间目标文件(O文件或OBJ文件)。

链接时主要链接函数和全局变量,因此我们可以使用这个中间目标文件(O文件或OBJ文件)来链接我们的应用程序。

链接器不关心函数所在的源文件,只关心函数的中间目标文件(Object File)。 很多时候,因为源文件太多,编译生成的中间目标文件也太多,链接时需要明确强调这一点。 中间目标文件名,

3.Makefile的使用

1)规则,格式如下:

目标:依赖性

状况

Target:是目标file.o文件,也可以是可执行文件。 也可以是标签(Label)

依赖:生成该类目标所需的文件或目标。

条件:即make需要执行的命令。 (任意 shell 命令)

示例如下:

目标:main.c

gcc main.c -o 目标

注意:

如果目标文件比依赖文件新,则不会编译。

如果依赖文件比目标文件新,则编译它

如果目标文件不存在也会编译

2)变量—>v4

自定义变量—>不要将其视为C变量

自动变量

cc —>默认为gcc

$< -->依赖列表中的第一个

$^ -->所有依赖项

$@ -->所有目标,但我们最终的希望是:一个目标,多个依赖! ! ! !

% —》自动匹配,相当于Linux下的键值 * *.c

3)功能

通配符

帕特萨斯特

文件名可以写成makefile或者Makefile

也可以写成其他名称,如:abc —> 编译命令:make -f abc

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 源码编译 交叉编译linux内核源码-Linux 基础知识。 交叉编译工具链、makefile https://www.wkzy.net/game/198294.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务