介绍:
GCC 原名为 GNU C语言编译器,因为它原本只能处理 C 语言,但如今的 GCC 不仅可以编译 C、C++ 和 Objective-C,还可以通过不同的前端模块支持各种语言,包括 Java、Fortran、Ada、Pascal、Go 和 D 语言等等。
编译过程:
GCC的编译过程可以划分为四个阶段:
- 预处理(Pre-Processing)
- 编译(Compiling)
- 汇编(Assembling)
- 链接(Linking)
Linux 程序员可以根据自己的需要控制 GCC 的编译阶段,以便检查或使用编译器在该阶段的输出信息,帮助调试和优化程序。以 C 语言为例,从源文件的编译到可执行文件的运行,整个过程大致如下。
各文件后缀说明:
语法:
gcc [options] file ....
options:
- -pass-exit-codes:从一个阶段以最高错误代码退出
- --target-help:显示特定于目标的命令行选项
- -dumpspecs:显示所有内置规范字符串
- -dumpversion:显示编译器的版本
- -dumpmachine: 显示编译器的的目标处理器
- -print-search-dirs :显示编译器配套库的名称
- -print-file-name= :显示库 的完整路径。
- -print-prog-name= :显示编译器组件 的完整路径。
- -print-multiarch :显示目标的规范化 GNU 三元组,用作库路径中的一个组件。
- -print-multi-directory :显示 libgcc 版本的根目录。
- -print-multi-lib :显示命令行选项和多个库搜索目录之间的映射。
- -print-multi-os-directory :显示操作系统库的相对路径。
- -print-sysroot :显示目标库目录。
- -print-sysroot-headers-suffix :显示用于查找标题的 sysroot 后缀。
- -Wa, :将逗号分隔的 传递给汇编器(assembler)。
- -Wp, :将逗号分隔的 传递给预处理器(preprocessor)。
- -Wl, :将逗号分隔的 传递给链接器(linker)。
- -Xassembler :将 传递给汇编器(assembler)。
- -Xpreprocessor :将 传递给预处理器(preprocessor)。
- -Xlinker :将 传递给链接器(linker)。
- -save-temps :不用删除中间文件。
- -save-temps= :不用删除指定的中间文件。
- -no-canonical-prefixes :在构建其他 gcc 组件的相对前缀时,不要规范化路径
- -pipe :使用管道而不是中间文件。
- -time :为每个子流程的执行计时。
- -specs= :使用 的内容覆盖内置规范。
- -std= :假设输入源为 。
- --sysroot= :使用 作为头文件和库的根目录。
- -B :将 添加到编译器的搜索路径。
- -v :显示编译器调用的程序。
- -E :仅执行预处理(不要编译、汇编或链接)。
- -S :只编译(不汇编或链接)。
- -c :编译和汇编,但不链接。
- -o :指定输出文件
- -pie :创建一个动态链接、位置无关的可执行文件。
- -I :指定头文件的包含路径
- -L :指定链接库的包含路径。
- -shared :创建共享库/动态库。
- -static :使用静态链接。
使用
示例代码
#include <stdio.h>
void foo(void);
int main(void)
{
printf("Hello, GetIoT\n");
foo();
return 0;
}
- gcc 默认输出a.out
gcc hello.c
- 指定输出 文件
gcc hello.c -o hello
- 只执行预处理,输出hello.i的源文件
gcc -E hello.c -o hello.i
- 执行性预处理和编译,输出hello.s汇编文件
gcc -S hello.c #或者 gcc -S hello.i -o hello.s
- 只执行预处理,编译,汇编,输出hello.o目标文件
gcc -c hello.c #或者 gcc -c hello.i 或者 gcc -c hello.s
- 由hello.o -o hello 链接成可只执行文件
gcc hello.o -o hello
- 使用静态库
-
- 分别创建staticFoo.c和shardFoo.c
#include <stdio.h> void foo(void) { printf("Here is a static library\n"); }
#include <stdio.h> void foo(void) { printf("Here is a shard library\n"); }
- 分别创建静态库和动态库
#创建静态库 gcc -c staticFoo.c -o staticFoo.o ar rcs libfoo.a staticFoo.o #ar命令将目标文件打包成一个名为libname.a的静态库文件 #创建动态库 gcc -fPIC -c shardFoo.c #-fPIC选项用于生成位置独立代码,这是创建动态库所需的。 gcc -shard -o libfoo.so shardFoo.o
- 将静态库和动态库分别链接到hello.c
# 动态库链接 gcc hello.c libfoo.so -o shardFoo export LD_LIBRARY_PATH=/usr/lib64/ #或者 gcc hello.c -L. -lfoo -Wl,-rpath=`pwd` -o hello2 rpath 即 run path,是种可以将共享库位置嵌入程序中的方法,从而不用依赖于默认位置和环境变量。这里在链接时使用 -Wl,-rpath=/path/to/yours 选项,-Wl 会发送以逗号分隔的选项到链接器 #或者 sudo cp libfoo.so /usr/lib/ #将llbfoo共享库添加到系统路径
- 分别创建staticFoo.c和shardFoo.c
本文含有隐藏内容,请 开通VIP 后查看