gcc 编译器个人参考手册。
GCC 代表 “GNU Compiler Collection”, 支持 C, C++, Objective-C, Objective-C++, Fortran, Ada, D 和 Go 语言。
GCC 语言无关的实现,如优化,以及为各种处理器生成机器码,称为 “back ends” ,GCC 语言相关的实现称为 “front end”。
调用 gcc 的三种方式(后两种方式一般用于交叉编译场景):
- gcc
- machine-gcc:如 x86_64-linux-gnu-gcc;
- machine-gcc-version:如 x86_64-linux-gnu-gcc-13;
阶段性编译:
- gcc -E file.c > file.i Preprocesses the source code.
- gcc -S file.i -o file.S Compiles preprocessed source to assembly code.
- gcc -c file.S -o file.o Assembles code into an object file,不进行链接
- gcc file.o -o file Links object files into an executable.
可以直接使用 gcc 完成编译预处理、汇编和链接,所以一般不需要手动调用 cpp、as、ld 命令。
GCC 参数 #
GCC 14 参数索引:Option-Index
gcc -v
显示 gcc 支持的 CPU 架构(Target)和编译 gcc 时的配置参数:
--build
,--host
,--target
分别指定编译 gcc 的 CPU 架构类型;
# ubunut 版本 gcc
alizj@ubuntu:~$ gcc -v
...
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
会打印详细的编译命令,同时也可以通过 -W 来为调用的其它命令添加 -v 参数::
- -Wp,-v: 编译预处理详细参数;
- -v:编译详情, cc1 编译器的执行详情
- -Wa,-v: 汇编详情: 显示调用的 as 命令参数;
- -Wl,-v: 链接详情,显示 collect2 调用 ld 的详情;
-v 和 –help 连用时除了打印 gcc 自身参数外,还打印它调用的命令,如 cpp、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 是 cpp 包提供的预处理器
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.
# 汇编 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.'
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
调试 #
示例:
# Includes debugging information in the executable.
gcc -g file.c -o file
# Includes extensive debugging information with optimizations.
gcc -g3 file.c -o file
# Disables stack protection mechanisms.
gcc -fno-stack-protector file.c
# Prints compilation commands and version information.
gcc -v file.c
# Omits the frame pointer in the generated code.
gcc -fomit-frame-pointer file.c
# Strips symbol table and debugging info from the executable.
gcc -s file.c -o file
# Includes debugging information in the executable.
gcc -g file.c -o file
开启了 -g 或 -ggdb 选项后, 才在 ELF 文件中包含调试信息,后续 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.
-
-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.
优化 #
示例:
# Disables optimizations for easier debugging.
gcc -O0 file.c -o file
# Enables basic optimizations.
gcc -O1 file.c -o file
# Optimizes code for speed.
gcc -O2 file.c -o file
# Aggressively optimizes code for speed.
gcc -O3 file.c -o file
# Optimizes code for size.
gcc -Os file.c -o file
# Generates code for profile-guided optimization.
gcc -fprofile-generate file.c -o file
# Uses profiling data to optimize the code.
gcc -fprofile-use file.c -o file_optimized
默认不开启优化,等效于-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
。
警告 #
示例:
# Enables all commonly used compiler warnings.
gcc -Wall file.c
# Treats all compiler warnings as errors.
gcc -Werror file.c
良好的开发习惯是在编译时指定如下参数: -std=c23 -Wall -Wextra -Wpedantic
只检查语法,不做其它处理:
-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
profiling #
- -pg Generate extra code to write
profile information
suitable for the analysis program prof (for -p) or gprof (for -pg). - -p: 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
预处理 #
示例:
# Adds a directory to the list of include file search paths.
gcc -I /path/to/include file.c -o file
# Defines a macro for use in the source code.
gcc -DMACRO file.c
# Generates Makefile dependencies for the source file.
gcc -MM file.c
cpp 包提供了 cc1 命令,gcc 调用它来执行预处理(gcc -E),单独的 cpp 程序是为了兼容性。
- /usr/libexec/gcc/aarch64-linux-gnu/13/cc1
只运行预处理:-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.
编译 #
-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"
编译是从 C 源文件生成汇编文件(.s) 的过程。
架构相关 #
示例:
# Compiles code for a 32-bit architecture.
gcc -m32 file.c
# Compiles code for a 64-bit architecture.
gcc -m64 file.c
# Optimizes code for the build machine's CPU architecture.
gcc -march=native file.c -o file
# Enables AVX instructions in the generated code.
gcc -mavx file.c -o file
# Uses x87 FPU registers instead of SSE instructions.
gcc -mno-sse file.c
通用选项:
- -mabi=abi # 默认lp64,其它:ilp32
- -mcpu=processor[+extension…] # 例如 cortex-a710
- -march=architecture[+extension…] # 例如 armv9.5-a 或 armv9.4-a, cpa, lut, faminmax 或 -march=i686+sse4+vmx
aarch64 选项: -mbig-endian -mlittle-endian
汇编 #
汇编: 从汇编源文件(.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
链接 #
示例:
# Links the executable with the specified shared library.
gcc file.c -o file -lcppfile
# Links the static library into an executable.
gcc -o res main.c libhello.a
# Prints the full path of the specified library.
gcc -print-file-name=libc.so
# Adds a directory to the list of library search paths.
gcc -L /path/to/lib file.c -o file -lmylib
# Links all object files from the specified archive.
gcc -o file -Wl,--whole-archive lib.a -Wl,--no-whole-archive other.o
当指定以下参数时将不执行链接: -c(编译)/-S(汇编)/-E(预处理)
指定使用的链接器类型(默认为 bfd,gold 为较新的 ELF only 链接器但因缺乏维护,新版本的 binutils 已经去掉了):
- -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
传递给链接器的参数:
-
-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++ 这些选项告诉 gcc 在链接时不要使用标准库(如 glic) 和 gcc 提供的 C 程序启动文件(如 crt0.o),即不自动链接 C 库和其它启动代码。一般用于嵌入式开发、内核开发或自定义运行环境。
-
例如嵌入式系统的 bare metal 工具链 riscv64-unkonwn-elf-gcc 不需要链接 gcc 和 C 标准库,这时一般需要使用 -T 来指定自定义链接脚本,其中包含程序的执行入口 entry。
-
-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 可查询)。
静态和动态库 #
# Compiles source to object file.
gcc -c hello.c -o hello.o
# Creates a static library from object file.
ar -cvq libhello.a hello.o
# Generates position-independent code for shared libraries.
gcc -c -fPIC -o hello.o hello.c
# Creates a shared library from object file.
gcc -shared -o libhello.so hello.o
# Links the executable with a shared or static library.
gcc -o res main.c -L. -lhello
开发者选项 #
示例:
gcc -dumpversion Prints the GCC version.
gcc -dM -E - < /dev/null Prints all predefined macros.
gcc -Q --help=target Lists all target-specific options.
gcc -Q --help=optimizers Lists all optimization options.
gcc -no-pie file.c Disables position-independent executables.
gcc -nostdinc file.c Does not search standard include directories.
gcc -fdump-tree-all hello.c Dumps abstract syntax tree information.
gcc test.c -o test -Wa,-adhln=test.s -g -fverbose-asm -masm=intel Generates assembly with embedded source code lines.
-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 等环境变量。