当前位置: 首页 > news >正文

Linux中C/C++程序编译过程与动静态链接库概述


✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭
~✨✨

🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。

我是Srlua小谢,在这里我会分享我的知识和经验。🎥

希望在这里,我们能一起探索IT世界的奥妙,提升我们的技能。🔮

记得先点赞👍后阅读哦~ 👏👏

📘📚 所属专栏:嵌入式

欢迎访问我的主页:Srlua小谢 获取更多信息和资源。✨✨🌙🌙

​​

目录

C/C++程序开发与链接库概述

ldd

用法

示例

选项

注意事项

结论

C/C++ 程序开发过程中的四个主要步骤

1. 预处理 (Preprocessing)

2. 编译 (Compilation)

3. 汇编 (Assembly)

4. 链接 (Linking)

总结

动态链接库

动态库的特点

动态库的管理

结论

静态链接库

静态库的特点

结论

静态库与动态库的比较

在某些云服务器上,默认情况下可能没有安装 C/C++ 的静态库和相关的编译工具链。

1. Ubuntu/Debian 系统

2. CentOS/RHEL 系统

3. 验证安装

4. 编译静态库示例

结论

先有语言还是先有编译器

1. 早期的编程语言

2. 高级语言的出现

3. 编译器的开发

4. 自举过程

总结


C/C++程序开发与链接库概述

ldd

ldd 是 Linux 中的一个命令,用于显示一个可执行文件或共享库所依赖的共享库(动态链接库)。这个命令可以帮助开发者和系统管理员检查程序的动态链接依赖关系,确保所有必要的库都能找到,并且程序能够正常运行。

用法

基本语法如下:

ldd [选项] <可执行文件>

示例

  1. 查看依赖库

    ldd /path/to/your/executable
  2. 示例输出

    linux-vdso.so.1 =>  (0x00007ffcb7ff3000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffcb7e7e000)
    /lib64/ld-linux-x86-64.so.2 (0x00007ffcb81da000)
    

    这里的输出表示可执行文件依赖于 libc.so.6ld-linux-x86-64.so.2 等共享库。

选项

  • --version:显示版本信息。
  • --help:显示帮助信息。
  • --quiet:只输出错误信息。

注意事项

  • ldd 可能会执行被检查的程序,尤其是在处理不受信任的二进制文件时,可能会存在安全风险。
  • 对于静态编译的程序,ldd 不会返回任何库,因为这些程序不依赖于共享库。

结论

ldd 是一个非常实用的工具,可以帮助开发者和运维人员排查动态链接库的问题,确保程序的可移植性和兼容性。

C/C++ 程序开发过程中的四个主要步骤

1. 预处理 (Preprocessing)

描述: 在这个步骤中,编译器处理所有的预处理指令,例如宏定义、条件编译和头文件包含。它生成一个扩展后的源代码文件。

Bash 示例

gcc -E example.c -o example.i

实际例子: 假设有一个名为 example.c 的文件,内容如下:

#include <stdio.h>
#define PI 3.14int main() {printf("Value of PI: %f\n", PI);return 0;
}

运行上述命令后,生成的 example.i 文件将包含所有的预处理指令处理结果,显示 #include 的内容以及宏 PI 的替换。

2. 编译 (Compilation)

描述: 在这个步骤中,编译器将预处理后的源代码转换为汇编语言。生成的文件通常以 .s 结尾。

Bash 示例

gcc -S example.i -o example.s

实际例子: 使用上一步生成的 example.i 文件,运行上述命令后,生成的 example.s 文件可能包含类似以下内容:

	.file	"example.c".text.globl	main.type	main, @function
main:...

3. 汇编 (Assembly)

描述: 在这个步骤中,汇编器将汇编代码转换为机器代码,生成目标文件,通常以 .o.obj 结尾。

gcc -c example.s -o example.o

实际例子: 运行上述命令后,会生成 example.o 文件。这个文件包含了机器码,但不是一个完整的可执行程序。

4. 链接 (Linking)

描述: 在这个步骤中,链接器将目标文件与需要的库文件链接,生成最终的可执行文件。

Bash 示例

gcc example.o -o example

实际例子: 运行上述命令后,会生成名为 example 的可执行文件。你可以运行它:

./example

输出将是:

Value of PI: 3.140000

总结

以上步骤展示了从源代码到可执行文件的完整过程,每一步都可以使用 Bash 命令在 Linux 中执行。这些步骤的输出文件在整个编译过程中扮演着重要的角色,确保程序的最终执行能够顺利进行。

动态链接库

libc.so.6 是 Linux 系统中的标准 C 库的动态链接库(shared library)。动态库的主要特点是可以在运行时被程序加载和使用,而不是在编译时将库的代码直接嵌入到可执行文件中。这使得程序可以共享同一个库,节省内存并简化更新过程。

动态库的特点

  1. 文件格式:动态库的文件名通常以 .so(Shared Object)为后缀,例如 libc.so.6
  2. 共享性:多个程序可以共享同一个动态库,从而减少内存使用。
  3. 动态加载:程序在运行时可以动态加载库,支持插件式的开发。
  4. 版本控制:动态库支持版本控制,例如 libc.so.6 表示 C 标准库的一个具体版本。

动态库的管理

在 Linux 系统中,动态库通常存放在 /lib/usr/lib/usr/local/lib 目录下。可以使用 ldconfig 命令来更新动态库的缓存,以便系统能够找到新的库。

结论

libc.so.6 是 Linux 系统中标准 C 库的一个具体实现版本。动态库的使用不仅节省了内存资源,还使得程序的更新和维护变得更加方便。在开发中,创建和使用动态库是提高程序效率和模块化的关键技术。

静态链接库

静态链接库是在编译时将库的代码直接嵌入到可执行文件中,从而生成一个独立的可执行程序。静态库通常具有 .a 后缀(在 Linux 系统中),与动态链接库不同,静态链接库的代码在链接时就已经被复制到最终的可执行文件中,因此不需要在运行时依赖外部库。

静态库的特点

  1. 文件格式:静态库的文件通常以 .a 为后缀,例如 libmylib.a
  2. 自包含性:链接静态库的可执行文件在运行时不需要外部库,适合在没有共享库环境的系统中运行。
  3. 文件体积大:由于静态库的代码被复制到每个可执行文件中,程序体积通常比使用动态库的大。
  4. 更新困难:如果库的代码需要更新,需要重新编译所有使用该库的程序。

结论

静态链接库在需要自包含性和不依赖外部环境的场合非常有用。尽管其更新成本较高,但在某些嵌入式系统或分发时无法保证共享库一致性的场合,静态库依然是一个非常实用的选择。

静态库与动态库的比较

特点静态库动态库
文件后缀.a.so
内存使用高(每个程序都有一份库的代码)低(共享库的代码)
更新方便性需重新编译所有依赖的程序只需更新库文件
运行时依赖无(不需要库文件)需要库文件
文件体积较大较小

在某些云服务器上,默认情况下可能没有安装 C/C++ 的静态库和相关的编译工具链。

要在这样的环境中开发和编译 C/C++ 程序,您需要手动安装必要的工具和库。下面是一些常见的 Linux 发行版(如 Ubuntu 和 CentOS)上安装 C/C++ 编译器和静态库的步骤。

1. Ubuntu/Debian 系统

对于基于 Debian 的系统(如 Ubuntu),可以使用 apt 包管理器进行安装:

# 更新包列表
sudo apt update# 安装 C 和 C++ 编译器
sudo apt install build-essential# 安装静态库
sudo apt install libc6-dev
  • build-essential 包包括 GCC(GNU Compiler Collection)、G++ 和其他编译工具以及标准库的开发文件。
  • libc6-dev 提供了 C 标准库的头文件和静态库。

2. CentOS/RHEL 系统

对于基于 RHEL 的系统(如 CentOS),可以使用 yumdnf 包管理器进行安装:

# 更新包列表(可选)
sudo yum update# 安装 C 和 C++ 编译器
sudo yum groupinstall "Development Tools"# 安装静态库
sudo yum install glibc-devel
  • Development Tools 组包包含了 GCC、G++ 和其他开发工具。
  • glibc-devel 提供了 C 标准库的头文件和静态库。

3. 验证安装

安装完成后,可以通过以下命令验证 GCC 和 G++ 是否安装成功:

gcc --version
g++ --version

您应该能够看到安装的版本信息。

4. 编译静态库示例

一旦安装了编译工具,您可以按照以下步骤创建一个静态库:

  1. 创建源文件mathlib.c):
    #include <stdio.h>void print_sum(int a, int b) {printf("Sum: %d\n", a + b);
    }
    
  2. 编译源文件为目标文件
    gcc -c mathlib.c -o mathlib.o
    
  3. 创建静态库
    ar rcs libmathlib.a mathlib.o
    
  4. 使用静态库的程序main.c):
    #include <stdio.h>extern void print_sum(int, int);int main() {print_sum(3, 5);return 0;
    }
    
  5. 编译并链接
    gcc main.c -L. -lmathlib -o main
    
  6. 运行程序
    ./main
    

结论

在云服务器上,如果默认没有安装 C/C++ 的静态库和编译工具,您可以通过相应的包管理器手动安装所需的工具和库。安装完成后,您就可以开始编写和编译 C/C++ 程序了。

先有语言还是先有编译器

1. 早期的编程语言

  • 机器语言和汇编语言
    • 在计算机发展的早期阶段,程序员主要使用机器语言(以二进制或十六进制形式表示)进行编程。这种语言直接对应于计算机硬件,程序员必须理解底层架构。
    • 随后,汇编语言出现,它为机器语言提供了助记符,使得编写程序更加容易,但仍然与具体的硬件架构紧密相关。

2. 高级语言的出现

  • 第一代高级语言
    • 随着计算机技术的发展,出现了更高级的编程语言,例如 Fortran(1957 年)和 COBOL(1959 年)。这些语言允许程序员以更抽象的方式编写代码,不必关心底层的机器指令。

3. 编译器的开发

  • 编译器的实现
    • 为了将这些高级语言转换为机器代码,开发了编译器。编译器是一种特殊的软件工具,负责将程序员编写的源代码翻译成计算机能够理解的指令。
    • 最早的编译器通常是用汇编语言或其他低级语言编写的,这使得编译器与特定的硬件架构紧密相连。

4. 自举过程

  • 自举(Bootstrapping)
    • 一旦编译器开发出来,就可以使用它来编译其他程序,包括它自身的后续版本。这个过程称为自举。
    • 例如,最初的 C 编译器可能用汇编语言实现,随后用 C 语言重写,最后能够用自己编译自己。

总结

综上所述,计算机历史上是先有编程语言,再有编译器。编程语言的出现为编译器的发展提供了基础,而编译器则使得这些语言可以被计算机理解和执行。因此,编程语言和编译器的关系是相互依存的,语言的设计往往影响编译器的实现,而编译器的发展又会推动语言的演进。

​​

希望对你有帮助!加油!

若您认为本文内容有益,请不吝赐予赞同并订阅,以便持续接收有价值的信息。衷心感谢您的关注和支持!


http://www.mrgr.cn/news/59311.html

相关文章:

  • 【C++开篇】
  • Java 开发——(上篇)从零开始搭建后端基础项目 Spring Boot 3 + MybatisPlus
  • 丹麦和意大利 家用电源插头和插座标准规范CEI 23-50 V4-2015,DS 60884-2-D1-2017
  • 【软件工程】软件工程入门
  • 功能测试的方向
  • 安徽对口高考Python试题选:输入一个正整数,然后输出该整数的3的幂数相加形式。
  • LeetCode438.找到字符串中所有字母异位词
  • Macos系统使用wine安装window的exe软件
  • Redis 线程控制 总结
  • 图片懒加载
  • lodash 库作用
  • python的装饰器
  • 好/坏代码实例解读:图文并茂说明
  • 在MySQL中存储IP地址的最佳实践
  • C#判断带数字的字符串数组连续性的两种方式
  • 【JavaSE】认识String类,了解,进阶到熟练掌握
  • 使用 Resilience4j 实现重试
  • PHP模拟多继承的方式:traits
  • 数据结构 - 散列表,初探
  • Java篇图书管理系统
  • 深度图像和距离图像
  • 2024年如何学好JS
  • 多层感知机的从零实现与softmax的从零实现(真·0000零基础)
  • 2025前端面试-内存泄露-001
  • 软件模拟 SPI 时序,驱动OLED屏幕
  • 基于Python+Django的气象数据分析与可视化系统