gcc编译与Linux下的库

2024-09-04 19:20
文章标签 编译 linux gcc

本文主要是介绍gcc编译与Linux下的库,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

gcc与g++编译

  1. GCC:GCC是一个由GNU项目开发的多平台编译器,最初是为C语言设计的编译器,但随着时间的发展,它已经扩展到支持多种编程语言。它支持多种编程语言,包括C、C++、Objective-C、Fortran、Ada和Go等。GCC是自由软件,遵循GNU通用公共许可证(GPL)发布。

  2. G++是GCC的一个部分,专门用于编译C++程序。G++实际上是GCC的一个前端,它使用相同的后端来生成机器代码。在很多系统中,g++ 命令实际上是一个指向 gcc 的符号链接,但它们在处理C++特有的特性时会有所不同。

  3. GNU:是“GNU's Not Unix”的缩写,是一个由理查德·斯托曼(Richard Stallman)发起的自由软件项目,旨在创建一个完全自由的操作系统,包括操作系统的所有组件。GNU项目开发了许多重要的自由软件,如GCC、Emacs编辑器、Bash shell、GDB调试器等。

GCC和G++都是GNU项目的一部分,它们是GNU工具链中的核心组件,用于编译和链接程序。GNU工具链还包括其他工具,如链接器(ld)、库(如glibc)、调试器(如GDB)等,这些都是构建和运行程序所必需的。

  • 预处理:

编译器对各种预处理命令进行处理,包括对头文件的包含、宏定义的扩展、条件编译的选择。(总结的将就是对#语句的扩展处理)。

//现有文件test.c
//在命令行下输入gcc预处理命令
gcc -E test.c -o test.i

选项“-E”告诉gcc只进行预处理;“test.c”为C源程序文件;“-o”用于指定要生成的结果文件,后面跟的就是结果文件名字;这里输出的预处理结果文件为test.i。

  • 编译

编译器对高级语言源程序进行语法分析、词法分析和语义分析,然后根据分析的结果进行代码优化和存储分配,最终把高级语言程序翻译成汇编语言程序。

gcc对源程序文件编译后生成的汇编文件是.s文件。我们可对上边的 test.i进行编译:

gcc -S test.i -o test.s

也可以直接对c源程序文件进行编译:

gcc -S test.c -o test.s

选项“-S”告诉只进行到编译阶段。

  • 汇编

将编译生成的汇编语言程序转换为机器语言程序。
因为通常最终生成的可执行目标文件是由多个不同模块对应的机器语言目标代码组合而形成,所以,在生成单个模块的机器语言代码是,不可能确定每一条指令或数据最终的地址,即单个模块的机器语言目标代码需要重定位,因此把汇编生成的机器语言目标代码文件称为可重定位目标文件。

gcc生成的二进制代码文件(可重定位目标文件)为后缀名为.o的文件。我们对上边的test.s进行汇编

gcc -c test.s -o test.o

也可以直接对c源程序文件进行汇编:

gcc -c test.c -o test.o

选项“-c”告诉只进行到汇编阶段。

  • 链接

将一个程序的所有关联模块对应的可重定位目标文件结合在一起,以形成一个可执行文件的过程称为链接。在早期的计算机系统中,链接是手动完成的,而现在则由专门的链接程序(链接器)来实现。

需要知道的是:可重定位目标文件和可执行目标文件都是机器语言目标文件,都是不可显示的二进制文件,所不同的是前者是由单个模块生成的,而后者是多个模块生成的。因而,对前街,代码地址总是从0开始,而对于后者,代码在操作系统规定的虚拟地址空间中产生。

对上边生成的可重定位目标文件test.o进行链接:

gcc test.o -o test

这里只有一个可重定位目标文件, 如果有多个可重定位目标文件(.o文件)可以写在一起,每两个目标文件之间加空格,例如

gcc test1.o test2.o test3.o -o test

运行后,生成可执行文件test,我们可以运行它:

./test

gcc常见选项

gcc语法格式:

gcc [选项] 准备编译的文件 [选项] [目标文件]
  • -o:用于指定要生成的结果文件,后边跟的就是结果文件名字。
  • -I(i的大写):用来指定头文件所在文件夹的路径,用法为 -I dirPath。
  • -wall:显示所用的警告信息(Warn all)。
  • -g:产生供gdb调试用的可执行文件。
  • -l:链接共享库。

在实际的软件开发中,对于一些需要被许多模块反复使用的公共代码,我们通常可以将他们编译为库文件。库从本质上说是一种可执行代码的二进制格式,可以被载入内存中执行。

静态库(Static Library)

  1. 定义:静态库是一组编译后的代码和资源的集合,它们在编译时被直接链接到最终的可执行文件中。

  2. 文件扩展名:通常为.a(在Unix-like系统中)或.lib(在Windows系统中)。

  3. 编译过程在编译时,静态库的内容被复制到最终的可执行文件中,这意味着可执行文件包含了所有需要的代码和资源。

  4. 优点

    • 因为库代码已经包含在可执行文件中,所以不需要在运行时额外加载库文件。

    • 减少了运行时的依赖,因为所有需要的代码都已经包含在内。

    • 可能提高程序的启动速度,因为加载的是单个文件。

  5. 缺点

    • 增加了可执行文件的大小,因为包含了库的代码。

    • 如果库更新,需要重新编译整个程序来更新这部分代码。

    • 多个程序使用同一个静态库的不同版本可能会导致内存浪费。

        4、配合静态库写一个头文件,文件里的内容就是提供给外边使用的函数、变 量或类的声明。

静态库与源码编译:

gcc test.c -o test -l库名 -L 指定库文件 -I 头文件地址

动态库(Dynamic Library)

  1. 定义:动态库在程序运行时被加载,而不是在编译时。它们在内存中只存在一份,可以被多个程序共享。

  2. 文件扩展名:通常为.so(在Unix-like系统中,如Linux),.dll(在Windows系统中)或.dylib(在macOS系统中)。

  3. 编译过程在编译时,程序只记录了动态库的位置和需要的函数接口,实际的代码在运行时才被加载。

  4. 优点

    • 减少了可执行文件的大小,因为不包含库的代码。

    • 库的更新不需要重新编译程序,只需替换或更新动态库文件。

    • 多个程序可以共享同一份库,节省内存和存储空间。

  5. 缺点

    • 程序启动可能稍慢,因为需要在运行时加载库。

    • 需要确保动态库在运行时可用,否则程序可能无法启动或运行不正常。

    • 动态库的版本管理可能更复杂。

解决方式原理:把动态库放在默认的搜索路径上或者告诉系统动态库的路径即可。

选择使用静态库还是动态库

选择使用静态库还是动态库通常取决于应用程序的需求、部署环境和库的更新频率。例如,对于需要快速启动且不经常更新的小型应用程序,静态库可能是更好的选择。而对于大型应用程序或库更新频繁的情况,动态库可能更合适,因为它允许更灵活的更新和共享。+

注:

针对程序的具体的编译执行过程以及静态库、动态库,可参考袁春风的《计算机系统基础》中第4章:程序的链接。

gcc具体的Linux操作命令可参考(朱文伟 李建英) 的《Linux c与c++一线开发实践 》中第2章第八节:gcc编译和第10章:linux下的库

这篇关于gcc编译与Linux下的库的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

ubuntu16.04如何部署dify? 在Linux上安装部署Dify的技巧

《ubuntu16.04如何部署dify?在Linux上安装部署Dify的技巧》随着云计算和容器技术的快速发展,Docker已经成为现代软件开发和部署的重要工具之一,Dify作为一款优秀的云原生应用... Dify 是一个基于 docker 的工作流管理工具,旨在简化机器学习和数据科学领域的多步骤工作流。它

Linux高并发场景下的网络参数调优实战指南

《Linux高并发场景下的网络参数调优实战指南》在高并发网络服务场景中,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃,本文基于真实案例分析,从参数解读、问题诊断到优... 目录一、问题背景:当并发连接遇上性能瓶颈1.1 案例环境1.2 初始参数分析二、深度诊断:连接状态与

Android NDK版本迭代与FFmpeg交叉编译完全指南

《AndroidNDK版本迭代与FFmpeg交叉编译完全指南》在Android开发中,使用NDK进行原生代码开发是一项常见需求,特别是当我们需要集成FFmpeg这样的多媒体处理库时,本文将深入分析A... 目录一、android NDK版本迭代分界线二、FFmpeg交叉编译关键注意事项三、完整编译脚本示例四

Linux系统调试之ltrace工具使用与调试过程

《Linux系统调试之ltrace工具使用与调试过程》:本文主要介绍Linux系统调试之ltrace工具使用与调试过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、ltrace 定义与作用二、ltrace 工作原理1. 劫持进程的 PLT/GOT 表2. 重定

Linux区分SSD和机械硬盘的方法总结

《Linux区分SSD和机械硬盘的方法总结》在Linux系统管理中,了解存储设备的类型和特性是至关重要的,不同的存储介质(如固态硬盘SSD和机械硬盘HDD)在性能、可靠性和适用场景上有着显著差异,本文... 目录一、lsblk 命令简介基本用法二、识别磁盘类型的关键参数:ROTA查询 ROTA 参数ROTA

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

Linux搭建单机MySQL8.0.26版本的操作方法

《Linux搭建单机MySQL8.0.26版本的操作方法》:本文主要介绍Linux搭建单机MySQL8.0.26版本的操作方法,本文通过图文并茂的形式给大家讲解的非常详细,感兴趣的朋友一起看看吧... 目录概述环境信息数据库服务安装步骤下载前置依赖服务下载方式一:进入官网下载,并上传到宿主机中,适合离线环境

windows和Linux使用命令行计算文件的MD5值

《windows和Linux使用命令行计算文件的MD5值》在Windows和Linux系统中,您可以使用命令行(终端或命令提示符)来计算文件的MD5值,文章介绍了在Windows和Linux/macO... 目录在Windows上:在linux或MACOS上:总结在Windows上:可以使用certuti

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将