一、引言
这篇博客主要介绍openEuler中GCC和make的使用。
二、GCC
1.GCC简介
GCC(GNU Compiler Collection)是GNU推出的功能强大、性能优越的多平台编译器。GCC编译器能将C、C++语言源程序、汇编程序和目标程序编译、链接成可执行文件。openEuler操作系统中已默认安装了GCC软件包。
2.GCC编译流程
使用GCC将源代码文件生成可执行文件,需要经过预处理、编译、汇编和链接。
- 预处理:将源程序(如 .c 文件)预处理,生成 .i 文件。
- 编译:将预处理后的 .i 文件编译成为汇编语言,生成 .s 文件。
- 汇编:将汇编语言文件经过汇编,生成目标文件 .o 文件。
- 链接:将各个模块的 .o 文件链接起来生成一个可执行程序文件。
3.一个例子
1.编写Hello World程序,保存为helloworld.c
2.在代码目录,执行编译,使用命令:
gcc helloworld.c -o helloworld
3.编译完成后,会生成helloworld可执行文件,运行:
./helloworld
三、make
1.make简介
GNU make实用程序(通常缩写为make)是一种用于控制从源文件生成可执行文件的工具。 make会自动确定复杂程序的哪些部分已更改并需要重新编译。 make使用称为Makefiles的配置文件来控制程序的构建方式。
2.make工作流程
使用make由源代码文件生成可执行文件,需要经过如下步骤。
- make命令会读入Makefile文件,包括当前目录下命名为"GNUmakefile" 、“makefile” 、"Makefile"的文件、被include的makefile文件、参数-f、–file、–makefile指定的规则文件。
- 初始化变量。
- 推导隐含规则,分析依赖关系,并创建依赖关系链。
- 根据依赖关系链,决定哪些目标需要重新生成。
- 执行生成命令,最终输出终极文件。
3.Makefile
make是通过Makefile文件获取如何编译、链接和安装、清理的方法,从而实现将源代码文件生成可执行文件和其他相关文件的工具。因此,Makefile中描述了整个工程的编译和链接等规则,其中包含了哪些文件需要编译,哪些文件不需要编译,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重建等等。Makefile文件让工程编译实现了自动化,不需要每次都手动输入一堆源文件和参数。
Makefile结构
Makefile文件结构如下所示:
targets:prereguisites
command
或者是:
targets:prerequisites;command
command
其中:
targets :目标,可以是目标文件、可执行文件或标签。
prerequisites :依赖文件,生成targets需要的文件或者是目标。可以是多个,也可以没有。
command :make需要执行的命令(任意的 shell 命令)。可以有多条命令,每一条命令占一行。
目标和依赖文件之间要使用“:”分隔,命令的开始一定要按“Tab”。
Makefile文件结构表明了输出的目标,输出目标的依赖对象和生成目标需要执行的命令。
4.一个例子
1.创建1个头文件hello.h和2个函数hello.c、main.c。
vi hello.h
vi hello.c
vi main.c
2.编写代码内容
hello.h:
#pragma once
#include <stdio.h>
void hello();
hello.c:
#include "hello.h"
void hello()
{
int i=1;
while(i<5)
{
printf("The %dth say hello.\n", i);
i++;
}
}
main.c:
#include "hello.h"
#include <stdio.h>
int main()
{
hello();
return 0;
}
3.创建Makefile文件
vi Makefile
Makefile文件内容示例:
main:main.o hello.o
gcc -o main main.o hello.o
main.o:main.c
gcc -c main.c
hello.o:hello.c
gcc -c hello.c
clean:
rm -f hello.o main.o main
-1.
main:main.o hello.o
:这是一个规则,指定了如何生成名为main
的可执行文件。它依赖于两个对象文件main.o
和hello.o
。
2.gcc -o main main.o hello.o
: 这是上述规则的命令部分,当make工具发现main
这个目标需要被构建时,它会执行这个命令。这里使用gcc
编译器来链接main.o
和hello.o
两个对象文件,并输出一个名为main
的可执行文件。
3.main.o:main.c
: 这是另一个规则,指定了如何生成main.o
对象文件。它依赖于源文件main.c
。
4.gcc -c main.c
:这是上述规则的命令部分,当make工具发现main.o
需要被构建时,它会执行这个命令。这里使用gcc
编译器的-c
选项来编译main.c
源文件,生成main.o
对象文件。
5.hello.o:hello.c
: 这是第三个规则,指定了如何生成hello.o
对象文件。它依赖于源文件hello.c
。
6.gcc -c hello.c
: 这是上述规则的命令部分,当make工具发现hello.o
需要被构建时,它会执行这个命令。这里使用gcc
编译器的-c
选项来编译hello.c
源文件,生成hello.o
对象文件。
7.clean:
:这是一个名为clean
的伪目标,它不依赖于任何文件,而是一个特殊的目标,用于执行清理操作。
8.rm -f hello.o main.o main
:这是clean
目标的命令部分,当执行make clean
时,make工具会执行这个命令。这里使用rm
命令来删除hello.o
、main.o
和main
文件,以便清理编译生成的文件。
4.执行make命令。
命令执行后,会打印Makefile中执行的命令。如果不需要打印该信息,可以在执行make命令时加上参数-s。
5.执行./main目标。
./main
参考:https://docs.openeuler.org/zh/docs/24.03_LTS/docs/ApplicationDev/