一文看懂C/C++编译过程以及g++编译选项

news2025/1/21 11:29:05

前言

在linux系统下,输入man g++,即可以看到gcc官方文档对gcc编译选项的详细说明,本文也主要是在官方文档基础上,对gcc/g++编译过程和一些编译选项进行了总结和说明,希望对学习这块内容的人有所帮助。

1、编译的四个阶段

一般我们使用gcc/g++将源码编译为可执行文件,编译过程仔细划分的话,可以分为4个阶段:预处理、编译、汇编、链接。以add.cpp为源文件进行举例说明。

  • 预处理

这一步主要是替换掉源文件中定义的宏,比如替换#include包含的头文件,替换define定义的宏变量等。预处理之后的文件形式上还是源码,只是对源码有些地方做了替换。预处理后的文件名后缀为.ii 。

  • 编译

将预处理的之后的源码编译为汇编代码。汇编后缀为.s

  • 汇编

将汇编代码汇编生成目标文件。目标文件后缀为.o

  • 链接

将一个或几个目标文件链接在一起,形成一个可执行文件。

2、通过编译选项来控制编译过程

还是以add.cpp为例,如果要生成各个阶段的文件,可以通过编译选项来控制。

  • 生成预处理.ii文件

编译选项为 -E,这里一定要用-o 指定输出的文件名,不然默认是输出到屏幕。其它几个阶段可以不用指定输出文件名。

g++ add.cpp -E -o add.ii  #需要指定输出文件名,得到add.ii
  • 生成汇编.s文件

编译选项为-S,可以不用-o指定输文件名,默认为add.s,当然也可以指定。

g++ add.ii -S        # 默认输出文件名为add.s
# 也可以直接一步从源文件得到.s文件
g++ add.cpp -S  
  • 生成目标.o文件

编译选项为-c,可以不用-o指定输出文件名,默认为add.o。

g++ add.s -c       # 从汇编文件得到目标文件
# 也可以从源文件或与预处理后文件得到目标文件
g++ add.ii -c      # 从预处理之后的文件得到目标文件
  • 生成可执行文件

一般每个.cpp文件经过处理之后,都能得到一个目标.o文件,可以将多个目标文件链接成一个可执行文件。假如main.cpp,也生成了main.o文件,那么将main.o和add.o链接成一个可执行文件。

不需要编译选项,可以用-o指定可执行文件的文件名,如果不指定默认为a.out

g++ main.o add.o    # 默认生成a.out
g++ main.o add.o  -o main # 指定可以执行文件名为main

值得说明的是,编译选项只是指定编译过程的结束阶段,并未要求输入文件阶段,因此跳过中间某一个过程也是可以,比如从.cpp文件直接生成可以执行文件。涉及多个文件时,不同文件处于不同阶段也是可以的。比如一个为源文件,一个为汇编文件,然后用这个两个文件生成可执行性文件也是ok的:

g++ main.cpp add.s -o main

3、一个编译案例

假如main.cpp、add.cpp和add.h位于同一个目录下面,每个文件的具体内容如下:

// main.cpp
#include <iostream>
#include "add.h"
using namespace std;
int main ()
{
    cout << "add result is:" << add(500, 20) << endl;
    return 0;
}
// add.h
int add(int num1, int num2);
// add.cpp
#include "add.h"
int add(int num1, int num2) {
    return num1 + num2;
}

linux系统下,进入到三个文件所在目录,依次执行下面3个命令:

g++ add.cpp -E -o add.ii  # 生成add.ii
g++ add.ii -S             # 生成add.s
g++ add.s -c              # 生成add.o

会依次生成add.ii 、add.s、 add.o三个文件。此时目录文件情况为:

add.cpp add.h add.ii add.o add.s main.cpp

然后使用下面的命令,直接将main.cpp和add.o生成可以执行文件,相当与省略了main.cpp编译的中间过程。

g++ main.cpp add.o -o main

此时目录情况为:

add.cpp add.h add.ii add.o add.s main main.cpp

然后输入 ./main 可以看到打印如下,说明编译过程正确。

# add result is:520

4、g++编译选项总结

前面提到可以编译选项-E、-S、-c来指定编译的终止阶段,如果不加编译选项,默认生成可以执行文件。其它常用的编译选项有:

-o filename 指定输出文件名

-I dir,(大写i,可理解为include首字母),将dir添加到头文件的查找路径,即如果头文件在dir可以确保查找头文件成功。

-llibrary 或 -l library(不推荐),如果需要连接库library,指定链接库library。

-L dir,为-l中指定的库添加搜索目录dir,即如果library在dir可以确定搜索到

-shared以及-fpic或-fPIC,生成动态库时需要,pic表示postion independent code,即生成与位置无关的代码。

-std=standard,执行标准,如-std=c++11。

-g,编译时产生调试信息,比如要使用gdb进行调试,就要加上该选项。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/161115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Cannot read properties of null (reading ‘pickAlgorithm‘)

2568 verbose node v16.15.0 2569 verbose npm v8.5.5 2570 error Cannot read properties of null (reading ‘pickAlgorithm’) 2571 verbose exit 1 2572 timing npm Completed in 20918ms 2573 verbose unfinished npm timer reify 1673607123032 2574 verbose unfinished …

openSUSE-Leap-15.4系统分析和微调指南-略读笔记

openSUSE-Leap-15.4系统分析和微调指南——略读笔记 openSUSE Leap 15.4 System Analysis and Tuning Guide SUSE 产品文档-中文(简体)-下载中心 https://documentation.suse.com/zh-cn/sled/15-SP4/ 单击English选择简体中文——单击PDF是可以下载的&#xff0c;例如System A…

学习记录:featurecounts

Input one or more files of aligned reads (short or long reads) in either SAM or BAM formata list of genomic features in either Gene Transfer Format (GTF) or General Feature Format (GFF) or Simplified Annotation Format (SAF)比对后产生的bam或者sam文件&#…

一次简单的本机调试webshell的经历

环境安装 安装php和nginx&#xff0c;不再赘述 apt-get update apt-get install nginx这里我的版本是php7.4 # php -v PHP 7.4.33 (cli) (built: Jan 6 2023 16:10:36) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies with Zend …

Optional最佳实践(对象操作利器)

前篇文章已经总结了集合的操作是如何在Java8优化的&#xff1a;函数编程和Stream_txxs的博客-CSDN博客&#xff0c;这篇文章总结一下对于对象如何利用Java8进行操作&#xff0c;这样对于大部分代码都可以用Java8的语法进行操作了。 一、 Optional 是什么 Optional 的作者 Bri…

收购淘米后,MMV加速走向迪士尼式IP开发之旅

一家纯正的元宇宙控股公司与经典IP公司碰撞&#xff0c;能擦出怎样的火花&#xff1f;这个问题或将在不远的将来得出答案。 1月12日晚间&#xff0c;刚在一周前以SPAC方式登陆纳斯达克的MMV&#xff08;MultiMetaVerse&#xff0c;即“元宇宙控股”&#xff09;&#xff0c;宣…

C语言进阶——动态内存管理

目录 一. 为什么存在动态内存分配 二. 动态内存函数 1.malloc 2.free 3.calloc 4.realloc 三. 常见的动态内存错误 一. 为什么存在动态内存分配 在此之前&#xff0c;我们为数组开配空间都是这样的 int nums[10]{0}; 但这样会有很大的局限性 1. 空间开辟大…

十三、Gtk4-TfeTextView函数

TfeTextView相关函数在这一章节介绍 1 tfetextview.h 头文件tfetextview.h提供了: TfeTextView的类型&#xff0c;是TFE_TYPE_TEXT_VIEW。G_DECLARE_FINAL_TYPE的扩展包含了一些有用的宏。定义了open-response信号的常量。tfetextview.c的公共函数被声明。 因此&#xff0c…

「布道人生」第一期:阿里云DevOps资深专家章屹

本期嘉宾——章 屹 阿里云 DevOps 资深专家。2012 年加入阿里巴巴&#xff0c;十年如一日专注在 DevOps 领域的理论、咨询、解决方案和产品技术工作上。作为 CIO 学院和阿里云大学的讲师&#xff0c;为众多大型企业管理高层讲授 DevOps 课程&#xff0c;探讨通过 DevOps 提升企…

drawCell | 不会画细胞结构图就用这个R包吧~ Super Nice!~

1写在前面 我们在paper中经常需要画到细胞结构图&#xff0c;新手ppt一点一点画&#xff0c;高手可能会用AI手搓&#xff0c;土豪直接使用BioRender。&#x1f912; 今天给大家大家分享一个代码画细胞结构图的R包&#xff0c;如果你觉得自己不会写代码&#xff0c;不想看了&…

python基础篇之元组、字典(增删改查)

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a;lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

震旦ad188复印机报机器故障维修召唤c0211

故障现象: 手送走纸的机器出现嗒嗒的异响,走几张还会跳0211,经常出现卡纸等现象,或者报C0211; 故障分析: 维修召唤C0211可能是感光鼓和载体寿命到期࿰

云原生|Java二级高速缓存架构设计

为什么使用缓存 缓存&#xff0c;主要有两个用途&#xff1a;提高服务性能和并发。 缓存是提高服务响应速度最快的方式之一。 我们设计缓存的目的是减少用户直接访问磁盘、访问网络带来的性能损耗&#xff0c;把磁盘、网络请求的内容存在在内存中&#xff0c;提升应用程序的…

【Doris】Doris数据库最新版安装方法,详细图文教程

环境安装 Doris 作为一款开源的 MPP 架构 OLAP 数据库&#xff0c;能够运行在绝大多数主流的商用服务器上。为了能够充分运用 MPP 架构的并发优势&#xff0c;以及 Doris 的高可用特性&#xff0c;我们建议 Doris 的部署遵循以下需求&#xff1a; Linux 操作系统版本需求Linu…

研讨会回顾 | UI自动化测试现场演示

2022年12月6日&#xff0c;龙智与软件测试自动化“领导者”SmartBear联合举办了主题为“如何通过自动化测试实现降本、增效与提质”的在线研讨会。此次研讨会中&#xff0c;龙智技术工程师邱洁玉现场演示了使用UI自动化测试的过程&#xff0c;并简要介绍了API的自动化测试。 软…

时钟频率与时间单位的换算

1. 频率、时间 各自的单位的关系 频率&#xff1a; 1GHz 1000MHz、1MHz 1000KHz、1KHz 1000Hz 1GHz 103MHz 106KHz 109Hz 时间&#xff1a; 1s 1000ms、1ms 1000μs、1μs 1000ns [注]&#xff1a;s (秒)、ms (毫秒)、μs (微秒)、ns (纳秒)。 2. 时间 和 频率 的换…

jsp税务管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 jsp 税务管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开 发&#xff0c;数据库为Mysql&#xff0c;使用ja…

【SpringCloud10】OpenFeign服务接口调用

1.概述 1.1OpenFeign是什么 官网 Feign是一个声明式WebService客户端&#xff0c;使用Feign能让编写Web Service客户端更加简单。 它的使用方法是定义一个服务接口然后在上面添加注解&#xff0c;Feign也支持可拔插式的编码器和解码器&#xff0c;Spring Cloud对Feign进行了…

设计模式-JDBC中的桥接模式

一、首先看整个brige模式的结构图。如下&#xff1a;Abstraction — 抽象化角色&#xff1a;定义抽象的接口&#xff0c;包含一个对实现化角色的引用Refined Abstraciotn — 扩展抽象化角色&#xff1a;抽象化角色的子类&#xff0c;实现父类中的业务方法&#xff0c;并通过组合…

录屏专家怎么用?录屏软件使用教程(附下载)

想要更好地录制电脑屏幕可以使用电脑录屏专家&#xff0c;但有很多人在安装录屏专家之后&#xff0c;不知道如何使用。录屏专家怎么用&#xff1f;怎样使用录屏专家录制电脑屏幕&#xff1f;下面小编给您分享录屏软件使用的教程&#xff08;附安装教程&#xff09;&#xff0c;…