编译器

 

参考

llvm/clang

安装

windows

在windows下配置Clang编译器

linux

  • 命令安装
sudo apt install llvm clang
  • 源码安装
sudo wget https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-15.0.7.tar.gz
sudo tar xvf llvm-project-llvmorg-15.0.7

sudo mkdir -p /usr/local/llvm
sudo cmake -S . -B build -G "Unix Makefiles" -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE="Release" -DLLVM_INCLUDE_TESTS=OFF -DCMAKE_INSTALL_PREFIX="/usr/local/llvm"
sudo cmake --build build -j ${nproc}
sudo cmake --install build

使用

基础命令

基本和gcc相同

gcc/g++

安装

交叉编译

# 32位
sudo apt install -y arm-linux-gnueabihf-g++

# 64位
sudo apt install -y g++-aarch64-linux-gnu

编译

-E

仅进行预处理操作

gcc main.c -E -o main.i

-I

添加头文件搜索路径

g++ -I 头文件目录 源文件 -o 可执行文件
  • 示例, 在/path/include路径下搜索头文件
g++ -I /path/include ...

-D

条件编译, 通过-D宏=值指定对应宏值

  • 示例, 仅编译YES宏包含部分
#include <stdio.h>

int main() {
    #if YES
        printf("OK\n");
    #endif
    printf("Hello World\n");
    return 0;
}

-S

将预处理文件生成汇编文件

gcc main.i -S -o main.s

-c

将汇编文件生成目标文件

gcc main.s -c -o main.o

-L

添加库文件搜索路径

g++ -L 库文件路径 源文件 -o 可执行文件
  • 示例, 添加/path/to/lib搜索路径
g++ -L /path/to/lib source.cpp -o executable

-shared

创建动态库

g++ 源文件 -fPIC -shared -o 库文件
  • 示例, 生成main.so
g++ main.c -fPIC -shared -o main.so

-o

直接生成可执行文件

g++ main.c -o main

-static

禁用动态库, 避免依赖问题, 但编译出程序较大

g++ -static main.c -o main

提示

警告

-w

忽略所有警告

-Werror

不区分警告和错误, 遇到任何警告都停止编译

-Wall

对代码所有可能有问题地方发出警告

-Wshadow

作用域相关存在变量同名时发出告警

-Wextra

对所有合法但值得怀疑表达式发出告警

调试

gdb 程序

run

运行程序遇到断点后停止运行, 等待输入下一步命令

continue

继续执行到下一个断点处(或运行结束)

next

单步跟踪程序, 遇到函数调用时, 直接调用, 不进入函数

step

单步调试, 遇到有函数调用, 进入函数运行

until

运行程序直到退出循环体

until+行号

运行至某行, 不仅仅用来跳出循环

finish

运行程序, 直到当前函数完成返回, 并打印函数返回时堆栈地址和返回值及参数值等信息

call 函数(参数)

调用程序中可见函数, 并传递参数, 如: call gdb_test(55)

quit

退出gdb

break

在第n行处设置断点

break func

在函数func()入口处设置断点

delete n

删除第n个断点

disable n

暂停第n个断点

enable n

开启第n个断点

clear n

清除第n行断点

info breakpoints

显示当前程序断点设置情况

delete breakpoints

清除所有断点

list

列出程序源代码, 默认每次显示10行

  • list 行号

将显示当前文件以”行号”为中心前后10行代码, 如: list 12

  • list 函数名

将显示函数源代码

  • list : 不带参数

将接着上一次 list 命令输出下边内容

print

print 表达式

表达式可以是任何当前正在被测试程序的有效表达式, 如当前正在调试C语言程序, 那么”表达式”可以是任何C语言有效表达式, 包括数字, 变量甚至是函数调用

  • print 数字a

将显示数字a值

  • print ++a

a 值加1显示

  • print name

显示字符串name值

  • print gdb_test(22)

将以整数22作为参数调用 gdb_test() 函数

  • print gdb_test(a)

将以变量 a 作为参数调用 gdb_test() 函数

display

在单步运行时将非常有用, 使用display命令设置一个表达式后, 它将在每次单步进行指令后, 紧接着输出被设置的表达式及值. 如: display a

watch

设置监视点, 一旦被监视表达式值改变, gdb将强行终止正在被调试程序. 如: watch a

whatis

查询变量或函数

info function

查询函数

源码构建

安装依赖

sudo apt update
sudo apt install build-essential flex bison gawk texinfo gmp libmpfr-dev libmpc-dev libisl-dev

下载源码

下载 GCC、Binutils 和 Glibc源码

GCCGNU 编译器集合, 提供g++ 编译器

Binutils提供链接器和汇编器

Glibc提供 C 标准库

# 下载 GCC 源码
wget https://ftp.gnu.org/gnu/gcc/gcc-12.2.0/gcc-12.2.0.tar.gz
tar -xvzf gcc-12.2.0.tar.gz
cd gcc-12.2.0

# 下载 Binutils 源码
wget https://ftp.gnu.org/gnu/binutils/binutils-2.39.tar.gz
tar -xvzf binutils-2.39.tar.gz

# 下载 Glibc 源码
wget http://ftp.gnu.org/gnu/libc/glibc-2.36.tar.gz
tar -xvzf glibc-2.36.tar.gz

配置交叉编译环境

创建交叉编译目录

为防止与宿主系统的工具链冲突, 最好为交叉编译器创建一个独立目录结构

mkdir -p ~/cross_compile/aarch64-linux-gnu
cd ~/cross_compile/aarch64-linux-gnu
配置 Binutils

首先, 配置 Binutils(汇编器、链接器等), 需要指定目标架构aarch64

cd ~/cross_compile/aarch64-linux-gnu
mkdir build-binutils
cd build-binutils
~/cross_compile/binutils-2.39/configure --prefix=/home/your_user/cross_compile/aarch64-linux-gnu --target=aarch64-linux-gnu --with-sysroot --disable-nls --disable-werror
make
make install
配置 GCC

在配置 GCC 时, 需要指定交叉编译目标, 并且使用之前构建的 Binutils 作为工具链

cd ~/cross_compile/aarch64-linux-gnu
mkdir build-gcc
cd build-gcc
~/cross_compile/gcc-12.2.0/configure --prefix=/home/your_user/cross_compile/aarch64-linux-gnu --target=aarch64-linux-gnu --enable-languages=c,c++ --disable-nls --without-headers --with-sysroot=/home/your_user/cross_compile/aarch64-linux-gnu --disable-multilib --disable-shared
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc
配置 Glibc

构建 Glibc 时, 也需要指定目标平台和工具链

cd ~/cross_compile/aarch64-linux-gnu
mkdir build-glibc
cd build-glibc
~/cross_compile/glibc-2.36/configure --prefix=/home/your_user/cross_compile/aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --disable-multilib
make
make install

构建交叉编译器

构建 g++ 编译器 使用上面配置的工具链和库, 继续构建 C++ 编译器

cd ~/cross_compile/aarch64-linux-gnu
mkdir build-g++-final
cd build-g++-final
make
make install

验证

安装完成后, 可以通过以下命令验证交叉编译器是否安装成功

~/cross_compile/aarch64-linux-gnu/bin/aarch64-linux-gnu-g++ --version

如果看到类似如下的输出, 则说明交叉编译器构建成功

aarch64-linux-gnu-g++ (GCC) 12.2.0

使用

现在, 可以使用 aarch64-linux-gnu-g++ 来交叉编译目标架构为 aarch64 的 C++ 程序

aarch64-linux-gnu-g++ -o hello hello.cpp