前言:在嵌入式课程中会学到使用Linux下的GCC来编译C语言的方法,本文基于 Ubuntu 18.04 展示如何使用GCC以及编写基础Makefile文件。

一. 安装准备

首先打开命令行,使用sudo权限身份

第一步:更新包列表

1
sudo apt update

第二步:安装 build-essential 软件包(包括了gcc / g++ / make)

1
sudo apt install build-essential

第三步:查看是否安装完成

1
gcc --version

二. 使用GCC编译C语言

例如,我先用vim编写一个 test.c 的c语言程序,然后可以使用下列命令。

1. 一步到位的编译

1
2
3
4
# 编译
gcc test.c -o test
# 执行
./test

上面的编译命令中,其实包含了四个阶段:预编译、编译、汇编、连接

2.1 预编译

1
gcc -E test.c -o test.i

2.2 编译

1
2
# 编译为汇编代码
gcc -S test.i -o test.s

2.3 汇编

1
gcc -c test.s -o test.o

2.4 连接

1
2
# 负责将程序目标文件和所需的目标文件连接起来
gcc test.o -o test

三. Makefile编写

目的:可以方便地编译多个源代码

实战:编写一个Makefile来编译整个文件夹的内容

第一步:首先,在 /home/test/calc 下创建三个c语言文件,分别是:

add.c

1
2
3
4
5
#include <stdio.h>
int add(int a, int b){
int ans = a + b;
return ans;
}

sub.c

1
2
3
4
5
#include <stdio.h>
int sub(int a, int b){
int ans = a - b;
return ans;
}

main.c

1
2
3
4
5
6
7
8
#include <stdio.h>
#include "add.c"
#include "sub.c"
int main(){
printf("the answer of 2+3: %d\n",add(2, 3));
printf("the answer of 5-1: %d\n",sub(5, 1));
return 0;
}

第二步:创建目录 /home/test/obj 来保存中间文件,创建目录 /home/test/elf 来保存可执行文件。

第三步:在 /home/test 下编写Makefile:

注意,文件名应该是 Makefilemakefile ,这样在该目录下执行make命令时系统会自动寻找。

1
2
3
4
5
# 切换目录
cd /home/test

# 创建Makefile
vim makefile

makefile 内容:

1
2
3
4
5
6
7
8
9
10
11
12
# 这是在makefile中的注释
main : main.o
gcc obj/main.o -o elf/main
main.o : main.s
gcc -c obj/main.s -o obj/main.o
main.s : main.i
gcc -S obj/main.i -o obj/main.s
main.i : calc/main.c
# echo中的内容会在make时输出
@echo "This file was written by BA_NANA."
@echo "My Website is 515code.com."
gcc -E calc/main.c -o obj/main.i

说明:我们从上往下读这个makefile文件,首先基本格式如下:

1
2
生成的文件名 : 依赖的文件
gcc语句

根据上述makefile,想要得到main这个可执行文件,就要依赖于main.o,那么就会往下寻找main.o的生成方法及依赖,以此类推。

最后在 /home/test 下执行make命令(注意要sudo),结果如下:

同时,/home/test/obj 目录下则保存了gcc编译过程的中间文件,可以打开看看是啥。

四. 结尾

在本篇文章中,我们学习了GCC编译的四个阶段及相应命令,并且实现了一个简单的Makefile。若想深入学习Makefile,可以参考 https://seisman.github.io/how-to-write-makefile/introduction.html