【Linux】编译器gcc/g++及其库的详细介绍

【Linux】编译器gcc/g++及其库的详细介绍
前言:

        上文我们学到了,LInux中的的编辑器vim【Linux】vim编辑器-ZEEKLOG博客

        本文来学习LInux中的编译器:gcc/g++

        gcc是C语言编译器,g++是C++编译器,这两个的使用一模一样。这里我们主要使用gcc给大家介绍

 1.格式

gcc  被编译的源文件   选项   编译的目标文件

选项:-o,生成指定文件

若不指定文件则默认生成a.out,若自定则生成指定的可执行文件

hyc@hcss-ecs-4ce7:~$ ls new new.c #未指定 hyc@hcss-ecs-4ce7:~$ gcc new.c hyc@hcss-ecs-4ce7:~$ ls a.out new new.c hyc@hcss-ecs-4ce7:~$ ./a.out 存在 存在 存在 存在 存在 #指定 hyc@hcss-ecs-4ce7:~$ gcc new.c -o new.exe hyc@hcss-ecs-4ce7:~$ ls new new.c new.exe hyc@hcss-ecs-4ce7:~$ ./new.exe 存在 存在 存在 存在 存在 

2.编译的过程 

2.1预处理

预处理的功能包括:替换宏定义、头文件展开、条件编译、去注释等

预处理的指令是从#开始的代码行

.c文件经过预处理会形成.i文件

-E选项:使编译器处理完预处理就停下
hyc@hcss-ecs-4ce7:~$ ls new new.c hyc@hcss-ecs-4ce7:~$ gcc -E new.c -o new.i hyc@hcss-ecs-4ce7:~$ ls new new.c new.i 

2.2编译

编译主要功能:检查.i文件代码是否规范,是否有语法错误。检查无误后gcc将代码翻译为汇编语言,生成.s文件

-S选项:使编译器处理完编译就停下
hyc@hcss-ecs-4ce7:~$ ls -l total 28 drw-rwxr-x 2 hyc hyc 4096 May 26 15:41 new -rw-rw-r-- 1 hyc hyc 219 May 29 21:58 new.c -rw-rw-r-- 1 hyc hyc 18047 Jun 3 13:31 new.i hyc@hcss-ecs-4ce7:~$ gcc -S new.i -o new.s hyc@hcss-ecs-4ce7:~$ ls -l total 32 drw-rwxr-x 2 hyc hyc 4096 May 26 15:41 new -rw-rw-r-- 1 hyc hyc 219 May 29 21:58 new.c -rw-rw-r-- 1 hyc hyc 18047 Jun 3 13:31 new.i -rw-rw-r-- 1 hyc hyc 895 Jun 3 13:38 new.s 

补充:为什么要将代码翻译成汇编?

        在计算机刚刚诞生的时代,没有任何编程语言,科学家是通过计算机上的元器件开关来控制计算机的。后来科学家发明了”打孔编程“,通过纸袋传递二进制信息

        再后来又发明了汇编语言,但汇编语言无法直接传递二进制信息。于是对于汇编语言的编译器诞生了。通过编译器将汇编语言映射为二进制,来操控计算机

        再后来就出现了各种各样的编译性语言:例如C/C++,java,python等等等等。对于这些语言我们也需要将其翻译为二进制,计算机才能明白我们的意图。

        但是这里有两条路:C -> 二进制,C ->汇编?选着哪条?

        显然我们选着了第二条路,因为C语言到二进制这无疑就困难的。而C到汇编语言仍是文本上的翻译,相对简单。我们可以直接站在巨人的肩膀上不用做二进制的翻译。

补充:编译器的诞生

        汇编语言被发明了,想要汇编语言被翻译成二进制,那么需要一个编译器来编译汇编语言。那汇编语言的编译器是怎么来的?答案是:先通过二进制编写一个编译器,得到汇编语言的编译器后,再通过使用汇编语言写一个汇编编译器。最终得到一个汇编版的汇编编译器。

        同理C语言被发明了,想要有一个C语言的编译器,只能先使用汇编语言编写一个C语言编译器,在通过C语言编译器写一个C语言的编译器。最终得到一个C语言版的C语言编译器。

        这就是编译器的自举

2.3汇编

汇编主要功能:将.s文件转化为机器可识别的二进制文件(.o)

-c选项:使编译器处理完汇编就停下
hyc@hcss-ecs-4ce7:~$ ls new new.c new.i new.s hyc@hcss-ecs-4ce7:~$ gcc -c new.s -o new.o hyc@hcss-ecs-4ce7:~$ ls -l total 36 drw-rwxr-x 2 hyc hyc 4096 May 26 15:41 new -rw-rw-r-- 1 hyc hyc 219 May 29 21:58 new.c -rw-rw-r-- 1 hyc hyc 18047 Jun 3 13:31 new.i -rw-rw-r-- 1 hyc hyc 1744 Jun 3 13:42 new.o -rw-rw-r-- 1 hyc hyc 895 Jun 3 13:38 new.s 

2.4连接

将库方法与我们自己写的目标文件连接起来,形成可执行文件
hyc@hcss-ecs-4ce7:~$ gcc new.o -o new.exe hyc@hcss-ecs-4ce7:~$ ls -l total 52 drw-rwxr-x 2 hyc hyc 4096 May 26 15:41 new -rw-rw-r-- 1 hyc hyc 219 May 29 21:58 new.c -rwxrwxr-x 1 hyc hyc 15960 Jun 3 13:51 new.exe -rw-rw-r-- 1 hyc hyc 18047 Jun 3 13:31 new.i -rw-rw-r-- 1 hyc hyc 1744 Jun 3 13:42 new.o -rw-rw-r-- 1 hyc hyc 895 Jun 3 13:38 new.s hyc@hcss-ecs-4ce7:~$ ./new.exe 存在 存在 存在 存在 存在

补充:

记忆选项:ESc

记忆文件后缀:.iso

对于编译器来说一般都是先将所有的文件编译为 .o文件,再将全部 .o文件一起连接

3.理解条件编译

条件编译是在预处理阶段执行的,其具体操作是将不满足条件的代码直接抹去,只保留满足条件的

演示:

新建一个代码

保存并退出,我们让其进行预处理,然后再查看代码

hyc@hcss-ecs-4ce7:~$ gcc -E test.c -o test.i hyc@hcss-ecs-4ce7:~$ vim test.i 

我们可以看到代码就只剩第一个printf函数了。

同时编译器还支持在命令行中动态的定义宏

#使用-D选项,可以实现在命令行中动态的定义宏 hyc@hcss-ecs-4ce7:~$ gcc test.c -o test hyc@hcss-ecs-4ce7:~$ ./test 收费->专业版 hyc@hcss-ecs-4ce7:~$ gcc test.c -o test -DM=10 hyc@hcss-ecs-4ce7:~$ ./test 免费->社区版 

预处理的本质就是编辑我们的代码。像我们用到的vs、xshell等等工具都有社区版和专业版的区别,但不论是那个版本其本质都是同一个项目,只是使用了条件编译将专业版进行阉割作为社区版供给普通人免费使用。

4.动态库静态库

什么的库?

        库是编程中的 “工具箱”,通过复用成熟代码,让开发者聚焦业务逻辑,大幅提升开发效率和代码质量。从基础的标准库到专业的第三方库,它们构成了现代软件开发的核心生态,是实现快速迭代和复杂功能的关键支撑。

补充:ldd指令

ldd指令可以让我们查看可执行程序依赖了那些库

这里我们可以看到这个可执行程序依赖了C语言的动态库。

库的命名方式

动态库 :

在代码加载到内存时,会进行动态连接:将程序中要使用的库实现函数,在库中找到相应位置,并对函数地址进行替换。这样在调用对应函数时,就会直接跳转到库中相应位置进行执行。执行完毕跳转回来继续向下执行。

静态库:

静态库与动态库相反,在编译阶段就会将所需要部分的代码,直接拷贝到我们自己的代码中。

补充:

1.Linux下动态库为:xxx.so    静态库为:xxx.a

   windows下动态库为:xxx.dll    静态库为:xxx.lib

2.静态库只在连接时有用,一旦形成可执行文件后, 就不再需要了

动静态库对比

1.动态库所形成的可执行文件,体积小

2.可执行文件对静态库依赖小,动态库依赖大不可缺失

3.运行程序需要加载至内存中,静态库的连接方式会导致内存中出现大量重复代码

4.动态库的连接方式比较节省内存空间和磁盘资源

(一般的可执行程序都是默认动态连接的)

简单理解库的本质

库分为两部分:一个是开放的.h头文件包含各个函数的声明,另一个是的各个函数的实现,是编译后的.o文件组成的集合

Read more

用 Codex + GitHub Spec-Kit 做一次“规格驱动开发”实战

用 Codex + GitHub Spec-Kit 做一次“规格驱动开发”实战

* 用 Codex + GitHub Spec-Kit 做一次“规格驱动开发”实战 * 1) 初始化:把 spec-kit 工作区真正建起来(多种方式) * 方式 A:uvx 一次性运行(推荐) * 方式 B:uv tool install(全局安装 specify) * 方式 C:pipx 安装(Python 工具常用法) * 2) 初始化后,正确的目录结构长什么样( * 3) 在 Codex 里跑 speckit:统一输入规则(非常重要) * 4) 标准流水线:Constitution → Spec → Plan → Tasks → Implement * Step 1:

By Ne0inhk
一文读懂机器人设计:从模块拆解到场景适配的核心逻辑

一文读懂机器人设计:从模块拆解到场景适配的核心逻辑

无论是入门级的智能循迹小车,还是复杂的自主导航机器人,其设计都遵循着一套通用的核心框架与工程化流程。很多开发者在接触机器人开发时,易陷入“重硬件选型、轻系统设计”“重功能实现、轻工程实践”的误区,最终导致项目周期延误、可靠性不足或成本失控。本文将以“感知-决策-执行-支撑”四大核心维度为基础,按功能分层与物理模块拆解机器人核心架构,同时新增深度工程实践建议,覆盖开发流程、可靠性设计与成本控制,形成从理论拆解到落地实践的完整知识体系。不同场景下的机器人虽会增减模块,但这套基础框架与工程方法始终通用,助力开发者高效落地机器人项目。 一、核心支撑模块:机器人的“物理底座”        支撑模块是机器人的基础载体,直接决定其运动能力、运行稳定性与环境适配性,如同大楼的地基与承重结构。该模块核心解决“承载”与“供能”两大核心问题,主要分为机械结构和电源供电两大子模块,需从工程力学与电源工程角度进行系统化设计。 1. 机械结构模块:撑起机器人的“骨架”         机械结构的设计核心是在“承载能力-运动灵活性-场景适配性”三者间找到最优平衡,需结合工程力学、材料科

By Ne0inhk
深度评测 GLM-5:AtomGit 首发模型的代码生成实战体验

深度评测 GLM-5:AtomGit 首发模型的代码生成实战体验

文章目录 * 🔍 深度评测 GLM-5:AtomGit 首发模型的代码生成实战体验 * 📋 前言 * 🏗️ 一、模型参数配置 * ⚡ 二、核心能力实测:Flask API 完整服务生成 * 2.1 测试任务 * 2.2 模型输出分析 * 2.3 项目结构输出 * 2.4 核心代码质量评测 * 配置文件 (config.py) * 用户模型 (models/user.py) * 错误处理 (utils/errors.py) * 数据验证 (utils/validators.py) * 📊 三、性能表现评估 * 💡 四、使用技巧与建议 * 4.1 提示词优化技巧 * 4.2 参数调优建议

By Ne0inhk
GitCode Notebook 昇腾 910B NPU 平台 ops-transformer 算子:全场景性能测试与验证及与原生 PyTorch 注意力的深度性能对比

GitCode Notebook 昇腾 910B NPU 平台 ops-transformer 算子:全场景性能测试与验证及与原生 PyTorch 注意力的深度性能对比

GitCode Notebook 昇腾 910B NPU 平台 ops-transformer 算子:全场景性能测试与验证及与原生 PyTorch 注意力的深度性能对比 前言 基于 GitCode Notebook 昇腾 910B + CANN 8.2.rc1 环境,聚焦 ops-transformer 算子的完整部署与性能验证,通过清晰的环境配置、依赖安装、多场景性能测试及与原生 PyTorch 注意力的对比实验,直观呈现其在低时延、高吞吐量及显存优化上的核心优势,为 LLM 训练 / 推理等 NLP 任务提供高效、可落地的算子应用参考 前提条件 开发环境准备:GitCode Notebook NPU 启动配置 1、GitCode启动NoteBook资源 计算类型:NPUCANN是昇腾 NPU设计的异构计算架构,

By Ne0inhk