参考
llvm/clang
安装
windows
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 表达式
表达式
可以是任何当前正在被测试程序的有效表达式, 如当前正在调试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