GUN编译器(gcc/g++)- 编译过程

本文详细解释了gcc/g++编译系统的工作原理,包括预编译、编译、汇编和链接四个步骤,以及其在编译过程中的灵活性和功能扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明

gcc test.c -o test
g++ test.cpp -o test
  • 如上,可以很简单的使用一条命令将源码编译成可执行文件,但是实际上编译过程是一个比较复杂的工作,gcc/g++只是编译系统的入口程序,解析用户输入的参数,顺序调用预处理器(cpp)、编译器(ccl/cclplus)、汇编器(as)、链接器(ld),完成以下四个编译过程,生成可执行文件。
  1. 预编译
  2. 编译
  3. 汇编
  4. 链接

编译过程

预编译(Prepressing)

  • 对代码进行预处理(即编译前的处理),执行源码中的预处理指令,例如:文件导入(#include),宏定义展开(#define)等,输出结果是C代码。

编译(Compilation)

  • 将预编译产生的代码文件转化为汇编代码,输出结果是汇编代码。

汇编(Assembly)

  • 将编译产生的汇编代码进行汇编编译,输出的二进制的目标文件.o。

链接(Linking)

  • 将汇编编译产生的.o文件,链接成可执行程序文件(.out)。

使用

灵活

  • 使用gcc/g++编译非常灵活
  1. 可以从源码开始到任何一个步骤停止(-o 可以将输出结果输出到文件),例如:
gcc -E test.c -o test_new.i // -E: 执行完预编译, 输出预编译结果
gcc -S test.c -o test.s    // -S: 执行完编译,输出汇编代码
gcc -c test.c -o test.o    // -c: 执行完汇编,输出目标文件
gcc test.c -o test        // 执行完所有过程,输出可执行文件
  1. 也可以从编译过程的任何一个步骤继续编译,任意一个步骤停止,例如:
* 从预处理开始
gcc -E test.c -o test.i
gcc -S test.i -o test.s  //将预处理后的代码编译成汇编代码
gcc -c test.i -o test.o  //将预处理后的代码编译成目标文件
gcc test.i -o test  //将预处理后的代码编译成可执行文件
* 从汇编开始
gcc -S source_file.c -o source_file.s // 编译成汇编代码 source_file.s
gcc source_file.s -o source_file // 将汇编代码编译成可执行程序
gcc -c source_file.s -o source_file.o  //将汇编代码编译成目标文件(.o) 
* 从目标文件(.o)开始
gcc -c source_file.c -o source_file.o // 编译成目标文件 source_file.o
gcc source_file.o -o source_file // 将目标文件链接成可执行程序

强大

  • gcc/g++不仅仅是一个C/C++编译器,也可以完成汇编器(as)和链接器(ld)的工作。
  • 汇编和链接工作,也可以使用as和ld来实现,但是需要手动加很多参数,使用gcc就简单很多。

汇编器

  1. 将汇编代码编译成可执行程序
gcc source_file.s -o source_file  //将汇编代码,编译成可执行程序,如果汇编代码中没有main函数会提示,可先编译成.o文件
  1. 将汇编代码编译成.o文件
gcc -c source_file.s -o source_file.o //将汇编代码,编译成.o文件

链接器

  1. 链接成可执行程序
gcc source_file.o xxx.o -o source_file  //将.o文件链接成可执行文件,
  • .o 文件可以从.c编译而成,也可以从汇编代码(.s)编译而成。
<think>我们正在讨论如何将交叉编译器切换到gcc-aarch64-linux-gnu。根据引用内容,我们知道gcc-aarch64-linux-gnu是一个用于交叉编译ARMv8 64位目标程序的工具链。下面我将介绍切换交叉编译器的方法。 ### 切换交叉编译器的方法 切换交叉编译器通常涉及修改构建系统的环境变量或配置参数。以下是几种常见的方法: 1. **设置环境变量**:在构建之前,可以通过设置环境变量来指定交叉编译器。例如,在Linux终端中执行: ```bash export CC=aarch64-linux-gnu-gcc export CXX=aarch64-linux-gnu-g++ ``` 这样,后续的构建命令(如`make`)就会使用这些环境变量来调用交叉编译器。 2. **在构建命令中指定**:许多构建系统允许在命令行中直接指定编译器。例如,使用CMake时: ```bash cmake .. -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ ``` 3. **在Makefile中指定**:如果项目使用Makefile,可以在Makefile中直接设置编译器变量。例如: ```makefile CC = aarch64-linux-gnu-gcc CXX = aarch64-linux-gnu-g++ ``` 4. **使用工具链文件(CMake)**:对于复杂的项目,可以创建一个CMake工具链文件,例如`aarch64-toolchain.cmake`,内容如下: ```cmake set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++) ``` 然后在配置项目时指定该工具链文件: ```bash cmake -DCMAKE_TOOLCHAIN_FILE=aarch64-toolchain.cmake .. ``` ### 注意事项 - 确保交叉编译器已正确安装在系统上,并且其路径已包含在`PATH`环境变量中。通常,安装后可以直接使用`aarch64-linux-gnu-gcc`命令。如果遇到问题,可以尝试使用绝对路径。 - 根据引用[4],某些版本的交叉编译器可能存在库支持问题(如不支持较新的glibcxx版本)。如果遇到类似问题,可能需要升级交叉编译器或调整构建选项。 - 在Windows环境下,可以参考引用[5]中的示例,设置`CMAKE_BUILD_WITH_INSTALL_RPATH`等选项以避免路径问题。 ### 示例:编译一个简单的程序 假设有一个简单的C程序`hello.c`,使用交叉编译器编译的命令为: ```bash aarch64-linux-gnu-gcc hello.c -o hello ``` 这将在当前目录下生成一个针对ARMv8架构(aarch64)的可执行文件`hello`。 ### 验证安装 可以通过以下命令检查交叉编译器的版本,以确认安装是否成功: ```bash aarch64-linux-gnu-gcc --version ``` §§相关问题§§ 1. 如何安装gcc-aarch64-linux-gnu交叉编译器? 2. 交叉编译时如何处理依赖库? 3. 如何调试交叉编译的程序? 4. 交叉编译与本地编译的主要区别是什么?</think>### 如何切换交叉编译器gcc-aarch64-linux-gnu 切换交叉编译器的核心是**修改编译工具链的环境变量和构建参数**,以下是具体步骤: #### 1. **设置环境变量** 在编译前通过终端设置环境变量(临时生效): ```bash export CC=aarch64-linux-gnu-gcc export CXX=aarch64-linux-gnu-g++ export LD=aarch64-linux-gnu-ld export AR=aarch64-linux-gnu-ar export STRIP=aarch64-linux-gnu-strip ``` > 这些变量会覆盖默认编译器,使后续编译命令自动使用 ARM 工具链[^2][^3]。 #### 2. **在构建命令中指定编译器** 对于 `make` 或 `cmake` 项目,直接在命令中声明编译器: ```bash # Makefile 项目 make CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ # CMake 项目 cmake .. \ -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \ -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \ -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_SYSTEM_PROCESSOR=aarch64 ``` #### 3. **解决路径问题** 如果工具链不在系统路径中,需指定绝对路径: ```bash # 示例(根据实际安装路径修改) export PATH="/opt/gcc-arm-9.2/bin:$PATH" ``` > 注意:Windows 交叉编译时需使用 `aarch64-none-linux-gnu-gcc.exe` 格式[^5]。 #### 4. **处理依赖库问题** 若出现 `glibcxx` 版本错误(如引用[4]): ```bash # 编译时添加静态链接参数 aarch64-linux-gnu-gcc -static myapp.c -o myapp ``` 或升级工具链到支持所需库的版本。 #### 5. **验证编译器切换** 检查编译器版本和架构: ```bash aarch64-linux-gnu-gcc -v # 输出应包含 Target: aarch64-linux-gnu file my_binary # 应显示 ELF 64-bit LSB ARM aarch64 ``` ### 关键注意事项 1. **主机要求**:必须使用 **64 位主机**安装和运行此工具链[^1][^2] 2. **工具链安装**: ```bash # Ubuntu/Debian sudo apt install gcc-aarch64-linux-gnu ``` 3. **交叉编译库**:依赖库(如 OpenCV)需用相同工具链重新编译[^3] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值