linux入门四:Linux 编译器

news2025/4/19 15:39:35

一、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/用户名/mylib

sudo 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.coloradmin.cn/o/2332493.html

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

相关文章

springboot集成springcloud vault读值示例

接上三篇 Vault---机密信息管理工具安装及常用示例 Vault机密管理工具集群配置示例 vault签发根证书、中间证书、ca证书流程记录 项目里打算把所有密码都放到vault里管理&#xff0c;vault提供了springcloud vault用来在springboot里连接vault&#xff0c;启动加载vault里的值放…

edis 主从复制

Redis 主从复制是一种数据同步机制&#xff0c;主节点&#xff08;Master&#xff09;将数据复制到一个或多个从节点&#xff08;Slave&#xff09;&#xff0c;从 而实现数据备份、读写分离和高可用性。 1、解决我们的日常一个单机故障&#xff0c;而衍生出来 主从架构 2、…

机器视觉+深度学习,让电子零部件表面缺陷检测效率大幅提升

在精密加工的3C电子行业中&#xff0c;一抹0.1毫米的油渍&#xff0c;一粒肉眼难辨的灰尘或将引发整机性能隐患。当制造业迈入微米级品质竞争时代&#xff0c;产品表面看似微不足道的脏污缺陷&#xff0c;正成为制约企业高质量发展的隐形枷锁。分布无规律的污渍斑点、形态各异的…

Java基础关键_035_Lambda 表达式

目 录 一、引例&#xff1a;TreeSet 排序 1.实现 Comparable 接口 2.比较器 3.匿名内部类 4.Lambda 表达式 5.Lambda 表达式和匿名内部类的区别 二、函数式编程 三、Lambda 表达式的使用 1.无返回值函数式接口 &#xff08;1&#xff09;无返回值无参数 &#xff08;…

OPEX baota 2024.02.26

OPEX baota 2024.02.26 运维集成软件宝塔2024.02.26作废例子&#xff1a; 最重要的两个地方&#xff1a;上传文件 网站&#xff0c;重启应用服务器&#xff08;tomcat&#xff09; 其他很少用的

若依 前后端部署

后端&#xff1a;直接把代码从gitee上拉去到本地目录 (https://gitee.com/y_project/RuoYi-Vue ) 注意下redis连接时password改auth 后端启动成功 前端&#xff1a;运行前首先确保安装了node环境&#xff0c;随后执行&#xff1a; &#xff01;&#xff01;一定要用管理员权限…

LeetCode算法题(Go语言实现)_37

题目 给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。 如果前进方向为右&#xff0c;那么移动到当前节点的的右子节点&#xff0c;否则移动到它的左子节点。 改变前进方…

使用 react-three-fiber 快速重构 Three.js 场景⚛️

不明白的知识先放在一边&#xff0c;激发兴趣是第一步&#xff0c;所以不必纠结代码的细节&#xff0c;相信我你很快就会爱上这种感觉&#xff01;&#xff01;&#xff01; 今天&#xff0c;我们将更进一步&#xff0c;将上一篇中vite npm传统 Three.js 原生代码完整 重构为 …

RT-Thread 屏蔽在线软件包的方法

说明 可能大家对 RT-Thread 的 Kconfig 配置项&#xff0c;Scons 构建有些疑惑&#xff0c;其实 BSP 的 Kconfig 可以自由的配置&#xff0c;目录也可以自由的调整 RT-Thread BSP 默认都有在线软件包的配置项&#xff0c;如果你不需要在线软件包&#xff0c;也可以把这个配置项…

深入理解Java反射

反射(Reflection)是Java语言的一个强大特性&#xff0c;它允许程序在运行时动态地获取类的信息并操作类或对象的属性、方法和构造器。就是在获取运行时的java字节码文件&#xff0c;通过各种方法去创建对象&#xff0c;反射是Java被视为动态语言的关键特性之一。 反射其实就是…

Apipost自定义函数深度实战:灵活处理参数值秘籍

在开发过程中&#xff0c;为了更好地处理传递给接口的参数值&#xff0c;解决在调试过程中的数据处理问题&#xff0c;我们经常需要用到函数处理数据。 过去&#xff0c;我们通过预执行脚本来处理数据&#xff0c;先添加脚本&#xff0c;然后将处理后的结果再赋值给请求参数。…

对重大保险风险测试的算法理解

今天与同事聊到重大保险风险测试&#xff0c;借助下面链接的文章&#xff0c; 谈IFRS 17下的重大保险风险测试 - 知乎 谈一下对下图这个公式的理解。 尤其是当看到下面这段文字的解释时&#xff0c;感觉有些算法上的东西&#xff0c;需要再澄清一些。 首先&#xff0c;上面文…

如何白嫖Grok3 API? 如何使用Grok3 API调用实例?怎么使用Grok3模型?

前段时间&#xff0c;Grok3&#xff08;想要体验Grok3的童鞋可以参考本文&#xff1a;Grok 上线角色扮演功能&#xff0c;教你课后作业手到擒来&#xff0c;Grok3使用次数限制&#xff1f;如何使用Grok3? Grok3国内支付手段如何订阅升级Premium - AI is all your need!&#x…

Fast网络速度测试工具

目录 网站简介 功能特点 测试过程 为什么使用Fast 如果网络速度不达标 网站简介 Fast是一个由Netflix提供的网络速度测试工具&#xff0c;主要用来测试用户的互联网下载速度。它以其简洁的界面和快速的测试过程而受到用户的欢迎。 功能特点 下载速度测试&#xff1a;这是…

ubuntu20.04在mid360部署direct_lidar_odometry(DLO)

editor&#xff1a;1034Robotics-yy time&#xff1a;2025.4.10 1.下载DLO&#xff0c;mid360需要的一些...: 1.1 在工作空间/src下 下载DLO&#xff1a; git clone https://github.com/vectr-ucla/direct_lidar_odometry 1.2 在工作空间/src下 下载livox_ros_driver2&…

制造企业数据治理体系搭建与业务赋能实践

当下制造企业正面临着前所未有的机遇与挑战&#xff0c;从多环节业务协同的复杂性&#xff0c;到海量数据资源的沉睡与孤岛化&#xff1b;从个性化定制需求的爆发&#xff0c;到供应链效率优化的迫切性——如何通过数据治理将“数据包袱”转化为“数据资产”&#xff0c;已成为…

【LunarVim】解决which-key 自定义键位注册不成功问题

问题描述 LunarVim将which-key设置放在一个keymaps.lua中&#xff0c;然后config.lua调用reload “user.keymaps”&#xff0c;键位没用注册成功&#xff0c;而直接写在config.lua中&#xff0c;就注册成功 这暴露了LunarVim 插件和配置加载顺序的一些细节坑&#xff0c;下面解…

开源推荐#5:CloudFlare-ImgBed — 基于 CloudFlare Pages 的开源免费文件托管解决方案

大家好&#xff0c;我是 jonssonyan。 寻找一个稳定、快速、还最好是免费或成本极低的图床服务&#xff0c;一直是许多开发者、博主和内容创作者的痛点。公共图床可能说关就关&#xff0c;付费服务又增加成本。现在&#xff0c;一个名为 CloudFlare-ImgBed 的开源项目&#xf…

算法训练之动态规划(三)

♥♥♥~~~~~~欢迎光临知星小度博客空间~~~~~~♥♥♥ ♥♥♥零星地变得优秀~也能拼凑出星河~♥♥♥ ♥♥♥我们一起努力成为更好的自己~♥♥♥ ♥♥♥如果这一篇博客对你有帮助~别忘了点赞分享哦~♥♥♥ ♥♥♥如果有什么问题可以评论区留言或者私信我哦~♥♥♥ ✨✨✨✨✨✨ 个…

xv6-labs-2024 lab2

lab-2 0. 前置 课程记录 操作系统的隔离性&#xff0c;举例说明就是&#xff0c;当我们的shell&#xff0c;或者qq挂掉了&#xff0c;我们不希望因为他&#xff0c;去影响其他的进程&#xff0c;所以在不同的应用程序之间&#xff0c;需要有隔离性&#xff0c;并且&#xff0…