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

相关文章

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除

Linux下MySQL数据库定时备份脚本与Crontab配置教学

《Linux下MySQL数据库定时备份脚本与Crontab配置教学》在生产环境中,数据库是核心资产之一,定期备份数据库可以有效防止意外数据丢失,本文将分享一份MySQL定时备份脚本,并讲解如何通过cr... 目录备份脚本详解脚本功能说明授权与可执行权限使用 Crontab 定时执行编辑 Crontab添加定

Java使用Javassist动态生成HelloWorld类

《Java使用Javassist动态生成HelloWorld类》Javassist是一个非常强大的字节码操作和定义库,它允许开发者在运行时创建新的类或者修改现有的类,本文将简单介绍如何使用Javass... 目录1. Javassist简介2. 环境准备3. 动态生成HelloWorld类3.1 创建CtC

使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解

《使用Python批量将.ncm格式的音频文件转换为.mp3格式的实战详解》本文详细介绍了如何使用Python通过ncmdump工具批量将.ncm音频转换为.mp3的步骤,包括安装、配置ffmpeg环... 目录1. 前言2. 安装 ncmdump3. 实现 .ncm 转 .mp34. 执行过程5. 执行结

Java使用jar命令配置服务器端口的完整指南

《Java使用jar命令配置服务器端口的完整指南》本文将详细介绍如何使用java-jar命令启动应用,并重点讲解如何配置服务器端口,同时提供一个实用的Web工具来简化这一过程,希望对大家有所帮助... 目录1. Java Jar文件简介1.1 什么是Jar文件1.2 创建可执行Jar文件2. 使用java

C#使用Spire.Doc for .NET实现HTML转Word的高效方案

《C#使用Spire.Docfor.NET实现HTML转Word的高效方案》在Web开发中,HTML内容的生成与处理是高频需求,然而,当用户需要将HTML页面或动态生成的HTML字符串转换为Wor... 目录引言一、html转Word的典型场景与挑战二、用 Spire.Doc 实现 HTML 转 Word1

Java中的抽象类与abstract 关键字使用详解

《Java中的抽象类与abstract关键字使用详解》:本文主要介绍Java中的抽象类与abstract关键字使用详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、抽象类的概念二、使用 abstract2.1 修饰类 => 抽象类2.2 修饰方法 => 抽象方法,没有

MyBatis ParameterHandler的具体使用

《MyBatisParameterHandler的具体使用》本文主要介绍了MyBatisParameterHandler的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一、概述二、源码1 关键属性2.setParameters3.TypeHandler1.TypeHa

Spring 中的切面与事务结合使用完整示例

《Spring中的切面与事务结合使用完整示例》本文给大家介绍Spring中的切面与事务结合使用完整示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考... 目录 一、前置知识:Spring AOP 与 事务的关系 事务本质上就是一个“切面”二、核心组件三、完

使用docker搭建嵌入式Linux开发环境

《使用docker搭建嵌入式Linux开发环境》本文主要介绍了使用docker搭建嵌入式Linux开发环境,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1、前言2、安装docker3、编写容器管理脚本4、创建容器1、前言在日常开发全志、rk等不同