gcc 编译器个人参考手册。
GCC 编译器 #
GCC 代表 “GNU Compiler Collection”, 主要支持 C, C++, Objective-C, Objective-C++, Fortran, Ada, D, and Go 语言。
GCC 语言无关的实现包括各种优化,以及为各种处理器生成机器码的“back ends” 。
GCC 语言相关的实现称为 “front end”。
调用 gcc 命令的三种方式:
- gcc
- machine-gcc
- 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
-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)