头文件、源文件和库
一般惯例
头文件 :包括函数、结构体、类、变量等的声明,一般不包含核心变量及函数的定义与实例。
源文件 :包括函数的定义、变量的定义、类的定义等成分。
库文件 :包括函数的定义、变量的定义、类的定义等成分,由源文件生成。
举例:cstdio
头文件:cstdio
1 2 3 ... int __cdecl printf (const char * __restrict__ _Format,...) ;...
源文件:main.cpp
1 2 3 4 5 6 7 #include <cstdio> #include <cstdlib> int main () { printf ("hello, world!\n" ); return EXIT_SUCCESS; }
库文件:libstdc++.a
可执行程序的生成流程
编译器及版本
1 2 3 4 g++.exe (x86_64-win32-seh-rev3, Built by MinGW-W64 project) 12.1.0 Copyright (C) 2022 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
预处理
对源文件所有预处理代码进行转义等操作。
1 g++ -E main.cpp -o main.cxx
文件:main.cxx
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 # 0 ".\\main.cpp" # 0 "<built-in>" # 0 "<command-line>" # 1 ".\\main.cpp" # 1 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/cstdio" 1 3 # 39 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/cstdio" 3 # 40 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/cstdio" 3 # 1 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 1 3 # 296 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 3 # 296 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 3 namespace std{ typedef long long unsigned int size_t ; typedef long long int ptrdiff_t ; typedef decltype (nullptr ) nullptr_t ; #pragma GCC visibility push(default) extern "C++" __attribute__ ((__noreturn__, __always_inline__)) inline void __terminate() noexcept { void terminate () noexcept __attribute__ ((__noreturn__)) ; terminate (); } #pragma GCC visibility pop } # 329 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 3 namespace std{ inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11" ))) { } } namespace __gnu_cxx{ inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11" ))) { } } # 508 "C:/Users/shuij/Documents/portables/mingw64/lib/gcc/x86_64-w64-mingw32/12.1.0/include/c++/x86_64-w64-mingw32/bits/c++config.h" 3 ... ... namespace std{ using ::__gnu_cxx::lldiv_t ; using ::__gnu_cxx::_Exit; using ::__gnu_cxx::llabs; using ::__gnu_cxx::div; using ::__gnu_cxx::lldiv; using ::__gnu_cxx::atoll; using ::__gnu_cxx::strtof; using ::__gnu_cxx::strtoll; using ::__gnu_cxx::strtoull; using ::__gnu_cxx::strtold; } } # 3 ".\\main.cpp" 2 # 4 ".\\main.cpp" using namespace std;int main () { printf ("hello, world!\n" ); return # 9 ".\\main.cpp" 3 0 # 9 ".\\main.cpp" ; }
编译
将转义完成的C++文件转化为汇编代码
1 g++ -S main.cxx -o main.s
文件:main.s
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 .file "main.cxx" .text .section .text$_Z6printfPKcz,"x" .linkonce discard .globl _Z6printfPKcz .def _Z6printfPKcz; .scl 2; .type 32; .endef .seh_proc _Z6printfPKcz _Z6printfPKcz: .LFB10: pushq %rbp .seh_pushreg %rbp pushq %rbx .seh_pushreg %rbx subq $56, %rsp .seh_stackalloc 56 leaq 48(%rsp), %rbp .seh_setframe %rbp, 48 .seh_endprologue movq %rcx, 32(%rbp) movq %rdx, 40(%rbp) movq %r8, 48(%rbp) movq %r9, 56(%rbp) leaq 40(%rbp), %rax movq %rax, -16(%rbp) movq -16(%rbp), %rbx movl $1, %ecx movq __imp___acrt_iob_func(%rip), %rax call *%rax movq %rax, %rcx movq 32(%rbp), %rax movq %rbx, %r8 movq %rax, %rdx call __mingw_vfprintf movl %eax, -4(%rbp) movl -4(%rbp), %eax addq $56, %rsp popq %rbx popq %rbp ret .seh_endproc .def __main; .scl 2; .type 32; .endef .section .rdata,"dr" .LC0: .ascii "hello, world!\12\0" .text .globl main .def main; .scl 2; .type 32; .endef .seh_proc main main: .LFB80: pushq %rbp .seh_pushreg %rbp movq %rsp, %rbp .seh_setframe %rbp, 0 subq $32, %rsp .seh_stackalloc 32 .seh_endprologue call __main leaq .LC0(%rip), %rax movq %rax, %rcx call _Z6printfPKcz movl $0, %eax addq $32, %rsp popq %rbp ret .seh_endproc .ident "GCC: (x86_64-win32-seh-rev3, Built by MinGW-W64 project) 12.1.0" .def __mingw_vfprintf; .scl 2; .type 32; .endef
汇编
将汇编代码转化为二进制机器码
链接
将所有二进制机器码进行统一,生成可执行文件
一步生成
1 g++ main.cpp -o main.exe
总览