汉字魔法师
118.67M · 2026-02-04
C++代码到可执行程序的生成过程主要分为四个阶段,让我详细解释:
// 预处理前:main.cpp
#include <iostream>
#define PI 3.14159
int main() {
std::cout << "PI = " << PI << std::endl;
}
预处理操作:
#include 文件包含 → 将头文件内容插入#define 宏替换 → 将PI替换为3.14159#ifdef/#endif 条件编译执行命令:
g++ -E main.cpp -o main.i # 生成预处理文件
将预处理后的代码翻译成汇编语言
编译过程:
# 生成的汇编代码示例 (main.s)
main:
pushq %rbp
movq %rsp, %rbp
movl $.LC0, %esi
movl std::cout, %edi
call std::basic_ostream<char>::operator<<
...
执行命令:
g++ -S main.i -o main.s # 生成汇编文件
将汇编代码转换为机器码(目标文件)
g++ -c main.s -o main.o # 生成目标文件
目标文件 (.o/.obj) 包含:
将多个目标文件和库文件合并成可执行文件
g++ main.o -o main # 链接生成可执行文件
链接主要任务:
# 一步完成所有过程
g++ main.cpp -o main
# 分步骤编译
g++ -c main.cpp # 编译成目标文件
g++ main.o -o main # 链接成可执行文件
// 文件结构:
// main.cpp
// math.cpp
// math.h
# 方法1:分别编译再链接
g++ -c main.cpp -o main.o
g++ -c math.cpp -o math.o
g++ main.o math.o -o program
# 方法2:一次编译多个文件
g++ main.cpp math.cpp -o program
CXX = g++
CXXFLAGS = -std=c++11 -Wall
TARGET = program
OBJS = main.o math.o
$(TARGET): $(OBJS)
$(CXX) $(CXXFLAGS) -o $@ $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) -c $< -o $@
clean:
rm -f $(OBJS) $(TARGET)
| 选项 | 说明 |
|---|---|
-o <file> | 指定输出文件名 |
-c | 只编译不链接 |
-I <dir> | 添加头文件搜索路径 |
-L <dir> | 添加库文件搜索路径 |
-l<name> | 链接库文件 |
-std=c++11 | 指定C++标准 |
-Wall | 开启所有警告 |
-O2 | 优化等级2 |
-g | 包含调试信息 |
// 示例项目结构
// main.cpp
#include <iostream>
#include "math_utils.h"
int main() {
std::cout << add(5, 3) << std::endl;
return 0;
}
// math_utils.h
#pragma once
int add(int a, int b);
// math_utils.cpp
#include "math_utils.h"
int add(int a, int b) {
return a + b;
}
编译过程:
# 1. 预处理
g++ -E main.cpp -o main.i
g++ -E math_utils.cpp -o math_utils.i
# 2. 编译
g++ -S main.i -o main.s
g++ -S math_utils.i -o math_utils.s
# 3. 汇编
g++ -c main.s -o main.o
g++ -c math_utils.s -o math_utils.o
# 4. 链接
g++ main.o math_utils.o -o program
# 或者一步到位
g++ main.cpp math_utils.cpp -o program
CMake(跨平台构建系统)
cmake_minimum_required(VERSION 3.10)
project(MyProject)
add_executable(program main.cpp math_utils.cpp)
Bazel(Google开源构建工具)
MSBuild(Visual Studio构建系统)
g++ -E -dD main.cppg++ -S -fverbose-asm main.cppnm main.oldd program(Linux)/ otool -L program(macOS)理解这个完整过程有助于: