介绍
最初的GNU C 编译器(GCC) 是由GNU 项目的创始人 Richard Stallman 开发的。理查德·斯托曼 (Richard Stallman) 于 1984 年创立了 GNU 项目,旨在创建一个完整的类 Unix 操作系统作为自由软件,以促进计算机用户和程序员之间的自由与合作。
GCC,前身为“ GNU C Compiler ”,随着时间的推移不断发展壮大以支持多种语言,例如 C ( gcc)、C++ ( g++)、Objective-C、Objective-C++、Java ( gcj)、Fortran ( gfortran)、Ada ( gnat)、Go ( gccgo)、OpenMP、Cilk Plus 和 OpenAcc。它现在被称为“ GNU 编译器集合”。GCC 的母站点是http://gcc.gnu.org/。
GCC 是所谓的“ GNU 工具链”的关键组件,用于开发应用程序和编写操作系统。
GNU 工具链
- GNU Compiler Collection (GCC):一个支持多种语言的编译器套件,例如 C/C++ 和 Objective-C/C++。
- GNU Make:用于编译和构建应用程序的自动化工具。
- GNU Binutils:一套二进制实用工具,包括链接器和汇编器。
- GNU 调试器 (GDB)。
- GNU Autotools:一个包含 Autoconf、Autoheader、Automake 和 Libtool 的构建系统。
- GNU Bison:一个解析器生成器(类似于 lex 和 yacc)。
GCC 是可移植的,可以在许多操作平台上运行。GCC(和 GNU 工具链)目前可在所有 Unix 上使用。它们也被移植到 Windows(通过 Cygwin、MinGW 和 MinGW-W64)。GCC 也是一个交叉编译器,用于在不同平台上生成可执行文件。
gcc使用教程
查看使用说明
gcc --help
man gcc # linux
编译过程
gcc常用参数
-std=<standard> Assume that the input sources are for <standard>.
-B <directory> Add <directory> to the compiler's search paths.
-v Display the programs invoked by the compiler.
-E Preprocess only; do not compile, assemble or link.
-S Compile only; do not assemble or link.
-c Compile and assemble, but do not link.
-o <file> Place the output into <file>.
-shared Create a shared library.
- 预处理
gcc -E hello.c -o hello.i
- 编译
gcc -S hello.i -o hello.s
- 汇编
as hello.s -o hello.o
- 链接
ld -o hello.exe hello.o ...libraries... # library太长
常用方式
例如多文件下的工程
hello.c:
#include <stdio.h>
#include "doAdd.h"
int main()
{
int result = 0;
printf("using doAdd()\n");
result = doAdd(1,1,10);
printf("result=%d", result);
return 0;
}
doAdd.h:
#ifndef __doAdd__
#define __doAdd__
int doAdd(int a, int b, int c);
#endif
doAdd.c:
#include "doAdd.h"
int doAdd(int a, int b, int c)
{
int i, sum = 0;
for(i = a; i < c; i = i+b)
{
sum = sum + i;
}
return sum;
}
一
- 把.c的文件都预处理、编译和汇编,不进行链接
gcc -c hello.c -o hello.o
gcc -c doAdd.c -o doAdd.o
- 链接
gcc hello.o doAdd.o -o hello.exe
二
gcc hello.c doAdd.c -o hello.exe
makefile
在大型项目,使用makefile时,编译更方便,不仅可以按照你的规则编译,而且在命令行敲命令也变得简单!
格式
target: pre-req-1 pre-req-2 …
[Tab] command1
[Tab] command2
创建以下名为“makefile”(没有任何文件扩展名)的文件,其中包含构建可执行文件的规则,并保存在与源文件相同的目录中。使用“tab”来缩进命令(不是空格)。
例子
就刚才的例子写一个makefile如下:
all: hello.exe
hello.exe: hello.o doAdd.o
gcc hello.o doAdd.o -o hello.exe
hello.o: hello.c
gcc -c hello.c -o hello.o
doAdd.o: doAdd.c
gcc -c doAdd.c -o doAdd.o
.PHONY : clean # 说明clean不是一个文件,是一个伪指令
clean:
del *.o # linux下换成rm *.o
在上面的例子中,规则“ all”有一个先决条件“ hello.exe”。make找不到文件“ hello.exe”,所以它寻找一个规则来创建它。规则“ hello.exe”有两个先决条件“ hello.o”,“doAdd.o”。同样,它们不存在,所以make寻找一个规则来创建它。规则“ hello.o”有一个先决条件“ hello.c”。make检查“ hello.c”是否存在并且它比目标(不存在)更新。它运行命令“ gcc -c hello.c -o hello.o”和“gcc -c doAdd.c -o doAdd.o”生成hello.o和doAdd.o,到了规则“ hello.exe”会运行它的命令“ gcc hello.o doAdd.o -o hello.exe”。最后,规则“ all”什么都不做。
更重要的是,如果先决条件不比目标新(文件生成日期),则不会运行该命令。换句话说,只有当目标与其先决条件相比已过时,该命令才会运行。
build
make all
清除编译过程生成的文件
make clean
自动变量
匹配规则后,由 make 设置自动变量。其中包括:
$@: 目标文件名。
$*: 不带文件扩展名的目标文件名。
$<: 第一个先决条件文件名。
$^: 所有先决条件的文件名,以空格分隔,丢弃重复项。
$+: 类似于$^,但包括重复项。
$?: 比目标更新的所有先决条件的名称,以空格分隔。
all: hello.exe
# $@ 匹配目标;$< 匹配第一个依赖的(先决条件)
hello.exe: hello.o
gcc -o $@ $< # 或者 gcc -o hello.exe hello.o
hello.o: hello.c
gcc -c $< # 或者 gcc -c hello.c
clean:
rm hello.o hello.exe
隐式模式规则
Make 附带了大量的隐式模式规则。您可以通过以下命令参考规则。
make --print-data-base
# 或者
make -p
当文件过多少,我们就要使用隐式模式规则来快速编写Makefile
其他
GDB调试教程
https://blog.youkuaiyun.com/zhaobryant/article/details/51038896