linux入门四:Linux 编译器

一、C 语言编译器 GCC:开启编程之旅

1.1 GCC 安装:一站式工具链

GCC(GNU Compiler Collection)是 Linux 下最常用的 C/C++ 编译器,支持多种编程语言。安装命令(适用于 Debian/Ubuntu 系统):

sudo apt-get install build-essential

build-essential 包包含 GCC、G++、make 等开发工具,一次安装即可满足基本编译需求。

1.2 GCC 基础使用:从源码到可执行文件

编译单个 C 文件
# 默认生成 a.out 可执行文件(推荐显式指定输出名)gcc main.c# 显式指定输出文件名(更规范)gcc main.c -o main # 生成 main 可执行文件(Linux 下无需 .exe 后缀)gcc main.c -o main.exe # 也可添加 .exe 后缀(兼容 Windows 习惯)
运行可执行文件
# 当前目录执行(需加 ./ 表示当前路径)./main # 执行当前目录的 main 文件/home/user/main # 执行绝对路径下的文件

1.3 编译四步法:深入理解编译过程

C 程序的编译分为 预处理、编译、汇编、链接 四个阶段,GCC 可通过选项控制每个阶段。

1. 预处理(Preprocessing)
  • 作用:处理 #include 头文件、#define 宏定义等。
  • 命令
gcc -E main.c -o main.i # 生成预处理后的文本文件 main.i(无宏和头文件展开)
2. 编译(Compilation)
  • 作用:将预处理后的代码转为汇编语言。
  • 命令
gcc -S main.i -o main.s # 生成汇编文件 main.s(内容为人类可读的汇编代码)
3. 汇编(Assembly)
  • 作用:将汇编语言转为二进制目标文件(.o)。
  • 命令
gcc -c main.s -o main.o # 或直接对 .c 文件执行:gcc -c main.c -o main.o
4. 链接(Linking)
  • 作用:将多个目标文件和库文件链接为可执行文件。
  • 命令
gcc main.o -o main # 链接单个目标文件gcc file1.o file2.o -o program # 链接多个目标文件

1.4 实战作业:用 GCC 编译冒泡排序并调试

第一步:用 Vim 编写冒泡排序代码(bubble.c)
#include <stdio.h>void bubble_sort(int arr[], int n) {int i, j, temp;for (i = 0; i < n-1; i++) {for (j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}int main() {int arr[] = {64, 34, 25, 12, 22, 11, 90};int n = sizeof(arr)/sizeof(arr[0]);bubble_sort(arr, n);printf("排序后的数组:");for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}return 0;}
第二步:编译并运行
gcc bubble.c -o bubble # 编译为可执行文件./bubble # 运行结果:11 12 22 25 34 64 90
第三步:用 GDB 调试(需安装 gdb)
sudo apt install gdb # 安装调试器gdb bubble # 启动 GDB 调试(gdb) break main # 在 main 函数入口打断点(gdb) run # 运行程序,停在断点处(gdb) next # 单步执行(跳过函数调用)(gdb) step # 单步执行(进入函数内部)(gdb) print arr # 打印数组内容(gdb) quit # 退出调试

二、C++ 编译器 G++:支持现代编程范式

G++ 是 GCC 用于编译 C++ 代码的前端,使用方法与 GCC 类似,但会自动链接 C++ 标准库。

2.1 安装与基本使用

# 通常随 build-essential 安装,若未安装:sudo apt install g++# 编译 C++ 文件(.cpp 或 .cxx)g++ main.cpp -o main # 生成 C++ 可执行文件

2.2 C++ 特性支持

  • C++11 及以上标准:需添加 -std=c++11 选项(如 g++ main.cpp -o main -std=c++11)。
  • 链接 C++ 库:G++ 会自动链接 libstdc++,无需手动指定。

三、Linux 库开发:动态库与静态库详解

3.1 动态库(Shared Library):运行时加载

概述
  • 特点:程序运行时动态加载,多个程序可共享,节省内存,更新方便(无需重新编译程序)。
  • 命名规则:lib库名.so(如 libadd.so,库名为 add)。
创建与使用步骤
  1. 编写库代码(add.c
int add(int a, int b) { return a + b; } // 保存为 add.c
  1. 编译为动态库
gcc -shared -fPIC add.c -o libadd.so # -shared 表示生成动态库,-fPIC 生成位置无关代码
  1. 编写调用程序(main.c
#include <stdio.h>extern int add(int a, int b); // 声明外部函数int main() {printf("1 + 2 = %d\n", add(1, 2));return 0;}
  1. 编译时指定库路径(两种方式)
# 方式一:直接指定库文件路径(适合临时使用)gcc main.c ./libadd.so -o main# 方式二:通过 -l 选项指定库名(需将库放到系统搜索路径,见下文)gcc main.c -ladd -o main # -ladd 对应 libadd.so
  1. 运行时找不到库的解决方法
    • 方法一:复制到系统库目录(不推荐,可能污染系统):
sudo cp libadd.so /lib/ # 系统库目录sudo cp libadd.so /usr/lib/ # 用户库目录
    • 方法二:添加自定义库路径到系统搜索列表:
      1. 创建个人库目录:mkdir ~/mylib
      1. 复制库到该目录:cp libadd.so ~/mylib
      1. 编辑系统库配置文件:
sudo vim /etc/ld.so.conf # 添加一行:/home/用户名/mylibsudo ldconfig # 刷新库缓存

3.2 静态库(Static Library):编译时链接

概述
  • 特点:库代码在编译时直接嵌入可执行文件,运行时无需依赖库文件,体积较大,更新需重新编译程序。
  • 命名规则:lib库名.a(如 libadd.a,库名为 add)。
创建与使用步骤
  1. 编译目标文件
gcc -c add.c -o add.o # 生成 add.o 目标文件
  1. 打包为静态库
ar -r libadd.a add.o # -r 表示替换或添加文件到库
  1. 编写调用程序(同动态库的 main.c:无需 extern 声明,直接编译链接:
gcc main.c libadd.a -o main # 直接指定静态库文件
  1. 执行
./main # 输出:1 + 2 = 3(无需依赖库文件)

四、编译器与库对比:选择合适的工具

类型

优点

缺点

适用场景

GCC/G++

跨平台、支持多语言

需命令行操作(新手需适应)

所有 C/C++ 开发

动态库

节省内存、更新方便

运行时依赖库文件

大型项目、共享库开发

静态库

独立可执行、无需依赖

体积大、更新麻烦

小型项目、嵌入式开发

五、总结:从编译到部署的完整流程

  1. 新手入门:先用 GCC 编译简单 C 程序,掌握 -o、-c 等基础选项。
  1. 进阶学习:理解编译四阶段,学会用 GDB 调试代码,解决编译错误(如头文件缺失、链接失败)。
  1. 库开发:从动态库开始,掌握 ldconfig 的使用,逐步尝试静态库,理解两者的本质区别。

通过实践作业(如冒泡排序的调试、自定义库的调用),新手可快速掌握 Linux 下的编译流程,为后续开发打下坚实基础。记住:多写代码、多调试、多解决报错,是掌握编译器的关键!

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

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

相关文章

建筑兔零基础自学记录69|爬虫Requests-2

Requests库初步尝试 #导入requests库 import requests #requests.get读取百度网页 rrequests.get(http://www.baidu.com) #输出读取网页状态 print(r.status_code) #输出网页源代码 print(r.text) HTTP 状态码是三位数字&#xff0c;用于表示 HTTP 请求的结果。常见的状态码有…

Web测试流程及注意点

在Web工程过程中&#xff0c;基于Web系统的测试、确认和验收是一项重要而富有挑战性的工作。基于Web的系统测试与传统的软件测试不同&#xff0c;它不但需要检查和验证是否按照设计的要求运行&#xff0c;而且还要测试系统在不同用户的浏览器端的显示是否合适。 重要的是&…

基于MATLAB/simulink的信号调制仿真--AM调制

实验内容&#xff1a; 假设y(t)(20.5*2cos&#xff08;2*pi*1000*t&#xff09;)*5cos&#xff08;2*pi*2*1e4*t&#xff09;调幅系统&#xff0c;请将一个频率为1000HZ的余弦波信号&#xff0c;通过进行AM调制&#xff0c;载波信号频率为20kHZ的余弦波&#xff0c;调制度ma0.…

通信协议详解(十):PSI5 —— 汽车安全传感器的“抗干扰狙击手”

一、PSI5是什么&#xff1f; 一句话秒懂 PSI5就像传感器界的“防弹信使”&#xff1a;在汽车安全系统&#xff08;如气囊&#xff09;中&#xff0c;用两根线同时完成供电数据传输&#xff0c;即便车祸时线路受损&#xff0c;仍能确保关键信号准确送达&#xff01; 基础概念…

数据结构与算法-图论-复习1(单源最短路,全源最短路,最小生成树)

1. 单源最短路 单一边权 BFS 原理&#xff1a;由于边权为单一值&#xff0c;可使用广度优先搜索&#xff08;BFS&#xff09;来求解最短路。BFS 会逐层扩展节点&#xff0c;由于边权相同&#xff0c;第一次到达某个节点时的路径长度就是最短路径长度。 用法&#xff1a;适用…

【WRF理论第十七期】单向/双向嵌套机制(含namelist.input详细介绍)

WRF运行的单向/双向嵌套机制 准备工作&#xff1a;WRF运行的基本流程namelist.input的详细设置&time_control 设置&domain 嵌套结构&bdy_control 配置部分 namelist 其他注意事项Registry.EM 运行 ARW 嵌套双向嵌套&#xff08;two-way nesting&#xff09;单向嵌套…

怎么查看苹果手机和ipad的设备信息和ios udid

你知道吗&#xff1f;我们每天使用的iPhone和iPad&#xff0c;其实隐藏着大量详细的硬件与系统信息。除了常见的系统版本和序列号外&#xff0c;甚至连电池序列号、摄像头序列号、销售地区、芯片型号等信息&#xff0c;也都可以轻松查到&#xff01; 如果你是开发者、维修工程…

matlab内置的git软件版本管理功能

1、matlab多人协作开发比普通的嵌入式软件开发困难很多 用过matlab的人都知道&#xff0c;版本管理对于matlab来说真的很费劲&#xff0c;今天介绍的这个工具也不是说它就解决了这个痛点&#xff0c;只是让它变得简单一点。版本管理肯定是不可或缺的&#xff0c;干就完了 2、…

vscode集成deepseek实现辅助编程(银河麒麟系统)【详细自用版】

针对开发者用户&#xff0c;可在Visual Studio Code中接入DeepSeek&#xff0c;实现辅助编程。 可参考我往期文章在银河麒麟系统环境下部署DeepSeek&#xff1a;基于银河麒麟桌面&&服务器操作系统的 DeepSeek本地化部署方法【详细自用版】 一、前期准备 &#xff08…

Java 大厂面试题 -- JVM 深度剖析:解锁大厂 Offe 的核心密钥

最近佳作推荐&#xff1a; Java大厂面试高频考点&#xff5c;分布式系统JVM优化实战全解析&#xff08;附真题&#xff09;&#xff08;New&#xff09; Java大厂面试题 – JVM 优化进阶之路&#xff1a;从原理到实战的深度剖析&#xff08;2&#xff09;&#xff08;New&#…

数据库实践题目:在线书店管理系统

完整的数据库实践题目&#xff1a;在线书店管理系统 数据库表结构及示例数据 书籍表(books) CREATE TABLE books ( book_id INT PRIMARY KEY, title VARCHAR(100) NOT NULL, author VARCHAR(50) NOT NULL, publisher VARCHAR(50), publish_year INT, category VARCHAR(30), …

Linux 入门指令(1)

&#xff08;1&#xff09;ls指令 ls -l可以缩写成 ll 同时一个ls可以加多个后缀 比如 ll -at (2)pwd指令 &#xff08;3&#xff09;cd指令 cd .是当前目录 &#xff08;4&#xff09;touch指令 &#xff08;5&#xff09;mkdir指令 &#xff08;6&#xff09;rmdir和rm…

图灵逆向——题七-千山鸟飞绝

目录列表 过程分析headers头部M参数分析载荷x参数分析响应数据解密分析 代码实现 一进来还是一个无限debugger&#xff0c;前面有讲怎么过&#xff0c;这里直接过掉~ 老规矩&#xff0c;养成习惯&#xff0c;先看请求头里有没有加密参数发现好像是有个M&#xff0c;它是个32位…

上门预约洗鞋店小程序都具备哪些功能?

现在大家对洗鞋子的清洗条件越来越高&#xff0c;在家里不想去&#xff0c;那就要拿去洗鞋店去洗。如果有的客户没时间去洗鞋店&#xff0c;这个时候&#xff0c;有个洗鞋店小程序就可以进行上门取件&#xff0c;帮助没时间的客户去取需要清洗的鞋子&#xff0c;这样岂不是既帮…

Node.js EventEmitter 深入解析

Node.js EventEmitter 深入解析 概述 Node.js 作为一种强大的 JavaScript 运行环境&#xff0c;以其异步、事件驱动特性在服务器端编程中占据了重要地位。EventEmitter 是 Node.js 中处理事件的一种机制&#xff0c;它允许对象&#xff08;称为“发射器”&#xff09;发出事件…

C++11QT复习 (十九)

文章目录 Day13 C 时间库和线程库学习笔记&#xff08;Chrono 与 Thread&#xff09;一、时间库 <chrono>1.1 基本概念1.2 使用示例1.3 duration 字面量单位 二、线程库 <thread>2.1 基本用法2.2 数据竞争&#xff08;Race Condition&#xff09;2.3 加锁&#xff…

C++初阶-C++的讲解1

目录 1.缺省(sheng)参数 2.函数重载 3.引用 3.1引用的概念和定义 3.2引用的特性 3.3引用的使用 3.4const引用 3.5.指针和引用的关系 4.nullptr 5.总结 1.缺省(sheng)参数 &#xff08;1&#xff09;缺省参数是声明或定义是为函数的参数指定一个缺省值。在调用该函数是…

Redisson 实现分布式锁

在平常的开发工作中&#xff0c;我们经常会用到锁&#xff0c;那么锁有什么用呢&#xff1f;锁主要是控制对共享资源的访问顺序&#xff0c;防止多个线程并发操作导致数据不一致的问题。经常可能会听到乐观锁、悲观锁、分布式锁、行锁、表锁等等&#xff0c;那么我们今天总结下…

环境—Ubuntu24(py3.12)安装streamlit(虚拟环境py3.9)

请尽可能不用Ubuntu24请直接跳7.查看解决方案 Action Log 在Ubuntu 24.04中更换为清华源的步骤【Bug】Python 3.12 on Ubuntu 24.04 is Externally Managed - PIP is broken 相关解决方案 从 Ubuntu 24.04 开始&#xff0c;有两个选项&#xff1a; 1. install python pacakg…

【C++进阶】关联容器:set类型

目录 一、set 基本概念 1.1 定义与特点 1.2 头文件与声明 1.3 核心特性解析 二、set 底层实现 2.1 红黑树简介 2.2 红黑树在 set 中的应用 三、set 常用操作 3.1 插入元素 3.2 删除元素 3.3 查找元素 3.4 遍历元素 3.5 性能特征 四、set 高级应用 4.1 自定义比较…