以下内容参考C++ 程序编译过程:从代码到程序_c++代码写好了怎么生成应用程序-CSDN博客
编译流程
程序 g++ 是将 gcc 默认语言设为 C++ 的一个特殊的版本,链接时它自动使用 C++ 标准库而不用 C 标准库。
首先在自己的文件夹下分别创建math.h\math.c\main.cpp三个文件,文件结构如下:
>include
>>math.h
>>math.c
>main.cpp
文件内容分别如下:
math.h
#ifndef MATH_APP
#define MATH_APP
int add(int l, int r);
#endif
math.c
#include "math.h"
int add(int l, int r)
{
return l + r;
}
main.cpp
#include <stdlib.h>
#include <stdio.h>
#include "math.h"
#define a 10
#define b 20
int main()
{
int c = add (a , b);
printf("c=%d", c);
system("pause");
return 0;
}
接下来在文件夹下打开cmd开始执行编译流程:
预处理
g++ -E -Iinclude main.cpp -o main.i
-E 告诉编译器执行完预处理就退出
-Iinclude 指定文件夹 include 为头文件目录,此处使用 -I./include 同理
-o 指定输出文件名
编译
g++ -S -Iinclude main.i -o main.s
-S 告诉编译器执行完编译就退出
-Iinclude 指定文件夹 include 为头文件目录,此处使用 -I./include 同理
-o 指定输出文件名
汇编
g++ -c -Iinclude main.s -o main.o
-c 告诉编译器执行到汇编操作退出
-o 指定输出文件名
链接
链接前需要准备好math.c的目标文件:
g++ -c ./include/math.c -o math.o
然后进行链接:
g++ main.o math.o -o main.exe
成功后双击main.exe结果如下:
关于extern "C"
其实我想了解C/C++编译流程的初衷还是想理解extern "C"的使用,所以这里必须得说一下。
上面的math.c我们是用g++编译的,它会按照C++的方式给函数add生成符号表符号,因此main.cpp在链接main.o的时候是不会出问题的,但是如果我们用gcc去编译math.c后再链接呢?
gcc -c ./include/math.c -o math.o
g++ math.o main.o -o main.exe
此时会出现以下问题:
main.o:main.cpp:(.text+0x1e): undefined reference to `add(int, int)'
collect2.exe: error: ld returned 1 exit status
main.o去链接math.o的时候找不到add函数,因为g++编译器按照C++的方式去寻找add函数对应的符号,大概会是类似于__addii这种,怎么解决这个问题呢?
在math.h中加extern "C"的宏定义:
#ifndef MATH_APP
#define MATH_APP
#ifdef __cplusplus
extern "C" {
#endif
int add(int l, int r);
#ifdef __cplusplus
}
#endif
#endif
等于是告诉g++编译器在连接的时候,add这个函数需要按照C的方式去需要对应的符号,此时对main.cpp重新编译再进行链接就成功了:
g++ -c -Iinclude main.cpp -o main.o
g++ main.o math.o -o main.exe