编译工具链gcc:
gcc是GNU Compiler Collection的简写,是一款被广泛使用的c语言编译工具。
还有Clang等编译工具
一、gcc的一般流程:
Linux下的ELF文件、链接、加载与库(含大量图文解析及例程)_elf文件的动态链接库与静态链接库-CSDN博客
首先需要了解源代码的编译这个复杂的过程。编译的过程实际上是把高级语言转换为低级语言的过程,编译和汇编是他的核心步骤,对计算机有一定了解的朋友想必都能很顺利的理解这一点。但是出于具体工程的兼容性和复用性的需要,还需要额外具有预处理和链接这两个额外的步骤。
下面稍微介绍一下为什么需要进行预处理和链接。在实际使用中,一段源码为了支持不同的平台上,不同的设备需要设置一定的宏变量以描述在对应的平台上具有的软件或硬件的特性。对于不同的特性应该进行的不同的操作,这就是选择性编译和编译控制。通过这种方法我们保证了代码的兼容性。
除此以外,在复杂的工程中经常充斥着对一段基础性代码的反复调用。为了提高可用性和效率,我们并不是每次使用都编译他们,而是将他们都提前编译好形成一个二进制文件。在每次编译文件时需要调用这个函数的时候,编译器会预先挖好空,等到链接阶段的时候直接链接到这个二进制文件去执行。一般的,大量的提前编译好的文件被打包归档成为一个库文件(lib, library)。库文件分为动态库和静态库,他们的实现之间有着一定的不同,相关的知识可以参见链接。【C++】静态库和动态库文件的生成和使用_c++ .a文件-CSDN博客
总而言之,编译一段源码的过程是:
-
预处理(Preprocessing):.c->.i 处理包含、宏定义(#标识)
gcc -e xxx.c -o yyy.i -
编译(Compilation):.i->.s 转换到特定汇编代码(不是机器码,取决于指令集)
gcc -s xxx.i -o yyy.s -
汇编(Assemble):.s->.o 转换到机器码(但并不是实际执行的代码)
gcc -c xxx.s -o yyy.o -
链接(Linking):.o->可执行文件(.exe或者.elf)
目标文件.o和其他文件、库文件、启动文件链接起来
gcc [无] xxx.o -o yyy -l zzz.a -
一般来说,使用gcc直接从.c文件编译到可执行文件
gcc [-选项] [目标文件],一般的缩写为:gcc xxx.c -o yyy
这个过程中具有的文件类型有:
-
源文件.c、头文件.h;
-
预处理得到的.i 预处理文件;
-
编译得到的.s 汇编文件;
-
汇编得到.o(可重定向)目标文件;
-
链接得到.out 或 .elf 可执行(目标)文件。
-
静态库文件.a实质上就是预先编译、汇编好的.o目标文件的集合。在运行前加载到代码段当中。
-
动态库文件.so又叫共享目标文件,在运行时加载到内存的共享库段

二、交叉编译
三、编译的头文件、库文件路径优先级:
gcc路径搜索是具有优先级的
- LD_PRELOAD环境变量 LD_PRELOAD 环境变量允许你指定一个或多个共享库,这些共享库会在程序启动时被优先加载,覆盖掉原有的同名库。
export LD_PRELOAD=/path/to/my/preload/lib.so
- gcc编译选项:
可以直接在编译命令中使用 -I 参数指定头文件目录,或使用 -L 参数指定链接时库文件路径(作用于gcc/g++),-Wl,-rpath 参数指定执行时库路径(作用于ld.so,-wl表示后面的参数传递给链接器)。当指定多个动态库搜索路径时,路径之间用冒号:分隔。
gcc -I/path/to/headers -L/path/to/libs myprogram.c -Wl,-rpath=path/to/libs -o myprogram
- 通过.c文件的参数设置路径:
还可以使用环境变量来扩展搜索路径。需要注意的是这种方法添加的搜索路径是临时的,仅在当前终端有效。
C_INCLUDE_PATH:
通过设置环境变量来添加自定义的头文件目录。
export C_INCLUDE_PATH=/path/to/your/custom/headers
CPLUS_INCLUDE_PATH:
类似于 C_INCLUDE_PATH,但适用于 C++。
export CPLUS_INCLUDE_PATH=/path/to/your/custom/headers
LIBRARY_PATH:
用于指定库文件(主要是静态链接库)的搜索路径。如果你的程序依赖于自定义库,可以将库文件路径添加到此环境变量中。在链接时起效。
export LIBRARY_PATH=/path/to/your/custom/libs
LD_LIBRARY_PATH:
用于指定库文件(动态链接库)的搜索路径。如果你的程序依赖于自定义库,可以将动态库路径添加到此环境变量中。在运行时起效。
export LD_LIBRARY_PATH=/path/to/your/custom/libs
- 配置文件指定的库路径
配置文件/etc/ld.so.conf中指定的动态库搜索路径。这是一个系统级别的更改,通常需要运行ldconfig命令来更新系统的库缓存,使新添加的路径生效。
- 系统默认搜索路径:
gcc 默认会搜索一些标准的系统头文件和库文件路径。
例如库文件路径是:/lib、/usr/lib、/lib64、/usr/lib64。/usr/local/lib和/usr/local/lib64一般存放用户自定义的库,一般不在标准的搜索路径之中。同样的也有/include、/usr/local/include等设置头文件搜索路径的