news 2026/7/30 11:26:59

【Linux】基础开发工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【Linux】基础开发工具



🎬 个人主页道尔柯南

专栏传送门:《C语言》《C++》《Linux操作系统
昙花一现,却等待了整个白昼;蝉鸣一夏,却蛰伏了好几个四季。

文章目录

  • 1->编译器gcc/g++
    • 1.1 基础知识
    • 1.2 gcc编译选项
      • 1.2.1 预处理(进行宏替换/去注释/条件编译/头文件展开等)
      • 1.2.2 编译(生成汇编)
      • 1.2.3 汇编 (生成机器可识别代码)
      • 1.2.4 链接(生成可执行文件或库文件)
    • 1.3 动态链接和静态链接
    • 1.4 动态库和静态库
    • 1.5 gcc其他常用选项---了解即可
  • 2->自动化建构make/Makefile
    • 2.1 对make和Makefile的理解
    • 2.2 Makefile文件
    • 2.3 make是如何工作的
  • 结尾

1->编译器gcc/g++

1.1 基础知识

预处理:进行宏替换/去注释/条件编译/头文件展开等
编译:生成汇编
汇编:生成机器可识别代码
链接: 生成可执行文件或库文件

1.2 gcc编译选项

格式:

gcc[选项]要编译的文件[选项]目标文件

1.2.1 预处理(进行宏替换/去注释/条件编译/头文件展开等)

预处理功能主要包括宏定义,文件包含,条件编译,去注释等。预处理指令是以#号开头的代码行。

• 实例: gcc -E hello.c -o hello.

gcc-E hello.c-o hello.i

选项 “-E” ,该选项的作用是让 gcc 在预处理结束后停止编译过程。

选项 “-o” 是指目标文件,“.i” 文件为已经过预处理的C原始程序。

1.2.2 编译(生成汇编)

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。

用户可以使用 “-S” 选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

• 实例:

gcc-S hello.i-o hello.s

1.2.3 汇编 (生成机器可识别代码)

汇编阶段是把编译阶段生成的 “.s” 文件转成目标文件

读者在此可使用选项 “-c” 就可看到汇编代码已转化为 “.o” 的二进制目标代码了

• 实例:

gcc-c hello.s-o hello.o

1.2.4 链接(生成可执行文件或库文件)

链接阶段本质是将.o文件合并

• 实例:

gcc hello.o-o hello

1.3 动态链接和静态链接

在我们的实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义的函数,但是每个源文件都是独立编译的,即每个.c文件会形成一个.o文件,为了满足前面说的依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成一个可以执行的程序。这个链接的过程就是静态链接
静态链接的缺点很明显:

浪费空间:因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有printf.o,所以同一个目标文件都在内存存在多个副本;

更新比较困难:因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。

动态链接的出现解决了静态链接中提到问题。动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件。动态链接其实远比静态链接要常用得多。

1.4 动态库和静态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的libc.so.6就是动态库。gcc在编译时默认使用动态库。完成了链接之后,gcc就可以生成可执行文件,如下所示。gcc hello.o -o hello

gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。

注意:
Linux下,动态库XXX.so,静态库XXX.a
Windows下,动态库XXX.dll,静态库XXX.lib

动静态库对比:

1.动态库形成的可执行程序体积一定很小

2.可执行程序对静态库的依赖度小,动态库不能缺失

3.程序运行,需要加载到内存,静态链接的,会在内存中出现大量的重复代码。

4.动态链接,比较节省内存和磁盘资源。

1.5 gcc其他常用选项—了解即可

-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面

-S 编译到汇编语言不进行汇编和链接

-c 编译到目标代码

-o 文件输出到 文件

-static 此选项对生成的文件采用静态链接

-g 生成调试信息。GNU 调试器可利用该信息。

-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统有动态库.

-O0

-O1

-O2

-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高

-w 不生成任何警告信息。

-Wall 生成所有警告信息。

2->自动化建构make/Makefile

2.1 对make和Makefile的理解

会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力

一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作

makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

2.2 Makefile文件

myproc:myproc.c//依赖关系gcc-o myproc myproc.c//依赖方法.PHONY:clean//伪目标clean://依赖关系rm-f myproc//依赖方法

依赖关系:上面的文件myproc,它依赖myproc.c

依赖方法:gcc -o myproc myproc.c ,就是与之对应的依赖关系

项目清理:

工程是需要被清理的

像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。

2.3 make是如何工作的

myproc:myproc.o gcc myproc.o-o myproc myproc.o:myproc.s gcc-c myproc.s-o myproc.o myproc.s:myproc.i gcc-S myproc.i-o myproc.s myproc.i:myproc.c gcc-E myproc.c-o myproc.i.PHONY:clean clean:rm-f*.i*.s*.o myproc

编译:

$ make gcc-E myproc.c-o myproc.i gcc-S myproc.i-o myproc.s gcc-c myproc.s-o myproc.o gcc myproc.o-o myproc

在默认的方式下,也就是我们只输入make命令。那么:

1.make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2.如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到 myproc 这个文件,并把这个文件作为最终的目标文件。

3.如果 myproc 文件不存在,或是 myproc 所依赖的后面的 myproc.o 文件的文件修改时间要比 myproc 这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成 myproc 这个文件。

4.如果 myproc 所依赖的 myproc.o 文件不存在,那么 make 会在当前文件中找目标为 myproc.o 文件的依赖性,如果找到则再根据那一个规则生成 myproc.o 文件。(这有点像一个堆栈的过程)

5.当然,你的C文件和H文件是存在的啦,于是 make 会生成 myproc.o 文件,然后再用 myproc.o 文件声明 make 的终极任务,也就是执行文件 hello 了。

6.这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

7.在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

8.make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。


结尾

uu们,本文的内容到这里就全部结束了,道尔在这里再次感谢您的阅读!

道尔柯南

C/C++ & Linux 底层探索者 | 一个正在努力学习的技术博主

👀【关注】跟随我一起深耕技术领域,见证每一次成长。
❤️【点赞】让优质内容被更多人看见,让知识传递更有力量。
【收藏】把核心知识点存好,在需要时随时查、随时用。
💬【评论】分享你的经验或疑问,评论区一起交流避坑!

不要忘记给博主“一键四连”哦!

“今日目标达成!”

结语:希望对学习Linux相关内容的uu有所帮助,不要忘记给博主“一键四连”哦!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/30 11:23:22

Python zlib模块深度解析:从DEFLATE原理到流式压缩实战

1. 项目概述:为什么Python开发者绕不开zlib? 如果你用Python处理过网络数据、文件存储或者任何需要节省空间或带宽的场景,那你大概率已经和zlib打过照面了,哪怕你自己没意识到。这个看似不起眼的库,其实是Python标准库…

作者头像 李华
网站建设 2026/7/30 11:22:42

嵌入式显示开发实战:从图像取模到DMA驱动的全流程优化

1. 从像素到显示:嵌入式显示开发的底层逻辑在嵌入式开发里,让一块LCD或OLED屏幕亮起来,并显示出我们想要的图像、文字或界面,是很多项目从“能跑”到“好用”的关键一步。无论是STM32、MSP430还是MSPM0G3507,驱动屏幕的…

作者头像 李华
网站建设 2026/7/30 11:21:25

基于Django的洗衣服务电商平台开发实践

1. 项目概述:基于Django的洗衣服务电商平台这个项目是一个典型的O2O(线上到线下)洗衣服务平台,采用Django作为后端框架构建。作为从业十多年的全栈开发者,我认为这类项目最核心的价值在于打通传统洗衣行业的数字化闭环…

作者头像 李华
网站建设 2026/7/30 11:21:08

从 three.js 编辑器看国产开源 3D 工具的未来

从 three.js 编辑器看国产开源 3D 工具的未来 本文围绕 three.js 编辑器(一款基于 Three.js 的 AI 驱动可视化低代码编辑器)展开。- 🌐 在线预览:https://z2586300277.github.io/threejs-editor/- 📦 GitHub 开源仓库&…

作者头像 李华
网站建设 2026/7/30 11:20:41

Python Lambda表达式:匿名函数在数据处理与高阶函数中的核心应用

1. 项目概述:为什么Lambda表达式是Python的“瑞士军刀”? 在Python的日常开发中,尤其是处理数据、编写回调函数或者进行函数式编程时,你总会遇到一种看起来有点“神秘”的语法: lambda 。它不像 def 那样正式地定义…

作者头像 李华