水一篇:gcc -o在干什么

auther: abinng date: 2026-02-01 10:55 createDate:2026-02-01 10:55

前言

前什么言?直接开始

提前准备的程序

我提前准备了一个.c文件hello.c

1
2
touch hello.c
vim hello.c
1
2
3
4
5
6
#include <stdio.h>

int main() {
printf("Hello World!\n");
return 0;
}

保存退出

这里默认你已经有gcc了,如果没有,emm….去装一下

Linux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
➜  Code_OS gcc -v -o build hello.c 
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04.2' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --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-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-2Y5pKs/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-2Y5pKs/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04.2)
COLLECT_GCC_OPTIONS='-v' '-o' 'build' '-mtune=generic' '-march=x86-64' '-dumpdir' 'build-'
/usr/lib/gcc/x86_64-linux-gnu/11/cc1 -quiet -v -imultiarch x86_64-linux-gnu hello.c -quiet -dumpdir build- -dumpbase hello.c -dumpbase-ext .c -mtune=generic -march=x86-64 -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccskptD9.s
GNU C17 (Ubuntu 11.4.0-1ubuntu1~22.04.2) version 11.4.0 (x86_64-linux-gnu)
compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/11/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/11/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C17 (Ubuntu 11.4.0-1ubuntu1~22.04.2) version 11.4.0 (x86_64-linux-gnu)
compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 4011c2103cba78949d7e02d0f0047a3d
COLLECT_GCC_OPTIONS='-v' '-o' 'build' '-mtune=generic' '-march=x86-64' '-dumpdir' 'build-'
as -v --64 -o /tmp/ccyULprM.o /tmp/ccskptD9.s
GNU assembler version 2.38 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.38
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/11/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/11/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'build' '-mtune=generic' '-march=x86-64' '-dumpdir' 'build.'
/usr/lib/gcc/x86_64-linux-gnu/11/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/11/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper -plugin-opt=-fresolution=/tmp/ccitT9ze.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 -m elf_x86_64 --hash-style=gnu --as-needed -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o build /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/11/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/11 -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/11/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/11/../../.. /tmp/ccyULprM.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/11/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-o' 'build' '-mtune=generic' '-march=x86-64' '-dumpdir' 'build.'

这段输出是你运行 gcc -v -o build hello.c 命令产生的结果。

  • -v: 表示 Verbose(详细模式),让 GCC 打印出它在编译过程中执行的所有具体步骤和配置信息。
  • -o build: 指定输出的可执行文件名为 build
  • hello.c: 源文件。

GCC(GNU Compiler Collection)实际上是一个驱动程序(Driver),它并不直接干活,而是指挥其他程序(预处理器、编译器、汇编器、链接器)来完成工作。

我们可以把这段复杂的输出分为四个主要部分来解读:

第一部分:GCC 的配置信息 (Configuration)

从开头到 gcc version ... 这一大段。

1
2
3
4
5
6
7
Using built-in specs.
COLLECT_GCC=gcc
...
Target: x86_64-linux-gnu
Configured with: ../src/configure ...
...
gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04.2)
  • Targetx86_64-linux-gnu 表示目标架构是 64位 Linux。
  • Configured with: 这里列出了当初编译安装这个 GCC 版本时所使用的所有参数(比如支持哪些语言、安装路径在哪里、启用了哪些特性等)。
  • gcc version: 你当前使用的版本是 GCC 11.4.0。

第二部分:编译 (Compilation) —— cc1

这是将 C 代码转换为汇编代码的步骤。

1
/usr/lib/gcc/x86_64-linux-gnu/11/cc1 -quiet -v ... hello.c ... -o /tmp/ccskptD9.s
  • cc1: 这是真正的 C 编译器核心程序。

  • 输入hello.c

  • 输出-o /tmp/ccskptD9.s。它把 C 代码翻译成了汇编代码,并临时保存在 /tmp 目录下的一个 .s 文件中。

  • 头文件搜索路径:
    输出中还有一段 #include "..." search starts here:,列出了编译器去哪里找头文件(比如 <stdio.h>):

    1
    2
    3
    4
    /usr/lib/gcc/x86_64-linux-gnu/11/include
    /usr/local/include
    /usr/include/x86_64-linux-gnu
    /usr/include

第三部分:汇编 (Assembly) —— as

这是将汇编代码转换为机器代码(目标文件)的步骤。

1
as -v --64 -o /tmp/ccyULprM.o /tmp/ccskptD9.s
  • as: 这是 GNU Assembler(汇编器)。
  • 输入/tmp/ccskptD9.s(上一步生成的汇编文件)。
  • 输出-o /tmp/ccyULprM.o。它把汇编代码翻译成了机器码(Object file,目标文件),也是临时保存在 /tmp 下。

第四部分:链接 (Linking) —— collect2

这是将目标文件和系统库组合成最终可执行文件的步骤。

1
/usr/lib/gcc/x86_64-linux-gnu/11/collect2 ... -o build ... /tmp/ccyULprM.o -lgcc ... -lc ...
  • collect2: 这是 GCC 的链接器包装器(通常它内部会调用 ld 链接器)。
  • 输入:
    • /tmp/ccyULprM.o: 刚才生成的你的代码的目标文件。
    • Scrt1.ocrti.ocrtbeginS.ocrtendS.ocrtn.o: 这些是 C Runtime (CRT) 启动文件。它们包含了程序启动(在 main 函数之前)和退出所需的初始化代码。
    • -lgcc-lgcc_s-lc: 链接标准 C 库(libc)和 GCC 内部库。
  • 输出-o build。最终生成了名为 build 的可执行文件。

总结

你的一条命令 gcc hello.c -o build 实际上触发了以下流水线:

  1. cc1 (编译器): hello.c (C语言) -> .s (汇编语言)
  2. as (汇编器): .s (汇编语言) -> .o (机器码)
  3. collect2/ld (链接器): .o + 系统启动文件 + C标准库 -> build (最终可执行程序)

-v 参数只是把幕后的这一切“黑盒操作”打印给你看了。

Windows

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
PS D:\07_Downloads> gcc -v -o build hello.c
specs
COLLECT_GCC=D:\09_SW\_Dev\TDM-GCC-64\bin\gcc.exe
COLLECT_LTO_WRAPPER=D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/lto-wrapper.exe
x86_64-w64-mingw32
../../../src/gcc-git-10.3.0/configure --build=x86_64-w64-mingw32 --enable-targets=all --enable-languages=ada,c,c++,fortran,jit,lto,objc,obj-c++ --enable-libgomp --enable-lto --enable-graphite --enable-cxx-flags=-DWINPTHREAD_STATIC --disable-build-with-cxx --disable-build-poststage1-with-cxx --enable-libstdcxx-debug --enable-threads=posix --enable-version-specific-runtime-libs --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --disable-libstdcxx-pch --enable-libstdcxx-threads --enable-libstdcxx-time=yes --enable-mingw-wildcard --with-gnu-ld --disable-werror --enable-nls --disable-win32-registry --enable-large-address-aware --disable-rpath --disable-symvers --prefix=/mingw64tdm --with-local-prefix=/mingw64tdm --with-pkgversion=tdm64-1 --with-bugurl=https://github.com/jmeubank/tdm-gcc/issues
posix
Supported LTO compression algorithms: zlib zstd
gcc 10.3.0 (tdm64-1)
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'
D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/cc1.exe -quiet -v -iprefix D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/ -D_REENTRANT hello.c -quiet -dumpbase hello.c -mtune=generic -march=x86-64 -auxbase hello -version -o C:\Users\abinng\AppData\Local\Temp\ccfDrkef.s
GNU C17 (tdm64-1) version 10.3.0 (x86_64-w64-mingw32)
compiled by GNU C version 10.3.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.23-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "D:/09_SW/_Dev/TDM-GCC-64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.3.0/include"
ignoring duplicate directory "D:/09_SW/_Dev/TDM-GCC-64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../include"
ignoring duplicate directory "D:/09_SW/_Dev/TDM-GCC-64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.3.0/include-fixed"
ignoring duplicate directory "D:/09_SW/_Dev/TDM-GCC-64/lib/gcc/../../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/include"
#include "..." search starts here:
#include <...> search starts here:
D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/include
D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../include
D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/include-fixed
D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/include
End of search list.
GNU C17 (tdm64-1) version 10.3.0 (x86_64-w64-mingw32)
compiled by GNU C version 10.3.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.23-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 68074fcaab9f6b1377b55f7cea05149b
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'
D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/as.exe -v -o C:\Users\abinng\AppData\Local\Temp\ccQQ89Cx.o C:\Users\abinng\AppData\Local\Temp\ccfDrkef.s
GNU assembler version 2.36.1 (x86_64-w64-mingw32) using BFD version (GNU Binutils) 2.36.1
COMPILER_PATH=D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/;D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/;D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/
LIBRARY_PATH=D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/;D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/;D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/;D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../lib/;D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/;D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'
D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/collect2.exe -plugin D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/liblto_plugin-0.dll -plugin-opt=D:/09_SW/_Dev/TDM-GCC-64/bin/../libexec/gcc/x86_64-w64-mingw32/10.3.0/lto-wrapper.exe -plugin-opt=-fresolution=C:\Users\abinng\AppData\Local\Temp\ccGtJPgp.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lkernel32 -m i386pep --exclude-libs=libpthread.a --undefined=__xl_f -Bdynamic -o build.exe D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/crtbegin.o -LD:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0 -LD:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc -LD:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib -LD:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../lib -LD:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib -LD:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../.. C:\Users\abinng\AppData\Local\Temp\ccQQ89Cx.o -lmingw32 -lgcc -lpthread -lgcc -lkernel32 -lmoldname -lmingwex -lmsvcrt -lkernel32 -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc -lpthread -lgcc -lkernel32 -lmoldname -lmingwex -lmsvcrt -lkernel32 D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o D:/09_SW/_Dev/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/crtend.o
COLLECT_GCC_OPTIONS='-v' '-o' 'build.exe' '-mtune=generic' '-march=x86-64'

这段输出和你之前在 Linux 上看到的逻辑是一模一样的,但这回是在 Windows 11 环境下运行的。

你使用的是 TDM-GCC(GCC 的一个 Windows 移植版本,基于 MinGW-w64)。

虽然流程还是“编译 -> 汇编 -> 链接”,但在 Windows 上,链接(Linking) 这一步涉及的系统库要比 Linux 复杂得多。

我们同样分四步来解读:

第一部分:环境配置 (Configuration)

1
2
3
Target: x86_64-w64-mingw32
...
gcc version 10.3.0 (tdm64-1)
  • Targetx86_64-w64-mingw32
    • x86_64: 64位架构。
    • w64: 指向 Windows 64位。
    • mingw32: 代表 Minimalist GNU for Windows。这是让 GCC 能在 Windows 上运行并生成 Windows 程序(.exe)的关键工具集。
  • 版本: 你使用的是 GCC 10.3.0 (TDM-GCC 版本)。

第二部分:编译 (Compilation) —— cc1.exe

1
D:/.../cc1.exe ... hello.c ... -o C:\Users\abinng\AppData\Local\Temp\ccfDrkef.s
  • 程序cc1.exe(Windows下多了 .exe 后缀)。
  • 输入hello.c
  • 输出: 汇编代码被输出到了你的用户临时目录 C:\Users\abinng\AppData\Local\Temp\ 下,文件名为 ccfDrkef.s
  • 头文件路径: 编译器去 D:/09_SW/_Dev/TDM-GCC-64/... 下面找 <stdio.h> 等头文件,而不是 Linux 下的 /usr/include

第三部分:汇编 (Assembly) —— as.exe

1
D:/.../as.exe -v -o C:\Users\abinng\AppData\Local\Temp\ccQQ89Cx.o C:\Users\abinng\AppData\Local\Temp\ccfDrkef.s
  • 程序as.exe(汇编器)。
  • 输入: 刚才生成的临时汇编文件 .s
  • 输出: 生成了机器码目标文件 .o,也放在 Temp 目录下。

第四部分:链接 (Linking) —— collect2.exe

这是 Linux 和 Windows 区别最大的地方。

1
D:/.../collect2.exe ... -o build.exe ... -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -lkernel32 ...
  • 程序collect2.exe(链接器包装器)。
  • 输出build.exe(Windows 可执行文件)。
  • 链接的库 (Libraries):
    在 Linux 上,你主要链接 libc。但在 Windows 上,为了让一个 C 程序能跑起来,GCC 必须链接一大堆 Windows 特有的库:
    • -lmingw32-lmingwex: MinGW 的运行时库,用来填补 Linux 和 Windows 之间的差异。
    • -lmsvcrtMicrosoft Visual C Runtime。这是 Windows 系统自带的 C 标准库(相当于 Linux 的 glibc)。
    • -lkernel32: Windows 内核 API(处理内存、进程、文件IO等核心功能)。
    • -luser32: 用户界面 API。
    • -lshell32-ladvapi32: 其他 Windows 系统服务。
  • 启动文件:
    • crt2.ocrtbegin.o: Windows 程序的启动代码(负责在调用 main() 之前初始化环境)。
    • default-manifest.o: 这是一个 Windows 特有的东西。它包含了一个 XML 清单,告诉 Windows 11 这个程序支持高 DPI 显示,或者需要什么样的权限。

总结:Linux vs Windows

步骤 Linux (Ubuntu) Windows (TDM-GCC)
编译器核心 cc1 cc1.exe
路径风格 /usr/lib/... D:\09_SW\...
临时文件 /tmp/... C:\Users\abinng\AppData\Local\Temp\...
最终产物 ELF 格式 (无后缀) PE 格式 (.exe)
核心依赖库 glibc (GNU C Library) msvcrt.dll (微软 C 库) + kernel32.dll (WinAPI)
中间层 MinGW (负责把 GCC 的指令翻译成 Windows 能懂的 API)

简单来说,这段日志展示了 GCC 如何在 Windows 上“入乡随俗”,把你的 C 代码和 Windows 庞大的 DLL 系统库(Kernel32, User32 等)拼接在一起,生成一个双击就能运行的 .exe 文件。