跳过正文

GCC 编译器 - 个人参考手册

·8152 字
Gnu Cpp Gcc Manual
目录

gcc 编译器个人参考手册。

GCC 编译器
#

GCC 代表 “GNU Compiler Collection”, 主要支持 C, C++, Objective-C, Objective-C++, Fortran, Ada, D, and Go 语言。

GCC 语言无关的实现包括各种优化,以及为各种处理器生成机器码的“back ends” 。

GCC 语言相关的实现称为 “front end”。

调用 gcc 命令的三种方式:

  1. gcc
  2. machine-gcc
  3. machine-gcc-version

后两种场景一般用于交叉编译。

gcc [-c|-S|-E] [-std=standard] [-g] [-pg] [-Olevel] [-Wwarn…] [-Wpedantic] [-Idir…] [-Ldir…] [-Dmacro[=defn]…] [-Umacro] [-foption…] [-mmachine‐option…] [-o outfile] [@file] infile…

gcc 14 参数索引: https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Option-Index.html

GCC 参数
#

-v 参数显示 GCC 支持的 Target 和配置参数:

  • –with-sysroot 指定系统 glibc 头文件和库文件的根目录;
  • –prefix=/opt/homebrew/opt/gcc –libdir=/opt/homebrew/opt/gcc/lib/gcc/current: gcc 自身安装路径, 也用于搜索自动调用的 cpp/ar/nm 等明。
# ubunut 版本 gcc
alizj@ubuntu:~$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=aarch64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-offload-targets=nvptx-none=/build/gcc-13-Nz4ro4/gcc-13-13.3.0/debian/tmp-nvptx/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)

-v 和 –help 连用时除了打印 gcc 自身参数外,还打印它调用的命令,如 cpp、ld 的参数: gcc -v --help 2>&1 |less

编译时加 -v 可以打印详细的编译命令,同时添加:

  • -Wp,-v: 编译预处理详细参数;
  • -v:编译详情, cc1 编译器的执行详情
  • -Wa,-v: 汇编详情: 显示调用的 as 命令参数;
  • -Wl,-v: 链接详情,显示 collect2 调用 ld 的详情;
alizj@ubuntu:/Users/alizj/docs/lang/c$ gcc -g -v -Wp,-v -Wa,-v -Wl,-v array.c
Using built-in specs.
COLLECT_AS_OPTIONS='-v'
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=aarch64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-offload-targets=nvptx-none=/build/gcc-13-Nz4ro4/gcc-13-13.3.0/debian/tmp-nvptx/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)

# cc1 是编译器,内置了编译预处理,实现 编译预处理+编译,生成汇编 .s 文件
COLLECT_GCC_OPTIONS='-g' '-v' '-mlittle-endian' '-mabi=lp64' '-dumpdir' 'a-'
 /usr/libexec/gcc/aarch64-linux-gnu/13/cc1 -quiet -v -imultiarch aarch64-linux-gnu -v array.c -quiet -dumpdir a- -dumpbase array.c -dumpbase-ext .c -mlittle-endian -mabi=lp64 -g -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -o /tmp/ccvkgXuK.s
GNU C17 (Ubuntu 13.3.0-6ubuntu2~24.04) version 13.3.0 (aarch64-linux-gnu)
	compiled by GNU C version 13.3.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP
## cc1 内置编译预处理搜索头文件目录
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/aarch64-linux-gnu/13/include
 /usr/local/include
 /usr/include/aarch64-linux-gnu
 /usr/include
End of search list.
Compiler executable checksum: 4641e2542d7b0fa864451cdc7c3485d3
array.c: In function ‘test_gnu_exten’:
array.c:243:16: warning: comparison of distinct pointer types lacks a cast
  243 |         if (p1 == p2) {
      |                ^~

# 汇编 as 命令参数
COLLECT_GCC_OPTIONS='-g' '-v' '-mlittle-endian' '-mabi=lp64' '-dumpdir' 'a-'
 as -v --gdwarf-5 -EL -mabi=lp64 -v -o /tmp/cc0XD2tu.o /tmp/ccvkgXuK.s

# 链接 wrapper collect2 的命令行参数,内部调用 ld
GNU assembler version 2.42 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.42
COMPILER_PATH=/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-g' '-v' '-mlittle-endian' '-mabi=lp64' '-dumpdir' 'a.'
 /usr/libexec/gcc/aarch64-linux-gnu/13/collect2 -plugin /usr/libexec/gcc/aarch64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/aarch64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/ccZXDhqQ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr --hash-style=gnu --as-needed -dynamic-linker /lib/ld-linux-aarch64.so.1 -X -EL -maarch64linux --fix-cortex-a53-843419 -pie -z now -z relro /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/Scrt1.o /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/crti.o /usr/lib/gcc/aarch64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/aarch64-linux-gnu/13 -L/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu -L/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib -L/lib/aarch64-linux-gnu -L/lib/../lib -L/usr/lib/aarch64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/aarch64-linux-gnu/13/../../.. -v /tmp/cc0XD2tu.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/aarch64-linux-gnu/13/crtendS.o /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/crtn.o
collect2 version 13.3.0

# collect 2 调用的 ld 命令
/usr/bin/ld -plugin /usr/libexec/gcc/aarch64-linux-gnu/13/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/aarch64-linux-gnu/13/lto-wrapper -plugin-opt=-fresolution=/tmp/ccZXDhqQ.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr --hash-style=gnu --as-needed -dynamic-linker /lib/ld-linux-aarch64.so.1 -X -EL -maarch64linux --fix-cortex-a53-843419 -pie -z now -z relro /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/Scrt1.o /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/crti.o /usr/lib/gcc/aarch64-linux-gnu/13/crtbeginS.o -L/usr/lib/gcc/aarch64-linux-gnu/13 -L/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu -L/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib -L/lib/aarch64-linux-gnu -L/lib/../lib -L/usr/lib/aarch64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/aarch64-linux-gnu/13/../../.. -v /tmp/cc0XD2tu.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/aarch64-linux-gnu/13/crtendS.o /usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/crtn.o
GNU ld (GNU Binutils for Ubuntu) 2.42
COLLECT_GCC_OPTIONS='-g' '-v' '-mlittle-endian' '-mabi=lp64' '-dumpdir' 'a.'

库搜索路径
#

总结:先搜索 GCC 库路径,再搜索标准库路径。

使用命令 echo 'main(){}' | gcc -E -v - 查看上面两个头文件搜索路径(gcc -v 显示详细执行命令):

alizj@ubuntu:/Users/alizj/docs/lang/c$ echo 'main(){}' | gcc -E -v -
Using built-in specs.
COLLECT_GCC=gcc
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=aarch64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-offload-targets=nvptx-none=/build/gcc-13-Nz4ro4/gcc-13-13.3.0/debian/tmp-nvptx/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
COLLECT_GCC_OPTIONS='-E' '-v' '-mlittle-endian' '-mabi=lp64'
 /usr/libexec/gcc/aarch64-linux-gnu/13/cc1 -E -quiet -v -imultiarch aarch64-linux-gnu - -mlittle-endian -mabi=lp64 -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -dumpbase -
ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/aarch64-linux-gnu/13/include
 /usr/local/include
 /usr/include/aarch64-linux-gnu
 /usr/include
End of search list.
# 0 "<stdin>"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "<stdin>"
main(){}
COMPILER_PATH=/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-mlittle-endian' '-mabi=lp64'

ubuntu host aarch64 架构编译器,使用如下目录搜索自身使用的二进制、库和头文件以及系统库文件,优先级如下:

alizj@ubuntu:~$ gcc -print-search-dirs
install: /usr/lib/gcc/aarch64-linux-gnu/13/
programs: =/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/bin/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/bin/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/bin/
libraries: =/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib/:/lib/aarch64-linux-gnu/13/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/13/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../:/lib/:/usr/lib/
  • /usr/libexec/gcc/aarch64-linux-gnu/13/
    • 保存 GCC 自身二进制
  • /usr/lib/gcc/aarch64-linux-gnu/13/
    • 保存 GCC 自身使用的库
    • 引用 /usr/lib/aarch64-linux-gnu 下的中的动态库,如 libatomic.so/libcc1.so 等
  • /usr/aarch64-linux-gnu/bin/aarch64-linux-gnu/13/
    • NO,目录不存在
  • /usr/aarch64-linux-gnu/bin/
    • NO, 目录不存在。
  • /usr/aarch64-linux-gnu/lib/aarch64-linux-gnu/13
    • NO, 目录不存在。
  • /usr/aarch64-linux-gnu/lib
    • NO, 目录不存在。
  • /usr/lib/aarch64-linux-gnu/
    • 系统标准库目录
  • /lib
  • /usr/lib
alizj@ubuntu:~$ ls  -l /usr/lib/aarch64-linux-gnu/lib[cm].so
-rw-r--r-- 1 root root 291 Aug  8 22:47 /usr/lib/aarch64-linux-gnu/libc.so
-rw-r--r-- 1 root root 149 Aug  8 22:47 /usr/lib/aarch64-linux-gnu/libm.so
alizj@ubuntu:~$ ls  -l /usr/lib/aarch64-linux-gnu/lib[cm].a
-rw-r--r-- 1 root root 5247070 Aug  8 22:47 /usr/lib/aarch64-linux-gnu/libc.a
-rw-r--r-- 1 root root     141 Aug  8 22:47 /usr/lib/aarch64-linux-gnu/libm.a
alizj@ubuntu:~$ ls  -ld /usr/lib/aarch64-linux-gnu/ld*
-rwxr-xr-x 1 root root 203968 Aug  8 22:47 /usr/lib/aarch64-linux-gnu/ld-linux-aarch64.so.1
drwxr-xr-x 1 root root   8490 Jan 14 23:55 /usr/lib/aarch64-linux-gnu/ldscripts

alizj@ubuntu:~$ ls -l /usr/include/aarch64-linux-gnu/
total 48
-rw-r--r-- 1 root root  4351 Aug  8 22:47 a.out.h
drwxr-xr-x 1 root root   644 Jan 14 23:55 asm
drwxr-xr-x 1 root root  4188 Jan 14 23:55 bits
drwxr-xr-x 1 root root     4 Jan 14 23:55 c++
-rw-r--r-- 1 root root  4251 Dec  2 04:52 expat_config.h
-rw-r--r-- 1 root root 14041 Apr  9  2024 ffi.h
-rw-r--r-- 1 root root  2748 Apr  9  2024 ffitarget.h
-rw-r--r-- 1 root root  3006 Aug  8 22:47 fpu_control.h
drwxr-xr-x 1 root root   120 Jan 14 23:55 gnu
-rw-r--r-- 1 root root  4430 Aug  8 22:47 ieee754.h
drwxr-xr-x 1 root root    56 Jan 14 23:55 openssl
drwxr-xr-x 1 root root    20 Jan 14 23:56 python3.12
drwxr-xr-x 1 root root  1190 Jan 14 23:55 sys

alizj@ubuntu:~$ ls -l /usr/libexec/gcc/aarch64-linux-gnu/13/
total 80868
-rwxr-xr-x 1 root root 26761448 Sep  4 22:44 cc1  # gcc 编译器
-rwxr-xr-x 1 root root 28862568 Sep  4 22:44 cc1plus # C++ 编译器
-rwxr-xr-x 1 root root   331800 Sep  4 22:44 collect2
-rwxr-xr-x 1 root root   264856 Sep  4 22:44 g++-mapper-server
-rwxr-xr-x 1 root root    68104 Sep  4 22:44 liblto_plugin.so
-rwxr-xr-x 1 root root 25646520 Sep  4 22:44 lto1
-rwxr-xr-x 1 root root   856192 Sep  4 22:44 lto-wrapper
# Host 架构,引用 /usr/lib/aarch64-linux-gnu
alizj@ubuntu:~$ ls -l /usr/lib/gcc/aarch64-linux-gnu/13/
total 24024
-rw-r--r-- 1 root root    3280 Sep  4 22:44 crtbegin.o
-rw-r--r-- 1 root root    3656 Sep  4 22:44 crtbeginS.o
-rw-r--r-- 1 root root    3832 Sep  4 22:44 crtbeginT.o
-rw-r--r-- 1 root root    1416 Sep  4 22:44 crtend.o
-rw-r--r-- 1 root root    1416 Sep  4 22:44 crtendS.o
-rw-r--r-- 1 root root    3928 Sep  4 22:44 crtfastmath.o
-rw-r--r-- 1 root root    1416 Sep  4 22:44 crtoffloadbegin.o
-rw-r--r-- 1 root root    1408 Sep  4 22:44 crtoffloadend.o
-rw-r--r-- 1 root root    1648 Sep  4 22:44 crtoffloadtable.o
drwxr-xr-x 1 root root     524 Jan 15 00:42 include
-rw-r--r-- 1 root root 3369448 Sep  4 22:44 libasan.a
-rw-r--r-- 1 root root   14848 Sep  4 22:44 libasan_preinit.o
lrwxrwxrwx 1 root root      39 Sep  4 22:44 libasan.so -> ../../../aarch64-linux-gnu/libasan.so.8
-rw-r--r-- 1 root root  208618 Sep  4 22:44 libatomic.a
lrwxrwxrwx 1 root root      41 Sep  4 22:44 libatomic.so -> ../../../aarch64-linux-gnu/libatomic.so.1
-rw-r--r-- 1 root root  107738 Sep  4 22:44 libbacktrace.a
lrwxrwxrwx 1 root root      38 Sep  4 22:44 libcc1.so -> ../../../aarch64-linux-gnu/libcc1.so.0
-rw-r--r-- 1 root root 3099922 Sep  4 22:44 libgcc.a
-rw-r--r-- 1 root root   53884 Sep  4 22:44 libgcc_eh.a
-rw-r--r-- 1 root root     132 Sep  4 22:44 libgcc_s.so
-rw-r--r-- 1 root root   72562 Sep  4 22:44 libgcov.a
-rw-r--r-- 1 root root  620414 Sep  4 22:44 libgomp.a
lrwxrwxrwx 1 root root      39 Sep  4 22:44 libgomp.so -> ../../../aarch64-linux-gnu/libgomp.so.1
-rw-r--r-- 1 root root     164 Sep  4 22:44 libgomp.spec
-rw-r--r-- 1 root root 1201118 Sep  4 22:44 libhwasan.a
-rw-r--r-- 1 root root    6440 Sep  4 22:44 libhwasan_preinit.o
lrwxrwxrwx 1 root root      41 Sep  4 22:44 libhwasan.so -> ../../../aarch64-linux-gnu/libhwasan.so.0
-rw-r--r-- 1 root root  221010 Sep  4 22:44 libitm.a
lrwxrwxrwx 1 root root      38 Sep  4 22:44 libitm.so -> ../../../aarch64-linux-gnu/libitm.so.1
-rw-r--r-- 1 root root     162 Sep  4 22:44 libitm.spec
-rw-r--r-- 1 root root 1175204 Sep  4 22:44 liblsan.a
-rw-r--r-- 1 root root    6264 Sep  4 22:44 liblsan_preinit.o
lrwxrwxrwx 1 root root      39 Sep  4 22:44 liblsan.so -> ../../../aarch64-linux-gnu/liblsan.so.0
lrwxrwxrwx 1 root root      61 Sep  4 22:44 liblto_plugin.so -> ../../../../libexec/gcc/aarch64-linux-gnu/13/liblto_plugin.so
-rw-r--r-- 1 root root  673462 Sep  4 22:44 libobjc.a
-rw-r--r-- 1 root root  701550 Sep  4 22:44 libobjc_gc.a
lrwxrwxrwx 1 root root      42 Sep  4 22:44 libobjc_gc.so -> ../../../aarch64-linux-gnu/libobjc_gc.so.4
lrwxrwxrwx 1 root root      39 Sep  4 22:44 libobjc.so -> ../../../aarch64-linux-gnu/libobjc.so.4
-rw-r--r-- 1 root root     362 Sep  4 22:44 libsanitizer.spec
-rw-r--r-- 1 root root    1534 Sep  4 22:44 libssp_nonshared.a
-rw-r--r-- 1 root root 6915858 Sep  4 22:44 libstdc++.a
-rw-r--r-- 1 root root  950348 Sep  4 22:44 libstdc++exp.a
-rw-r--r-- 1 root root  748174 Sep  4 22:44 libstdc++fs.a
lrwxrwxrwx 1 root root      14 Sep  4 22:44 libstdc++_libbacktrace.a -> libstdc++exp.a
lrwxrwxrwx 1 root root      41 Sep  4 22:44 libstdc++.so -> ../../../aarch64-linux-gnu/libstdc++.so.6
-rw-r--r-- 1 root root  422436 Sep  4 22:44 libsupc++.a
-rw-r--r-- 1 root root 2801138 Sep  4 22:44 libtsan.a
-rw-r--r-- 1 root root    4912 Sep  4 22:44 libtsan_preinit.o
lrwxrwxrwx 1 root root      39 Sep  4 22:44 libtsan.so -> ../../../aarch64-linux-gnu/libtsan.so.2
-rw-r--r-- 1 root root 1065066 Sep  4 22:44 libubsan.a
lrwxrwxrwx 1 root root      40 Sep  4 22:44 libubsan.so -> ../../../aarch64-linux-gnu/libubsan.so.1

ubuntu 交叉编译 x86_64 架构编译器库搜索路径:

alizj@ubuntu:~$ x86_64-linux-gnu-gcc -print-search-dirs
install: /usr/lib/gcc-cross/x86_64-linux-gnu/13/
programs: =/usr/libexec/gcc-cross/x86_64-linux-gnu/13/:/usr/libexec/gcc-cross/x86_64-linux-gnu/13/:/usr/libexec/gcc-cross/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/
libraries: =/usr/lib/gcc-cross/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/../lib/:/lib/x86_64-linux-gnu/13/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/13/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/:/lib/:/usr/lib/
  • /usr/libexec/gcc-cross/x86_64-linux-gnu/13/
    • 保存 GCC 自身二进制
  • /usr/lib/gcc-cross/x86_64-linux-gnu/13/
    • 保存 GCC 自身使用的库
    • 引用 /usr/x86_64-linux-gnu/lib 下的中的标准动态库,如 libatomic.so/libcc1.so 等
  • /usr/x86_64-linux-gnu/13/bin/x86_64-linux-gnu/13/
    • NO, 目录不存在
  • /usr/x86_64-linux-gnu/bin
    • 保存交叉编译架构的 binutils 二进制
  • /usr/x86_64-linux-gnu/lib
    • 保存交叉编译架构标准库文件
  • /usr/lib/x86_64-linux-gnu/
    • 保存链接器脚本和标准库的动态版本
  • /lib
  • /usr/lib

对于交叉编译器,存在 /usr/x86_64-linux-gnu 目录,它是保存交叉编译使用的二进制、头文件、标准库等的第二 /usr 目录层次:

alizj@ubuntu:~$ ls /usr/x86_64-linux-gnu/  # 交叉编译的第二 /usr 目录层次
bin  include  lib  lib64
alizj@ubuntu:~$ ls -l /usr/x86_64-linux-gnu/bin/ # 保存交叉编译版本的二进制工具
total 48
lrwxrwxrwx 1 root root 29 Aug  7 18:15 ar -> ../../bin/x86_64-linux-gnu-ar
lrwxrwxrwx 1 root root 29 Aug  7 18:15 as -> ../../bin/x86_64-linux-gnu-as
lrwxrwxrwx 1 root root 31 Aug  7 18:15 gold -> ../../bin/x86_64-linux-gnu-gold
lrwxrwxrwx 1 root root 29 Aug  7 18:15 ld -> ../../bin/x86_64-linux-gnu-ld
lrwxrwxrwx 1 root root 33 Aug  7 18:15 ld.bfd -> ../../bin/x86_64-linux-gnu-ld.bfd
lrwxrwxrwx 1 root root 34 Aug  7 18:15 ld.gold -> ../../bin/x86_64-linux-gnu-ld.gold
lrwxrwxrwx 1 root root 29 Aug  7 18:15 nm -> ../../bin/x86_64-linux-gnu-nm
lrwxrwxrwx 1 root root 34 Aug  7 18:15 objcopy -> ../../bin/x86_64-linux-gnu-objcopy
lrwxrwxrwx 1 root root 34 Aug  7 18:15 objdump -> ../../bin/x86_64-linux-gnu-objdump
lrwxrwxrwx 1 root root 33 Aug  7 18:15 ranlib -> ../../bin/x86_64-linux-gnu-ranlib
lrwxrwxrwx 1 root root 34 Aug  7 18:15 readelf -> ../../bin/x86_64-linux-gnu-readelf
lrwxrwxrwx 1 root root 32 Aug  7 18:15 strip -> ../../bin/x86_64-linux-gnu-strip
alizj@ubuntu:~$ ls -l /usr/x86_64-linux-gnu/include/std*.h  # 保存交叉编译版本的标准库和内核头文件
-rw-r--r-- 1 root root 26902 Apr 15  2024 /usr/x86_64-linux-gnu/include/stdbit.h
-rw-r--r-- 1 root root  2462 Apr 15  2024 /usr/x86_64-linux-gnu/include/stdc-predef.h
-rw-r--r-- 1 root root  8155 Apr 15  2024 /usr/x86_64-linux-gnu/include/stdint.h
-rw-r--r-- 1 root root  2800 Apr 15  2024 /usr/x86_64-linux-gnu/include/stdio_ext.h
-rw-r--r-- 1 root root 34649 Apr 15  2024 /usr/x86_64-linux-gnu/include/stdio.h
-rw-r--r-- 1 root root 41032 Apr 15  2024 /usr/x86_64-linux-gnu/include/stdlib.h
alizj@ubuntu:~$ ls -l /usr/x86_64-linux-gnu/lib/lib[cm].so # 交叉编译版本的标准库(动态库+静态库)
-rw-r--r-- 1 root root 308 Apr 15  2024 /usr/x86_64-linux-gnu/lib/libc.so
-rw-r--r-- 1 root root 148 Apr 15  2024 /usr/x86_64-linux-gnu/lib/libm.so
alizj@ubuntu:~$ ls -l /usr/x86_64-linux-gnu/lib/lib[cm].a
-rw-r--r-- 1 root root 6112386 Apr 15  2024 /usr/x86_64-linux-gnu/lib/libc.a
-rw-r--r-- 1 root root     132 Apr 15  2024 /usr/x86_64-linux-gnu/lib/libm.a
alizj@ubuntu:~$ ls -l /usr/lib/x86_64-linux-gnu/ # 交叉编译版本的标准库,保存动态链接版本的库,动态链接器和链接脚本
total 6784
drwxr-xr-x 1 root root      18 Jan 15 20:57 bfd-plugins
drwxr-xr-x 1 root root    5434 Jan 11 22:22 gconv
-rwxr-xr-x 1 root root  236616 Aug  8 22:47 ld-linux-x86-64.so.2
drwxr-xr-x 1 root root    2648 Jan 15 20:57 ldscripts
-rw-r--r-- 1 root root   14408 Aug  8 22:47 libanl.so.1
-rw-r--r-- 1 root root   14624 Aug  8 22:47 libBrokenLocale.so.1
-rw-r--r-- 1 root root   60744 Aug  8 22:47 libc_malloc_debug.so.0
-rwxr-xr-x 1 root root 2125328 Aug  8 22:47 libc.so.6
-rw-r--r-- 1 root root   14408 Aug  8 22:47 libdl.so.2
-rw-r--r-- 1 root root  183024 Sep  9 21:21 libgcc_s.so.1
lrwxrwxrwx 1 root root      16 Apr  9  2024 libidn2.so.0 -> libidn2.so.0.4.0
-rw-r--r-- 1 root root  133192 Apr  9  2024 libidn2.so.0.4.0
-rw-r--r-- 1 root root   18712 Aug  8 22:47 libmemusage.so
-rw-r--r-- 1 root root  952616 Aug  8 22:47 libm.so.6
-rw-r--r-- 1 root root 1018144 Aug  8 22:47 libmvec.so.1
-rw-r--r-- 1 root root  100640 Aug  8 22:47 libnsl.so.1
-rw-r--r-- 1 root root   43736 Aug  8 22:47 libnss_compat.so.2
-rw-r--r-- 1 root root   14336 Aug  8 22:47 libnss_dns.so.2
-rw-r--r-- 1 root root   14336 Aug  8 22:47 libnss_files.so.2
-rw-r--r-- 1 root root   26912 Aug  8 22:47 libnss_hesiod.so.2
-rw-r--r-- 1 root root   14544 Aug  8 22:47 libpcprofile.so
-rw-r--r-- 1 root root   14408 Aug  8 22:47 libpthread.so.0
-rw-r--r-- 1 root root   68104 Aug  8 22:47 libresolv.so.2
-rw-r--r-- 1 root root   14624 Aug  8 22:47 librt.so.1
-rw-r--r-- 1 root root   47912 Aug  8 22:47 libthread_db.so.1
lrwxrwxrwx 1 root root      21 Apr  9  2024 libunistring.so.5 -> libunistring.so.5.0.0
-rw-r--r-- 1 root root 1755312 Apr  9  2024 libunistring.so.5.0.0
-rw-r--r-- 1 root root   14408 Aug  8 22:47 libutil.so.1

alizj@ubuntu:~$ ls -l /usr/x86_64-linux-gnu/lib64/  # 交叉编译版本的链接器
total 4
lrwxrwxrwx 1 root root 27 Apr 15  2024 ld-linux-x86-64.so.2 -> ../lib/ld-linux-x86-64.so.2
alizj@ubuntu:~$ ls /usr/libexec/gcc-cross/x86_64-linux-gnu/13/  # 交叉编译 GCC 自身二进制
cc1  collect2  liblto_plugin.so  lto1  lto-wrapper
alizj@ubuntu:~$ ls -l  /usr/lib/gcc-cross/x86_64-linux-gnu/13  # 交叉编译 GCC 自身使用的库和头文件
total 20884
-rw-r--r-- 1 root root    2448 Sep 15 19:33 crtbegin.o
-rw-r--r-- 1 root root    2752 Sep 15 19:33 crtbeginS.o
-rw-r--r-- 1 root root    2968 Sep 15 19:33 crtbeginT.o
-rw-r--r-- 1 root root    1168 Sep 15 19:33 crtend.o
-rw-r--r-- 1 root root    1168 Sep 15 19:33 crtendS.o
-rw-r--r-- 1 root root    4112 Sep 15 19:33 crtfastmath.o
-rw-r--r-- 1 root root    3768 Sep 15 19:33 crtprec32.o
-rw-r--r-- 1 root root    3776 Sep 15 19:33 crtprec64.o
-rw-r--r-- 1 root root    3768 Sep 15 19:33 crtprec80.o
drwxr-xr-x 1 root root    3530 Jan 15 20:57 include
-rw-r--r-- 1 root root 4984914 Sep 15 19:33 libasan.a
-rw-r--r-- 1 root root    3568 Sep 15 19:33 libasan_preinit.o
lrwxrwxrwx 1 root root      45 Sep 15 19:33 libasan.so -> ../../../../x86_64-linux-gnu/lib/libasan.so.8
-rw-r--r-- 1 root root  158816 Sep 15 19:33 libatomic.a
lrwxrwxrwx 1 root root      47 Sep 15 19:33 libatomic.so -> ../../../../x86_64-linux-gnu/lib/libatomic.so.1
-rw-r--r-- 1 root root  142090 Sep 15 19:33 libbacktrace.a
lrwxrwxrwx 1 root root      38 Sep 15 19:33 libcc1.so -> ../../../aarch64-linux-gnu/libcc1.so.0
-rw-r--r-- 1 root root 3093656 Sep 15 19:33 libgcc.a
-rw-r--r-- 1 root root   66708 Sep 15 19:33 libgcc_eh.a
-rw-r--r-- 1 root root     132 Sep 15 19:33 libgcc_s.so
-rw-r--r-- 1 root root   68002 Sep 15 19:33 libgcov.a
-rw-r--r-- 1 root root  610806 Sep 15 19:33 libgomp.a
lrwxrwxrwx 1 root root      45 Sep 15 19:33 libgomp.so -> ../../../../x86_64-linux-gnu/lib/libgomp.so.1
-rw-r--r-- 1 root root     164 Sep 15 19:33 libgomp.spec
-rw-r--r-- 1 root root 2322684 Sep 15 19:33 libhwasan.a
-rw-r--r-- 1 root root    2296 Sep 15 19:33 libhwasan_preinit.o
lrwxrwxrwx 1 root root      47 Sep 15 19:33 libhwasan.so -> ../../../../x86_64-linux-gnu/lib/libhwasan.so.0
-rw-r--r-- 1 root root  323496 Sep 15 19:33 libitm.a
lrwxrwxrwx 1 root root      44 Sep 15 19:33 libitm.so -> ../../../../x86_64-linux-gnu/lib/libitm.so.1
-rw-r--r-- 1 root root     162 Sep 15 19:33 libitm.spec
-rw-r--r-- 1 root root 2232412 Sep 15 19:33 liblsan.a
-rw-r--r-- 1 root root    2344 Sep 15 19:33 liblsan_preinit.o
lrwxrwxrwx 1 root root      45 Sep 15 19:33 liblsan.so -> ../../../../x86_64-linux-gnu/lib/liblsan.so.0
lrwxrwxrwx 1 root root      66 Sep 15 19:33 liblto_plugin.so -> ../../../../libexec/gcc-cross/x86_64-linux-gnu/13/liblto_plugin.so
-rw-r--r-- 1 root root  627684 Sep 15 19:33 libquadmath.a
lrwxrwxrwx 1 root root      49 Sep 15 19:33 libquadmath.so -> ../../../../x86_64-linux-gnu/lib/libquadmath.so.0
-rw-r--r-- 1 root root     362 Sep 15 19:33 libsanitizer.spec
-rw-r--r-- 1 root root    1486 Sep 15 19:33 libssp_nonshared.a
-rw-r--r-- 1 root root 4596130 Sep 15 19:33 libtsan.a
-rw-r--r-- 1 root root    1464 Sep 15 19:33 libtsan_preinit.o
lrwxrwxrwx 1 root root      45 Sep 15 19:33 libtsan.so -> ../../../../x86_64-linux-gnu/lib/libtsan.so.2
-rw-r--r-- 1 root root 2002710 Sep 15 19:33 libubsan.a
lrwxrwxrwx 1 root root      46 Sep 15 19:33 libubsan.so -> ../../../../x86_64-linux-gnu/lib/libubsan.so.1
drwxr-xr-x 1 root root     212 Jan 15 20:57 plugin

头文件搜索路径
#

总结: 先搜索 GCC 相关头文件目录,再搜索系统标准头文件目录。

使用 cpp -v 命令查看搜索路径:

alizj@ubuntu:/Users/alizj/docs/lang/c$ cpp -v /dev/null -o /dev/null
Using built-in specs.
COLLECT_GCC=cpp
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: aarch64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=aarch64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-offload-targets=nvptx-none=/build/gcc-13-Nz4ro4/gcc-13-13.3.0/debian/tmp-nvptx/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=aarch64-linux-gnu --host=aarch64-linux-gnu --target=aarch64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
COLLECT_GCC_OPTIONS='-E' '-v' '-o' '/dev/null' '-mlittle-endian' '-mabi=lp64'
 /usr/libexec/gcc/aarch64-linux-gnu/13/cc1 -E -quiet -v -imultiarch aarch64-linux-gnu /dev/null -o /dev/null -mlittle-endian -mabi=lp64 -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -dumpbase null
ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/aarch64-linux-gnu/13/include
 /usr/local/include
 /usr/include/aarch64-linux-gnu
 /usr/include
End of search list.
COMPILER_PATH=/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-E' '-v' '-o' '/dev/null' '-mlittle-endian' '-mabi=lp64'

对于 host 架构而言,系统标准库和头文件分别是 /usr/lib 和 /usr/include 目录:

  • /usr/include/aarch64-linux-gnu/: GCC 自身定义和使用的头文件目录
  • /usr/lib/gcc/aarch64-linux-gnu/13/include: GCC 自身定义和使用的头文件目录
  • /usr/aarch64-linux-gnu: NO,目录不存在;
  • /usr/include: 系统标准头文件目录

对于交叉编译工具链,不存在 /usr/include/x86_64-linux-gnu/ 目录,GCC 相关和系统标准库头文件都位于:

  • /usr/lib/gcc/x86_64-linux-gnu/13/include # GCC 自身头文件
  • /usr/x86_64-linux-gnu/include # GCC 头文件 + 目标架构标准头文件(含内核)
alizj@ubuntu:~$ ls -l /usr/include/aarch64-linux-gnu/ # x86_64 没有对应目录,都合并到 /usr/x86_64-linux-gnu/include 目录下
total 48
-rw-r--r-- 1 root root  4351 Aug  8 22:47 a.out.h
drwxr-xr-x 1 root root   644 Jan 14 23:55 asm
drwxr-xr-x 1 root root  4188 Jan 14 23:55 bits
drwxr-xr-x 1 root root     4 Jan 14 23:55 c++
-rw-r--r-- 1 root root  4251 Dec  2 04:52 expat_config.h
-rw-r--r-- 1 root root 14041 Apr  9  2024 ffi.h
-rw-r--r-- 1 root root  2748 Apr  9  2024 ffitarget.h
-rw-r--r-- 1 root root  3006 Aug  8 22:47 fpu_control.h
drwxr-xr-x 1 root root   120 Jan 14 23:55 gnu
-rw-r--r-- 1 root root  4430 Aug  8 22:47 ieee754.h
drwxr-xr-x 1 root root    56 Jan 14 23:55 openssl
drwxr-xr-x 1 root root    20 Jan 14 23:56 python3.12
drwxr-xr-x 1 root root  1190 Jan 14 23:55 sys
alizj@ubuntu:~$ ls -l  /usr/lib/gcc/aarch64-linux-gnu/13/include # GCC 自身使用的头文件, x86_64 也有对应目录
total 1076
-rw-r--r-- 1 root root   7454 Sep  4 22:44 acc_prof.h
-rw-r--r-- 1 root root   9244 Sep  4 22:44 arm_acle.h
-rw-r--r-- 1 root root   1647 Sep  4 22:44 arm_bf16.h
-rw-r--r-- 1 root root  18689 Sep  4 22:44 arm_fp16.h
-rw-r--r-- 1 root root 874386 Sep  4 22:44 arm_neon.h
-rw-r--r-- 1 root root   1611 Sep  4 22:44 arm_sve.h
-rw-r--r-- 1 root root   9141 Sep  4 22:44 backtrace.h
-rw-r--r-- 1 root root   2982 Sep  4 22:44 backtrace-supported.h
-rw-r--r-- 1 root root  20749 Sep  4 22:44 float.h
-rw-r--r-- 1 root root   2940 Sep  4 22:44 gcov.h
-rw-r--r-- 1 root root   1272 Sep  4 22:44 iso646.h
-rw-r--r-- 1 root root   6399 Sep  4 22:44 limits.h
drwxr-xr-x 1 root root    196 Jan 15 00:42 objc
-rw-r--r-- 1 root root  12832 Sep  4 22:44 omp.h
-rw-r--r-- 1 root root   6403 Sep  4 22:44 openacc.h
drwxr-xr-x 1 root root    178 Jan 14 23:55 sanitizer
-rw-r--r-- 1 root root   1290 Sep  4 22:44 stdalign.h
-rw-r--r-- 1 root root   4303 Sep  4 22:44 stdarg.h
-rw-r--r-- 1 root root   9726 Sep  4 22:44 stdatomic.h
-rw-r--r-- 1 root root   1490 Sep  4 22:44 stdbool.h
-rw-r--r-- 1 root root  13735 Sep  4 22:44 stddef.h
-rw-r--r-- 1 root root   6000 Sep  4 22:44 stdfix.h
-rw-r--r-- 1 root root   9648 Sep  4 22:44 stdint-gcc.h
-rw-r--r-- 1 root root    328 Sep  4 22:44 stdint.h
-rw-r--r-- 1 root root   1136 Sep  4 22:44 stdnoreturn.h
-rw-r--r-- 1 root root    330 Sep  4 22:44 syslimits.h
-rw-r--r-- 1 root root  10938 Sep  4 22:44 unwind.h
-rw-r--r-- 1 root root    139 Sep  4 22:44 varargs.h


alizj@ubuntu:~$ ls -l /usr/x86_64-linux-gnu/include/ # 含标准库 + GCC 使用的头文件(如 a.out.h,asm/*, bits/* 等)
total 1312
-rw-r--r-- 1 root root   7739 Apr 15  2024 aio.h
-rw-r--r-- 1 root root   2028 Apr 15  2024 aliases.h
-rw-r--r-- 1 root root   1203 Apr 15  2024 alloca.h
-rw-r--r-- 1 root root   4351 Apr 15  2024 a.out.h
-rw-r--r-- 1 root root  25548 Apr 15  2024 argp.h
-rw-r--r-- 1 root root   6051 Apr 15  2024 argz.h
-rw-r--r-- 1 root root   1731 Apr 15  2024 ar.h
drwxr-xr-x 1 root root    100 Jan 15 20:57 arpa
drwxr-xr-x 1 root root   1150 Jan 15 20:57 asm
drwxr-xr-x 1 root root    690 Jan 15 20:57 asm-generic
-rw-r--r-- 1 root root   5086 Apr 15  2024 assert.h
drwxr-xr-x 1 root root   4204 Jan 15 20:57 bits
...
-rw-r--r-- 1 root root   1584 Apr 15  2024 ulimit.h
-rw-r--r-- 1 root root  45053 Apr 15  2024 unistd.h
-rw-r--r-- 1 root root   1905 Apr 15  2024 utime.h
-rw-r--r-- 1 root root   3223 Apr 15  2024 utmp.h
-rw-r--r-- 1 root root   4100 Apr 15  2024 utmpx.h
-rw-r--r-- 1 root root   1956 Apr 15  2024 values.h
drwxr-xr-x 1 root root     44 Jan 15 20:57 video
-rw-r--r-- 1 root root     22 Apr 15  2024 wait.h
-rw-r--r-- 1 root root  39102 Apr 15  2024 wchar.h
-rw-r--r-- 1 root root   5549 Apr 15  2024 wctype.h
-rw-r--r-- 1 root root   2502 Apr 15  2024 wordexp.h
drwxr-xr-x 1 root root     70 Jan 15 20:57 xen

对于 Fedora、CentOS 系列,安装交叉编译工具链后,还要安装 sysroot 包才能提供目标架构的头文件、库文件:

[root@d8e784ed1d22 ~]# aarch64-linux-gnu-gcc -v
Using built-in specs.
COLLECT_GCC=aarch64-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-linux-gnu/14/lto-wrapper
Target: aarch64-linux-gnu
Configured with: ../gcc-14.1.1-20240508/configure --bindir=/usr/bin --build=x86_64-redhat-linux-gnu --datadir=/usr/share --disable-decimal-float --disable-dependency-tracking --disable-gold --disable-libgcj --disable-libgomp --disable-libmpx --disable-libquadmath --disable-libssp --disable-libunwind-exceptions --disable-shared --disable-silent-rules --disable-sjlj-exceptions --disable-threads --with-ld=/usr/bin/aarch64-linux-gnu-ld --enable-__cxa_atexit --enable-checking=release --enable-gnu-unique-object --enable-initfini-array --enable-languages=c,c++ --enable-linker-build-id --enable-lto --enable-nls --enable-obsolete --enable-plugin --enable-targets=all --exec-prefix=/usr --host=x86_64-redhat-linux-gnu --includedir=/usr/include --infodir=/usr/share/info --libexecdir=/usr/libexec --localstatedir=/var --mandir=/usr/share/man --prefix=/usr --program-prefix=aarch64-linux-gnu- --sbindir=/usr/sbin --sharedstatedir=/var/lib --sysconfdir=/etc --target=aarch64-linux-gnu --with-bugurl=http://bugzilla.redhat.com/bugzilla/ --with-gcc-major-version-only --with-isl --with-newlib --with-plugin-ld=/usr/bin/aarch64-linux-gnu-ld --with-sysroot=/usr/aarch64-linux-gnu/sys-root --with-system-libunwind --with-system-zlib --without-headers --enable-gnu-indirect-function --with-linker-hash-style=gnu
Thread model: single
Supported LTO compression algorithms: zlib zstd
gcc version 14.1.1 20240507 (Red Hat Cross 14.1.1-1) (GCC)

[root@d8e784ed1d22 ~]# aarch64-linux-gnu-gcc -print-search-dirs
install: /usr/lib/gcc/aarch64-linux-gnu/14/
programs: =/usr/libexec/gcc/aarch64-linux-gnu/14/:/usr/libexec/gcc/aarch64-linux-gnu/14/:/usr/libexec/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/14/:/usr/lib/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/bin/aarch64-linux-gnu/14/:/usr/lib/gcc/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/bin/
libraries: =/usr/lib/gcc/aarch64-linux-gnu/14/:/usr/lib/gcc/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/lib/aarch64-linux-gnu/14/:/usr/lib/gcc/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/lib/../lib64/:/usr/aarch64-linux-gnu/sys-root/lib/aarch64-linux-gnu/14/:/usr/aarch64-linux-gnu/sys-root/lib/../lib64/:/usr/aarch64-linux-gnu/sys-root/usr/lib/aarch64-linux-gnu/14/:/usr/aarch64-linux-gnu/sys-root/usr/lib/../lib64/:/usr/lib/gcc/aarch64-linux-gnu/14/../../../../aarch64-linux-gnu/lib/:/usr/aarch64-linux-gnu/sys-root/lib/:/usr/aarch64-linux-gnu/sys-root/usr/lib/

[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-linux-gnu/
total 0
drwxr-xr-x 1 root root 92 Jan 22 07:59 bin
drwxr-xr-x 1 root root  0 May 13  2024 sys-root
[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-linux-gnu/bin/
total 20056
-rwxr-xr-x 2 root root 1286616 May 13  2024 ar
-rwxr-xr-x 2 root root 2351968 May 13  2024 as
-rwxr-xr-x 4 root root 3426184 May 13  2024 ld
-rwxr-xr-x 4 root root 3426184 May 13  2024 ld.bfd
-rwxr-xr-x 2 root root 1362072 May 13  2024 nm
-rwxr-xr-x 2 root root 1514504 May 13  2024 objcopy
-rwxr-xr-x 2 root root 3455728 May 13  2024 objdump
-rwxr-xr-x 2 root root 1286616 May 13  2024 ranlib
-rwxr-xr-x 2 root root  890584 May 13  2024 readelf
-rwxr-xr-x 2 root root 1514504 May 13  2024 strip
[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-linux-gnu/sys-root/
total 0

[root@d8e784ed1d22 ~]# rpm -qa |grep sysroot
sysroot-aarch64-fc40-glibc-2.39-33.fc40.noarch

# 安装 sysroot 包后,才会有交叉编译架构的头文件、标准库文件等类似于 /usr 的第二目录结构
[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-redhat-linux/
total 0
drwxr-xr-x 1 root root 8 Jan 22 08:52 sys-root
[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-redhat-linux/sys-root/
total 0
drwxr-xr-x 1 root root 6 Jan 22 08:52 fc40
[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-redhat-linux/sys-root/fc40/
total 0
drwxr-xr-x 1 root root 30 Jan 22 08:52 usr
[root@d8e784ed1d22 ~]# ls -l /usr/aarch64-redhat-linux/sys-root/fc40/usr/
total 0
drwxr-xr-x 1 root root 2090 Jan 22 08:52 include
drwxr-xr-x 1 root root   42 Jan 22 08:52 lib
drwxr-xr-x 1 root root 1234 Jan 22 08:52 lib64

# 在编译时需要为链接器传入 --sysroot 参数来指定上面目录
aarch64-linux-gnu-gcc --sysroot=/usr/aarch64-redhat-linux/sys-root/fc40/

打印 gcc 执行预处理、编译、汇编和链接的规则:

❯ gcc-14 -dumpspecs|head
*asm:
-arch %(darwin_arch) %{march*} %{mtune*} %{v} %{w:-W} %{I*} %{static} %{asm_macosx_version_min=*: -mmacosx-version-min=%* }    %<asm_macosx_version_min=*
*asm_debug:
*asm_debug_option:
*asm_final:

C 版本
#

-std:指定 C 语言版本: c90 c89 c99 c11 c17 c18 c23,gnu89 gnu90 gnu11 gnu17 gnu18 gnu23;

未指定 -std 参数时,clang 使用 C99 标准,gcc 使用 gnu17 标准,Linux kernel 使用 gnu11 标准。

如果只使用 C 标准特性,可以在指定 c99/c23 等 C 标准的同时,指定 -pedantic 或 -pedantic-errors 参数,这时 GNU 扩展或 GCC builtin 函数将不能再使用,使用 GNU C 扩展时将发送警告或出错。

-ansi 等效于 -std=c90 或 -std=c++98,它关闭了 GNU C 扩展, 只使用 ISO C 标准特性,如 asm/extension/inline/typeof 等关键字不可用, 但是编译器内置的带有前后下划线的名称可用, 如 __asm__/__extension__/__inline__/__typeof__

参考: https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Standards.html

调试
#

开启了 -g 或 -ggdb 选项后, 才在 binary 文件中包含调试信息,后续 gdb 需要该信息。

调试信息和符号表不是一回事, 符号表是默认都会带的, 除非后续用 strip 命令来删除。

  • -g: Generate source-level debug information. Produce debugging information in the operating system’s native format (stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging information.
  • -ggdb:生成 gdb 使用的调试信息,自动选择格式(如 DWARF);
  • -gdwarf,-gdwarf-{version}, version 可以是 version may be either 2, 3, 4 or 5,对于 linux 默认是 5, Version 5 requires GDB 8.0 or higher.
  • -pg Generate extra code to write profile information suitable for the analysis program prof (for -p) or gprof (for -pg).
  • -gbtf Request BTF debug information. BTF is the default debugging format for the eBPF target.
  • -glevel:request debugging information and also use level to specify how much information. The default level is 2. 特殊的 g0 表示 produces no debug information at all. Thus, -g0 negates -g.

优化
#

默认不开启优化,也就是 -O0.

  • -O0 Reduce compilation time and make debugging produce the expected results. This is the default.

优化级别:

  • -O1:Optimize. Optimizing compilation takes somewhat more time, and a lot more memory for a large function.
  • -O2 Optimize even more. GCC performs nearly all supported optimizations that do not involve a space‐speed tradeoff.
  • -O3 Optimize yet more. -O3 turns on all optimizations specified by -O2 and also turns on the following optimization flags
  • -Os Optimize for size. -Os enables all -O2 optimizations except those that often increase code size:
  • -Ofast Disregard strict standards compliance. -Ofast enables all -O3 optimizations.
  • -Og Optimize debugging experience.
  • -Oz Optimize aggressively for size rather than speed.

只要开启了优化,默认就会开启 -fomit-frame-pointer, 如果要明确支持 FP 则需要添加参数: -fno-omit-frame-pointer

另外一个和 stack unwiding 相关的参数是 --enable-frame-pointer

警告
#

只检查语法,不做其它处理:

  • -fsyntax-only: Check the code for syntax errors, but don’t do anything beyond that.

只使用 ISO C/C++ 规范定义(使用 -std 来指定版本,如 -std=gnu99 -Wpedantic),警告或拒绝 GNU C 等语言扩展。

  • -Wpedantic : 使用语言扩展时警告。但对于双下划线开头的扩展,如 __inline__/__asm__ 等不告警。
  • -pedantic : 拒绝所有语言扩展(编译出错)。
  • -pedantic-errors

警告:

  • -Wdeprecated : Enable warnings for deprecated constructs and define __DEPRECATED
  • -W<warning> : Enable the specified warning
    • -Wall : This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros
    • -Wextra : This enables some extra warning flags that are not enabled by -Wall
    • -Werror : Make all warnings into errors.
    • -Werror=* : Make the specified warning into an error
    • -Wfatal-errors : This option causes the compiler to abort compilation on the first error occurred rather than trying to keep going and printing further error messages.
  • -w : Suppress all warnings

良好的开发习惯是在编译时指定如下参数: -std=c23 -Wall -Wextra -Wpedantic

profiling
#

  • -p -pg: Generate extra code to write profile information suitable for the analysis program prof (for -p) or gprof (for -pg).
  • -fprofile-arcs
  • –coverage -ftest-coverage: This option is used to compile and link code instrumented for coverage analysis.
$ gcc -Wall -c -pg collatz.c
$ gcc -Wall -pg collatz.o

$ gprof a.out
Flat profile:
Each sample counts as 0.01 seconds.
% cumul. self self total
time seconds seconds calls us/call us/call name
68.59 2.14 2.14 62135400 0.03 0.03 step
31.09 3.11 0.97 499999 1.94 6.22 nseq
0.32 3.12 0.01 main


$ gcc -Wall -fprofile-arcs -ftest-coverage cov.c
$ gcov cov.c
88.89% of 9 source lines executed in file cov.c
Creating cov.c.gcov

预处理
#

cpp 当前已被内置到编译器中(gcc -E 只执行预处理),单独的 cpp 程序是为了兼容性。

只运行预处理:

  • -E: Only run the preprocessor 使用 GCC 内建的预处理器

指定传给预处理器程序 cpp 的参数:

  • -Xpreprocessor ; Pass to the preprocessor
  • -Wp,; Pass the comma separated arguments in to the preprocessor

指定预处理器查找头文件时的目录:

  • -I Add directory to the end of the list of include search paths
  • -iquote Add directory to QUOTE include search path
  • -isystem Add directory to SYSTEM include search path
  • -isystem-after Add directory to end of the SYSTEM include search path
  • -idirafter Add directory to AFTER include search path
  • -isysroot : 默认为 /, 指定查找系统 glibc 标准库头文件的根目录,如 <directory>/usr/include
    • 可以通过编译器的 –sysroot 参数指定。
  • -iwithprefix dir -iwithprefixbefore dir

If begins with ‘=’ or $SYSROOT, then the ‘=’ or $SYSROOT is replaced by the sysroot prefix; see –sysroot and -isysroot.

-iquote 只适用于 #include “header.h” 的查找。其它适用于两种类型的头文件查找。

定义 macro 常量,在所有源文件中生效:

  • -D name: 定义 macro name, 值默认为 1;
  • -D =:Define to (or 1 if omitted)

撤销以前定义的 macro name,等效于在头文件中使用 #undef name :

  • -U name: Cancel any previous definition of name, either built in or provided with a -D option.

在所有源文件前添加指定的 file,例如 -include stdio.h : 等效为在源文件前添加了 #incldue <stdio.h> 指令:

  • -include file: Process file as if #include “file” appeared as the first line of the primary source file.

-pthread: Define additional macros required for using the POSIX threads library.

编译
#

编译是从 C 源文件生成汇编文件(.s) 的过程,使用的是 gcc 提供的 cc1 命令:

  • 如果没有指定 -E,则使用内置的编译预处理功能,打印头文件搜索路径。
$ gcc -v -Wall array.c # gcc -v 显示执行的命令详情
...
COLLECT_GCC_OPTIONS='-v' '-Wall' '-mlittle-endian' '-mabi=lp64' '-dumpdir' 'a-'
 /usr/libexec/gcc/aarch64-linux-gnu/13/cc1 -quiet -v -imultiarch aarch64-linux-gnu array.c -quiet -dumpdir a- -dumpbase array.c -dumpbase-ext .c -mlittle-endian -mabi=lp64 -Wall -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat-security -fstack-clash-protection -o /tmp/ccUcSjmL.s
GNU C17 (Ubuntu 13.3.0-6ubuntu2~24.04) version 13.3.0 (aarch64-linux-gnu)
        compiled by GNU C version 13.3.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed/aarch64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/aarch64-linux-gnu/13/include
 /usr/local/include
 /usr/include/aarch64-linux-gnu
 /usr/include
End of search list.
Compiler executable checksum: 4641e2542d7b0fa864451cdc7c3485d3

-S: 编译后不执行汇编,输出的文件名后缀是 .s,内容是汇编代码;

$ gcc -Wall -S hello.i

$ cat hello.s
    .file "hello.c"
    .section .rodata
.LC0:
    .string "Hello, world!\n"
    .text
.globl main
    .type main, @function
main:
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    movl $0, %eax
    subl %eax, %esp
    movl $.LC0, (%esp)
    call printf
    movl $0, %eax
    leave
    ret
    .size main, .-main
    .ident "GCC: (GNU) 3.3.1"

汇编
#

汇编: 从汇编源文件(.s)生成对象文件(ELF 格式的 .o 文件)的过程;

gcc 调用 binutil 包提供的汇编器命令 as。

-c: Only run preprocess, compile, and assemble steps 只运行预处理、编译和汇编,不进行链接,结果是 object 文件;

$ gcc -v -Wall array.c
...
COLLECT_GCC_OPTIONS='-v' '-Wall' '-mlittle-endian' '-mabi=lp64' '-dumpdir' 'a-'
 as -v -EL -mabi=lp64 -o /tmp/ccbzmPYo.o /tmp/ccUcSjmL.s
GNU assembler version 2.42 (aarch64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.42

指定传给汇编器的参数:

  • -Wa, Pass the comma separated arguments in to the assembler
  • -Xassembler Pass to the assembler

指定传给 clang 编译器的参数:

  • -Xclang Pass to clang -cc1
  • –target= Generate code for the given target

clang 编译器支持交叉编译,通过 –target 传递目标架构的类型。但是 gcc 一般不支持交叉编译,需要指定特定前缀的 gcc 工具链,如 aarch64-linux-gnu-gcc.

编译生成位置无关代码和可执行程序:

  • -fpic -fPIC
  • -fpie -fPIE

链接
#

当指定以下参数时将不执行链接: -c(编译)/-S(汇编)/-E(预处理)

指定使用的链接器类型(默认为 bfd,gold 为较新的 ELF only 链接器):

  • -fuse-ld=bfd/-fuse-ld=gold/-fuse-ld=lld/-fuse-ld=mold

链接的库或目录:

  • -L Add directory to library search path
  • -llibrary:链接 liblibrary.a 或 liblibrary.so, 如果两个都存在, 优先动态库, 除非指定 -static
  • -o Write output to

glibc 头文件和库文件根目录:

  • –sysroot= Use as the root directory for headers

常见的使用 –sysroot 的常见是交叉编译,它指定 gcc 链接可执行程序使用的系统 glibc 库和头文件的根目录,例如在 fedora 40 x86_64 架构上交叉编译 aarch64 架构二进制,需要单独安装 aarch64 架构的 glibc 头文件和静态库:

  • 指定的 –sysroot 参数会传给编译预处理的参数 -isysroot
# --with-sysroot=/usr/aarch64-linux-gnu/sys-root 目录为空:
[root@d8e784ed1d22 bp-agent]# ls /usr/aarch64-linux-gnu/bin/
ar  as  ld  ld.bfd  nm  objcopy  objdump  ranlib  readelf  strip
[root@d8e784ed1d22 bp-agent]# ls /usr/aarch64-linux-gnu/sys-root/
[root@d8e784ed1d22 bp-agent]#

# 安装 aarch64 对应的 sysroot 包 sysroot-aarch64-fc40-glibc.noarch,它提供了交叉编译所需的 glibc 头文件和静态库
[root@d8e784ed1d22 bp-agent]# yum install sysroot-aarch64-fc40-glibc.noarch
[root@d8e784ed1d22 bp-agent]# ls /usr/aarch64-redhat-linux/sys-root/fc40/usr/
include  lib  lib64

# 使用 CGO_CFLAGS 环境变量为交叉编译 gcc 指定 --sysroot 参数,来使用安装的 aarch64 的 glibc 头文件和静态库,
# 同时使用 CC 环境变量指定使用该工具链来编译 CGO 链接的 C 程序
[root@d8e784ed1d22 bp-agent]# CC=aarch64-linux-gnu-gcc CGO_CFLAGS="-g -O2 --sysroot=/usr/aarch64-redhat-linux/sys-root/fc40" CGO_LDFLAGS="-g -O2 --sysroot=/usr/aarch64-redhat-linux/sys-root/fc40"  GOOS=linux GOARCH=arm64 CGO_ENABLED=1 go build -x -tags 'osusergo netgo sqlite_omit_load_extension no_dynamic_plugins' -o myagent -ldflags=" -extldflags '-static'" ./cmd/

传递给链接器的参数:

  • -Wl, Pass the comma separated arguments in to the linker

  • -Xlinker Pass to the linker

  • -z Pass -z to the linker

  • -pie: Produce a dynamically linked position independent executable on targets that support it。一般需要和 -fpie 或 -fPIE 连用

  • -pthread:链接 POSIX thread

  • -r -rdynamic

  • -s : Remove all symbol table and relocation information from the executable. 移除符号表+debug_XX 调试符号表

  • -S: 移除调试符号表

  • -static -static-pie -static-libgcc -static-libstdc++ :静态链接

  • -shared -shared-libgcc -symbolic: 动态链接,需要和 -fpic 或 -fPIC 连用.

  • -nostartfiles -nodefaultlibs -nolibc

  • -nostdlib -nostdlib++

  • -e entry –entry=entry

  • -u symbol -z keyword

移除符号表:

  • -s: Remove all symbol table and relocation information from the executable.

指定链接脚本:

  • -T script: Use script as the linker script

添加运行时动态链接库搜索路径到二进制中:

  • 在构建(链接阶段)时,通过 -rpath 参数指定动态库搜索路径(写入到了可执行文件 ELF .dynamic 段的 DT_RPATH 或 DT_RUNPATH,通过 readelf -d 可查询)。
alizj@lima-dev2:~$ aarch64-linux-gnu-gcc --print-search-dirs
install: /usr/lib/gcc/aarch64-linux-gnu/13/
programs: =/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/13/:/usr/libexec/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/bin/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/bin/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/bin/
libraries: =/usr/lib/gcc/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/13/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../aarch64-linux-gnu/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../lib/:/lib/aarch64-linux-gnu/13/:/lib/aarch64-linux-gnu/:/lib/../lib/:/usr/lib/aarch64-linux-gnu/13/:/usr/lib/aarch64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../../aarch64-linux-gnu/lib/:/usr/lib/gcc/aarch64-linux-gnu/13/../../../:/lib/:/usr/lib/


alizj@lima-dev2:~$ x86_64-linux-gnu-gcc-13 --print-search-dirs
install: /usr/lib/gcc-cross/x86_64-linux-gnu/13/
programs: =/usr/libexec/gcc-cross/x86_64-linux-gnu/13/:/usr/libexec/gcc-cross/x86_64-linux-gnu/13/:/usr/libexec/gcc-cross/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/bin/
libraries: =/usr/lib/gcc-cross/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/13/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/../lib/:/lib/x86_64-linux-gnu/13/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/13/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc-cross/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/lib/:/lib/:/usr/lib/
alizj@lima-dev2:~$

开发者选项
#

-dletters -dumpspecs -dumpmachine -dumpversion -dumpfullversion -fcallgraph-info[=su,da]

-fdump-lang-all -fdump-lang-switch -fdump-lang-switch-options

-print-file-name=library -print-libgcc-file-name -print-multi-directory -print-multi-lib -print-multi-os-directory -print-prog-name=program -print-search-dirs -Q -print-sysroot -print-sysroot-headers-suffix

❯ gcc-14  -dumpmachine
aarch64-apple-darwin24

❯ gcc-14  -dumpversion
14

❯ gcc-14  -fdump-lang-all
gcc-14: fatal error: no input files
compilation terminated.

❯ gcc-14 -print-sysroot
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk

❯ ls /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/
bin/  include/  lib/  libexec/  share/

❯ ls  /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/std*.h
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stddef.h
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdint.h
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdio.h
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/stdlib.h

❯ ls -l /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/lib[cm].tbd
lrwxr-xr-x 1 root 13 Dec 13 15:21 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libc.tbd -> libSystem.tbd
lrwxr-xr-x 1 root 13 Dec 13 15:21 /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/lib/libm.tbd -> libSystem.tbd

gcc 使用的环境变量
#

https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Environment-Variables.html

预处理时搜索头文件路径:

  • CPATH/C_INCLUDE_PATH/CPLUS_INCLUDE_PATH/OBJC_INCLUDE_PATH:
    • Each variable’s value is a list of directories separated by a special character, much like PATH, in which to look for header files
    • CPATH specifies a list of directories to be searched as if specified with -I, but after any paths given with -I options on the command line. This environment variable is used regardless of which language is being preprocessed.

gcc 动态链接时查找的库路径(类似 PATH ,是冒号分割):

  • LIBRARY_PATH: (but directories specified with -L come first) 注意不是 LD_LIBRARY_PATH,后者是运行动态链接的二进制时查找动态库路径。

注: gcc 不使用 CC、CXX 等环境变量。

查看 ELF 文件
#

# file: 二进制文件类型
alizj@ubuntu:/Users/alizj/docs/lang/c$ gcc -g array.c
array.c: In function ‘test_gnu_exten’:
array.c:243:16: warning: comparison of distinct pointer types lacks a cast
  243 |         if (p1 == p2) {
      |                ^~
alizj@ubuntu:/Users/alizj/docs/lang/c$ file a.out
a.out: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=65fc4878afb8bc32509a2df7717d2646e1c4e351, for GNU/Linux 3.7.0, with debug_info, not stripped

# nm: 检查符号表
alizj@ubuntu:/Users/alizj/docs/lang/c$ nm a.out
0000000000000278 r __abi_tag
                 U abort@GLIBC_2.17
0000000000020018 B __bss_end__
0000000000020018 B _bss_end__
0000000000020010 B __bss_start
0000000000020010 B __bss_start__
00000000000008b4 t call_weak_fn
0000000000020010 b completed.0
0000000000000bac T concat_fopen
                 w __cxa_finalize@GLIBC_2.17
0000000000020000 D __data_start
0000000000020000 W data_start
00000000000008d0 t deregister_tm_clones
0000000000000940 t __do_global_dtors_aux
000000000001fd50 d __do_global_dtors_aux_fini_array_entry
0000000000020008 D __dso_handle
000000000001fd58 a _DYNAMIC
0000000000020010 D _edata
0000000000020018 B __end__
0000000000020018 B _end
0000000000001138 T _fini
0000000000000d0c T foo
                 U fopen@GLIBC_2.17
0000000000000990 t frame_dummy
000000000001fd48 d __frame_dummy_init_array_entry
00000000000014f4 r __FRAME_END__
000000000001ffc8 a _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000012e8 r __GNU_EH_FRAME_HDR
0000000000000798 T _init
0000000000001150 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
                 U __libc_start_main@GLIBC_2.34
0000000000000d84 T main
                 U malloc@GLIBC_2.17
                 U printf@GLIBC_2.17
0000000000000900 t register_tm_clones
                 U __stack_chk_fail@GLIBC_2.17
                 U __stack_chk_guard@GLIBC_2.17
0000000000000880 T _start
                 U strcat@GLIBC_2.17
                 U strcpy@GLIBC_2.17
                 U strlen@GLIBC_2.17
0000000000000998 T sum
00000000000009f0 T sumB
0000000000000a40 T sumC
0000000000000b08 T sumD
0000000000001048 T test_gnu_exten
0000000000020010 D __TMC_END__

# ldd: 查看动态链接库
alizj@ubuntu:/Users/alizj/docs/lang/c$ ldd a.out
	linux-vdso.so.1 (0x0000ffff8e02f000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffff8ddf0000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffff8dfe0000)

相关文章

C 预处理器-个人参考手册
··8475 字
Gnu Cpp
这是我个人的 C 预处理器参考手册文档。
链接器 ld
··6277 字
Gnu Gcc Ld
使用 musl 交叉编译和静态链接
··2322 字
Cgo Go Compile Gcc Musl
本文介绍了使用轻量化 libc 库 musl 进行交叉编译生成多架构二进制的方案,最终实现在 x86_64 编译机器上能同时构建出静态链接的 x86_64 和 aarch64 二进制的目标,大大简化了多套构建脚本的开发和维护成本。
GCC 交叉编译工具链
·6210 字
Cgo Go Compile Gcc
交叉编译是指编译器能生成和它执行环境不同的 CPU 架构的二进制,例如在 arm64 机器上编译出在 x86_64 机器上运行的二进制。 本文分别以常用的 ubuntu aarch64 和 fedora 40 x86_64 编译环境为例,介绍这两个问题的解决方案。