Linux编译器--gcc/g++使用方式

2025-02-08 04:50

本文主要是介绍Linux编译器--gcc/g++使用方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Linux编译器--gcc/g++使用方式》文章主要介绍了C/C++程序的编译过程,包括预编译、编译、汇编和链接四个阶段,并详细解释了每个阶段的作用和具体操作,同时,还介绍了调试和发布版本的概念...

一、预编译指令

1.1预处理功能

  • 去掉注释js
  • 头文件的展开
  • 条件编译
  • 宏替换

1.2指令

  • 预处理指令是以#号开头的代码行
  • gcc下使用:gcc -E code.c -o code.i 来生成可执行文件
  • 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程
  • 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序

实例:

Linux编译器--gcc/g++使用方式

Linux编译器--gcc/g++使用方式

1.3问题扩展

为什么能在linux下进行C/C++或者其他形式的开发呢?

  • C/C++开发环境不只是指gcc、g++、vs等编译器,更重要的是语言本身的头文件和库文件
  • 在进行开发前,系统中一定要提前安装或者后续安装上C/C++相应的头文件和库
  • 对于编译型语言,在选择对应的开发包进行下载时,必定也在同步下载头文件和库文件
  • 使用ls /usr/include 可以查看Linux下包含的所以头文件

Linux编译器--gcc/g++使用方式

  • 条件编译的应用场景
  • 根据编译条件,裁剪掉某些社区版编译器所不需要的功能
  • 经过预处理的源文件也是C语言

二、编译(生成汇编)

  • 在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言
  • 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码

实例:

gcc -S code.i -o code.s

Linux编译器--gcc/g++使用方式

Linux编译器--gcc/g++使用方式

三、汇编(生成二进制机器语言)

  • 汇编阶段是把编译阶段生成的“.s”文件转成目标文件(可重定向二进制目标文件,.obj)
  • 可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码
  • 生成的目标文件虽然是二进制,但是不能独立运行,要和库进行链接形成可执行文件才能执行

实例:

gcc -c code.s -o code.o
http://www.chinasem.cn

Linux编译器--gcc/g++使用方式

Linux编译器--gcc/g++使用方式

四、链接(生成可执行文件或库文件)

4.1库文件

我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声China编程明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到 系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用

  • 库文件实际上是.c(源文件)经过一定的翻译打包后形成的一个文件——可以达到只需要提供一个文件不需要提供多个源文件,隐藏源文件的功能
  • 软件=头文件中方法的声明+库文件中方法的实现+代码
  • Windows下存在以.javascriptdll为后缀的动态库和以.lib为后缀的静态库
  • Linux下存在以.so为后缀的动态库和以.a为后缀的静态库

如何查看Linux的动态库和静态库?

ls /usr/lib64/libc.so*

Linux编译器--gcc/g++使用方式

ls /usr/lib64/libcpython.a*

Linux编译器--gcc/g++使用方式

4.2目标文件和库的链接

动态链接

  • 动态库在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时跳转到库中去执行相应的方法,执行结束后再回到代码调用处继续往下执行,这样可以节省系统的开销。动态库不能缺失,一旦缺失,所有依赖于动态库程序都无法正常运行。
  • 动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件。

静态链接

  • 静态库是指编译链接时,把库文件的代码全部拷贝加入到可执行文件中,因此生成的文件比较大,但再运行时,该目标问津不会再依赖库文件了。

4.3动态库和静态库的优缺点

  • 动态库:动态库为共享库,可以节约资源(磁盘空间,内存空间,网络空间);但动态库一旦缺失,所有依赖于该动态库的程序都无法正常运行
  • 静态库:程序不依赖库,静态库销毁,后续程序可以正常运行;体积大,不可以节约资源
  • Linux下,生成可执行文件时的默认为动态链接--需要提供动态库
  • Linux下,要按照静态链接的方式,在进行编译时要添加选项-static

实例:gcc code.c -o code.test

gcc code.c -o code.test_static -static

Linux编译器--gcc/g++使用方式

可以看出,按照静态链接的方式形成的可执行文件比动态链接形成的可执行文件大

  • 如果没有静态库,不能进行-static动态链接
  • 如果没有动态库,只有静态库,而且gcc能找到该静态库,那么可以进行静态链接
  • Linux默认优先动态链接,-static的本质:改变静态链接的优先级,只适配一次
  • 不一定所有的链接都是动态链接或静态链接,也有可能时动态链接和静态链接混合的

五、debug和release

  • Linux默认生成的release版本
  • debug版本的可执行文件会比release版本的略大
  • 要生成debug版本的可执行文件,可以在编译时添加-g选项

实例:gcc code.c -o code.test_debug -g

gcc code.c -o code.test_debug_static -g -static

Linux编译器--gcc/g++使用方式

  • 生成的可执行文件并不是无序的二进制格式,而是有自己的格式--ELF格式
  • file指令

实例:file code.test

file code.test_static

Linux编译器--gcc/g++使用方式

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程China编程(www.chinasem.cn)。

这篇关于Linux编译器--gcc/g++使用方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153335

相关文章

mybatis-plus QueryWrapper中or,and的使用及说明

《mybatis-plusQueryWrapper中or,and的使用及说明》使用MyBatisPlusQueryWrapper时,因同时添加角色权限固定条件和多字段模糊查询导致数据异常展示,排查发... 目录QueryWrapper中or,and使用列表中还要同时模糊查询多个字段经过排查这就导致只要whe

linux批量替换文件内容的实现方式

《linux批量替换文件内容的实现方式》本文总结了Linux中批量替换文件内容的几种方法,包括使用sed替换文件夹内所有文件、单个文件内容及逐行字符串,强调使用反引号和绝对路径,并分享个人经验供参考... 目录一、linux批量替换文件内容 二、替换文件内所有匹配的字符串 三、替换每一行中全部str1为st

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

使用Go实现文件复制的完整流程

《使用Go实现文件复制的完整流程》本案例将实现一个实用的文件操作工具:将一个文件的内容完整复制到另一个文件中,这是文件处理中的常见任务,比如配置文件备份、日志迁移、用户上传文件转存等,文中通过代码示例... 目录案例说明涉及China编程知识点示例代码代码解析示例运行练习扩展小结案例说明我们将通过标准库 os

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

MySQL中比较运算符的具体使用

《MySQL中比较运算符的具体使用》本文介绍了SQL中常用的符号类型和非符号类型运算符,符号类型运算符包括等于(=)、安全等于(=)、不等于(/!=)、大小比较(,=,,=)等,感兴趣的可以了解一下... 目录符号类型运算符1. 等于运算符=2. 安全等于运算符<=>3. 不等于运算符<>或!=4. 小于运

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

RabbitMQ消息总线方式刷新配置服务全过程

《RabbitMQ消息总线方式刷新配置服务全过程》SpringCloudBus通过消息总线与MQ实现微服务配置统一刷新,结合GitWebhooks自动触发更新,避免手动重启,提升效率与可靠性,适用于配... 目录前言介绍环境准备代码示例测试验证总结前言介绍在微服务架构中,为了更方便的向微服务实例广播消息,