嵌入式linux驱动之路02:linux c编程基础

嵌入式linux驱动之路02:linux c编程基础
Ubuntu 下也有一些可以进行编程的工具,但是大多都只是编辑器,也就是只能进行代码编辑,如果要编译的话就需要用到 GCC 编译器,使用 GCC 编译器肯定就要接触到 Makefile。所以我们就要了解如何在 Ubuntu 下进行 C 语言的编辑和编译、GCC 和 Makefile的使用和编写。

编写入门

我们所说的编写代码包括两部分:代码编写和编译,在 Linux下这两部分是分开的,比如我们用 VIM 进行代码编写,编写完成以后再使用 GCC 编译器进行编译。Ubuntu 自带的 GCC 编译器是针对 X86 架构的,因此只能编译在 X86 架构 CPU 上运行的程序。如果想要编译在 ARM上运行的程序就需要针对 ARM 的 GCC 编译器,也就是交叉编译器!我们是 ARM 开发,因此肯定要安装针对 ARM 架构的 GCC 交叉编译器,不同的目标架构,其 GCC 编译器是不同的。
输入如下命令:
gcc main.c
上述命令的功能就是使用 gcc 编译器来编译 main.c 这个 c 文件。编译完成以后会生成一个 main.out 文件,这个 main.out 就是编译生成
的可执行文件,执行此文件看看是否和我们代码的功能一样,执行的方法很简单使用命令:“./+可执行文件”.在使用 gcc 命令的时候加上-o 来指定生成的可执行文件名字。

GCC 编译器

gcc 命令

gcc 命令格式如下:
gcc [选项] [文件名字]
主要选项如下:
-c:只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
-o:<输出文件名>用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默认编译出来的可执行文件名字为 *.out。
-O:对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进行优化,这样产生的可执行文件执行效率就高。

gcc 编译流程

GCC 编译器的编译流程是:预处理、编译、汇编和链接。预处理就是展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中。编译是将经过预编译处理的代码编译成汇编代码,也就是我们常说的程序编译。汇编就是将汇编语言文件编译成二进制目标文件。链接就是将汇编出来的多个二进制目标文件链接在一起,形成最终的可执行文件。

Makefile 基础

如果我们的工程只有一两个 C 文件还好,需要输入的命令不多,使用 GCC 编译器在 Linux 进行 C 语言编译,通过在终端执行 gcc 命令来完成 C 文件的编译。
在终端输入如下命令:
gcc main.c calcu.c input.c -o main
上面命令的意思就是使用 gcc 编译器对 main.c、calcu.c 和 input.c 这三个文件进行编译,编译生成的可执行文件叫做 main。编译完成以后执行 。/main 。
这个程序当文件有几十、上百甚至上万个的时候用终端输入 GCC 命令的方法显然是不现实的。如果我们能够编写一个文件,这个文件描述了编译哪些源码文件、如何编译那就好了,每次需要编译工程的时只需要使用这个文件就行了。为此提出了一个解决大工程编译的工具:make,描述哪些文件需要编译、哪些需要重新编译的文件就叫做 Makefile,Makefile 就跟脚本文件一样,Makefile 里面还可以执行系统命令。使用的时候只需要一个 make,命令即可完成整个工程的自动编译。make 命令会在当前目录下查找是否存在“Makefile”这个文件,如果存在的话就会按照 Makefile 里面定义的编译方式进行编译

Makefile 引入

如果有一个文件被修改了以,使用上面的命令编译的时候所有的文件都会重新编译,如果工程有几万个文件(Linux 源码就有这么多文件!),最好的办法肯定是哪个文件被修改了,只编译这个被修改的文件即可,其它没有修改的文件就不需要再次重新编译了。为此我们需要这样一个工具:
1、如果工程没有编译过,那么工程中的所有.c 文件都要被编译并且链接成可执行程序。
2、如果工程中只有个别 C 文件被修改了,那么只编译这些被修改的 C 文件即可。
3、如果工程的头文件被修改了,那么我们需要编译所有引用这个头文件的 C 文件,并且链接成可执行文件。

Makefile 语法

代码如下:
1 main: main.o input.o calcu.o
2 gcc -o main main.o input.o calcu.o
3 main.o: main.c
4 gcc -c main.c
5 input.o: input.c
6 gcc -c input.c
7 calcu.o: calcu.c
8 gcc -c calcu.c
9
10 clean:
11 rm *.o
12 rm main
首先更新第一条规则中的 main,第一条规则的目标成为默认目标,只要默认目标更新了那么就认为 Makefile 的工作。在第一次编译的时候由于 main 还不存在,因此第一条规则会执行,第一条规则依赖于文件 main.o、input.o 和 calcu.o 这个三个.o 文件,这三个.o 文件目前还都没有,因此必须先更新这三个文件。make 会查找以这三个.o 文件为目标的规则并执行。以 main.o为例,发现更新 main.o 的是第二条规则,因此会执行第二条规则,第二条规则里面的命令为“gcc–c main.c”,这行命令很熟悉了吧,就是不链接编译 main.c,生成 main.o,其它两个.o 文件同理。
最后一个规则目标是 clean,它没有依赖文件,因此会默认为依赖文件都是最新的,所以其对应的命令不会执行,当我们想要执行 clean 的话可以直接使用命令“make clean”,执行以后就会删除当前目录下所有的.o 文件以及 main,因此 clean 的功能就是完成工程的清理。
总结一下 Make 的执行过程:
1、make 命令会在当前目录下查找以 Makefile(makefile 其实也可以)命名的文件。
2、当找到 Makefile 文件以后就会按照 Makefile 中定义的规则去编译生成最终的目标文件。
3、当发现目标文件不存在,或者目标所依赖的文件比目标文件新(也就是最后修改时间比目标文件晚)的话就会执行后面的命令来更新目标。
这就是 make 的执行过程,make 工具就是在 Makefile 中一层一层的查找依赖关系,并执行相应的命令。编译出最终的可执行文件。

Makefile 变量

Makefile 加入了变量支持。
#Makefile 变量的使用
2 objects = main.o input.o calcu.o
3 main: $(objects)
4 gcc -o main ( o b j e c t s ) M a k e f i l e 中变量的引用方法是“ (objects) Makefile 中变量的引用方法是“ (objects)Makefile中变量的引用方法是(变量名)”,比如本例中的“$(objects)”就是使用变量 objects。变量的真实值取决于它所引用的变量的最后一次有效值。
此外赋值符“:=”不会使用后面定义的变量,只能使用前面已经定义好的。
“?=”如果前面已经赋过值了,那么就使用前面赋的值。
Makefile 中的变量是字符串,有时候我们需要给前面已经定义好的变量添加一些字符串进去,此时就要使用到符号“+=”
自动化变量中,常用的三种:
$@:规则中的目标集合,
$<:依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么就是符合模式的一系列的文件集合。
$^:所有依赖文件的集合.
Makefile 有一种特殊的目标——伪目标,使用伪目标主要是为了避免 Makefile 中定义的执行命令的目标和工作目录下的实际文件出现名字冲突,有时候我们需要编写一个规则用来执行一些命令,但是这个规则不是用来创建文件的.如:在工作目录下创建一个名为“clean”的文件,当执行“make clean”的时候,规则因为没有依赖文件,所以目标被认为是最新的,因此后面的 rm 命令也就不会执行。。为了避免这个问题,我们可以将 clean 声明为伪目标,声明方式如下:
.PHONY : clean

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值