c++多文件编译

一、基础知识

1、四步走

从源代码到程序,大概分为四个步骤:预处理–》编译–》汇编–》链接
1、预处理:
把源文件中的预处理指令全部替换完成,比如include 的头文件,会把头文件的内容都放到源文件中。这也是后续编译时命令参数不需要带头文件的原因,因为已经把内容取过来了,所以后续就不带头文件玩了。

g++ -E main.cpp -o main.i

2、编译
c++是独立编译,针对每一个.cpp文件,进行编译,寻找语法错误,生成汇编代码。此时各个模块都是独立的,还没有交流。当以后对某个源文件做修改时,只需要简单地重新编译它后重新链接到应用,而不需要编译其他文件。

g++ -S main.i -o main.s

3、汇编
将汇编文件中的汇编代码翻译成相应的机器语言

g++ -c main.s -o main.o

3、链接
链接就是把编译产生的目标文件和库一起组合成最终的程序。

g++ main.o -o MyApp

2、gcc/g++编译器

两者都是linux的编译器,用于编译代码,都来自GNU编译器集合。
gcc是GCC中的GUN C Compiler(C 编译器)
g++是GCC中的GUN C++ Compiler(C++编译器)
两者用法一致,区别是:

  • 对于.c 和.cpp文件,gcc分别当作c和cpp文件编译,cpp的语法规则比c强一点
  • 对于.c 和.cpp文件,g++默认当作cpp文件编译。事实上,g++在编译阶段,是直接调用gcc去编译的。
  • gcc命令不能自动与c++程序使用的库链接,所以通常使用g++来链接,但也可以使用gcc -lstdc++去链接。

------------------g++/gcc 选项 参数--------------------------------------------------------

-c 只编译,不链接成可执行文件,生成.o为后缀的目标文件
-o 输出文件 源文件 生成可执行文件,如果输出文件名未指定,默认a.out
-g 在编译时生成调试信息,使用gdb的时候需要添加这个参数
-On 对程序进行优化编译链接,n取值范围0-3,表示优化的级别,O0表示没有优化,O1缺省值,O3优化级别最高
-E 预处理后停下来,生成后缀为 .i 的预编译文件。
-S 汇编后停下来,生成后缀为 .s 的汇编源文件。
-I(i的大写) 目录 指定头文件所在目录
-D 在程序编译的时候,指定一个宏。方便调试,比如发布时隐藏log输出
-w 不生成警告信息
-Wall 生成所有警告信息,比如一些未用的变量
-l (L的小写) 在程序编译时指定使用的库
-L 指定编译的时候,搜索的库的路径
-fPIC/fpic 生成与位置无关的代码
-shared 生成共享目标文件,通常用在建立共享库
-std 指定c方言,比如 -std=c99

-D 简单举例

//main.cpp
#include <iostream>
using namespace std;

int main(){
   int a = 10;
#ifdef DEBUG
    cout<<"debug\n";
#endif
    cout<<a<<endl;

    return 0;
}

无参数编译:

g++ -o test main.cpp
输出 :
10

有参数编译(相当于在文件里提前定义一个#define DEBUG)

g++ -o test main.cpp -D DEBUG
输出 :
debug
10

3、多文件编译

ok,编译流程和工具都了解差不多了,然后是多文件编译
c++文件分类:

  • .h 头文件,放声明,记得使用条件编译语句防止被同一.cpp文件多次包含。
  • .cpp 模块文件,放定义,包含.h文件
  • .cpp 主程序文件, 包含main()文件,程序入口

1、同目录小例子

//fun1.h
#pragma once
#include <vector>
void fun1();

//fun1.cpp
#include <iostream>
#include "fun1.h"

void fun1(){
    std::cout<<"hello world"<<std::endl;
}

//main.cpp
#include <iostream>
#include "fun1.h"

int main(){
    fun1();
    return 0;
}

一次性编译:一步走完所有流程

g++ main.cpp fun1.cpp -o test

或者分阶段编译,相当于最开始说的第三步和第四步依次进行:

g++ -c main.cpp -o main.o
g++ -c fun1.cpp -o fun1.o
g++ main.o fun1.o -o test

这样的好处是修改其中一个模块时,只需要对这一个模块进行编译链接,其他模块不动。

2、不同目录

但如果这三个文件不在同一目录呢?应该怎么引用头文件呢?
如图:
目录
上述代码不变,在链接时肯定会找不到fun1.h.此时就需要添加 -I 选项,指明头文件所在目录

include 文件夹下执行 :g++ -c fun1.cpp -o fun1.o
src 文件夹下执行: g++ -c main.cpp -o test -I …/include

还有另一种,是直接在main.cpp里修改头文件路径

#include "/fun1.h"变成
#include “…/include/fun1.h”

再编译时就不需要指定目录了,但这样灵活性就差了许多。

g++ -c main.cpp -o test

补充:linux 下默认搜索头文件及库文件的路径

  • #include ”头文件“ :默认从当前的目录来搜索
  • #include <头文件>:会先搜索 -I 选项后的路径(即用gcc编译时的-I选项),之后就是标准的系统头文件路径。
  • 通过cpp -v命令,可以查看标准系统头文件的路径。
  • 基本上是三个目录:
    usr/include
    usr/lib/include
    usr/local/include

但无论怎样,上面一一列出文件的写法不适合大型项目,所以自动编译工具Makefile工具要上场啦。

4、Makefile自动编译工具

学习传送门

5、项目一般结构

  • include 存放.h文件
  • lib 存放库文件
  • build 存放执行文件和.o文件
  • src 存放.cpp文件
  • main.cpp
  • Makefile

参考链接

https://blog.nowcoder.net/n/8c828675830f4c958c0c9767548ef674
https://www.jianshu.com/p/e5c6a255076b
https://www.jianshu.com/p/3eb25114576e

  • 37
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在VSCode中进行C++文件编译可以按照以下步骤进行操作: 1. 确保您已安装C++扩展:在VSCode中,点击左侧的扩展图标(四个方块),并搜索并安装由Microsoft提供的"C++"扩展。 2. 在项目文件夹中创建源文件:在VSCode中,打开您的C++项目文件夹,并在其中创建您的C++文件。可以使用`.cpp`扩展名来保存源文件。 3. 创建一个构建任务:在VSCode中,使用快捷键`Ctrl + Shift + B`(Windows/Linux)或者`Cmd + Shift + B`(Mac)来打开构建任务菜单。如果是第一次使用,VSCode会提示您选择一个构建系统。选择"C++"来生成一个默认的构建任务。 4. 配置构建任务:VSCode会在项目文件夹中创建一个`tasks.json`文件,您可以在其中配置构建任务。根据您的项目需要,可以配置多个构建任务。例如,如果您有多个源文件需要编译,您可以在`tasks.json`文件中指定它们的编译命令和依赖关系。 5. 运行构建任务:在VSCode中,使用快捷键`Ctrl + Shift + B`(Windows/Linux)或者`Cmd + Shift + B`(Mac)选择您要运行的构建任务。 6. 查看输出信息:构建任务成功运行后,将在VSCode的终端中显示构建输出的信息。您可以查看编译错误、警告或生成的可执行文件等信息。 请注意,具体的步骤和配置可能因您的项目和开发环境而有所不同。您可能需要根据实际情况自定义构建任务和编译选项。 希望这些步骤能帮助您在VSCode中成功进行C++文件编译。如有任何问题,请随时向我提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值