GNU快速入门

25 年 5 月 25 日 星期日
1660 字
9 分钟

GNU 快速入门

​ 我很难想象GNU的基础竟然不被大多数cs的学生熟知...因此我想写点东西

​ 由于如果我们需要详细的聊一聊GNU的背景,设计理由,以及更多trick,需要较多的专业知识,现在我们需要建立的初步认知就是GNU就是C语言/C++配套的工具链,你可以用它更好的理解C语言/C++,并且了解更多底层相关的知识

前言

what you need

任意的编辑器(vscode ,sublime text ,小熊猫cpp,Devc++,visual stdio) 尽量选择常见的

具有C语言第一课的基本知识,知道从.c文件到可执行文件到输出的基本信息流(我也会提一下的)

会动的手

一整套工具链

  • gcc : GNU的C语言编译器

  • g++

    的C++编译器

  • gdb : 调试器

  • as : 汇编器

  • ld :链接器

  • make :自动化构建工具

  • objump :二进制查看工具

  • nm :符号表查看工具

  • readlf : 查看ELF文件结构

  • ....

    上面的排版非常丑陋,但是我真的懒得改了,对不起 ......

workflow

​ 下面就根据工作的流程为准线推荐,我尽量让一切保持逻辑和关联

基本信息流

​ 这个可以理解为概述,也就是what you need里面的C语言第一课的基本知识

bash
hello.c -> hello.i -> hello.s -> hello .o -> hello(可执行文件)

​ 经过预处理->编译->汇编->链接,最终得到可执行程序

​ 命令一步步如下

bash
gcc -E hello.c -o hello.i

​ 用于处理**#include,#define等内容(这也是很重要的,需要知道.c文件多个不同的内容的‘翻译’是在多个阶段完成的),因此逻辑就复现出来了:哪些内容哪些阶段**翻译,在这里应该庆幸前文的基本信息流可以作为非常合适的参照,逐步推进(变成填空题了其实

bash
gcc -S hello.i -o hello.s

​ 生成汇编语言.s文件

bash
gcc -c hello.s -o hello.o

​ 生成目标文件.o(或者说是.out)

bash
gcc hello.o -o hello

​ 将.o文件和库链接生成最终可执行程序

​ 我详细只要我没有详细注释的地方,一般看的都是一头雾水(虽然详细注释也可能发生这种情况),上文只是为了严谨罗列了一些中间过程,在我们写代码的时候或者了解底层知识的时候,我们可能会用到上述的命令,并查看对应的文件内容,下面一条命令作为上面所有命令的并集(也就是直接一步跳到终点)

关键命令
bash
gcc hello.c -o test

​ -o是特定参数,固定搭配,test就是生成文件的名称,这是可以自定义命名的,生成的文件就是test.out,那如何运行呢

bash
./test.out

​ 最后输出的结果就是我们在visual stdio里面点一下运行出来的结果啦

请先不要抱有为什么用这些繁杂的流程来代替一键完成的质疑,或许后文我会仔细说说,或许你可以尝试搜索相关知识

GCC常用参数

​ 对于一个工具来说我们在乎他的使用方式,在命令行的形式上,不同的参数就代表不同的形式,可以有不同的功能(为什么我想起来电视遥控...)

编译并输出可执行程序

bash
gcc hello.c -o hello.o

​ 常用参数说明(没错,我要开始列一些无聊的大纲了

参数说明
-o指定输出文件名
-Wall显示所有警告信息
-g生成调试信息(配合 gdb 使用)
-O2启用优化
-std=c99使用 C99 标准
-c仅编译生成 .o 目标文件

​ 不错,gpt生成基础繁琐知识就是方便

多文件编译

​ 一般来说,我们不喜欢把一整个工程放在同一个.c文件里面,这会导致难以找到对应功能的代码,很难修改,所以多文件就应运而生了,在不同文件实现不同的功能,比如售票系统,分成买票,显示票信息等...所以多文件要如何编译呢,gcc中可以这么做

bash
gcc main.c utils.c -o myprog

main.c和utils.c是我写的C语言文件,myprog就是最后生成的可执行文件啦(似乎看着没啥难度耶...

GDB调试

​ 到这里我们惊讶的发现C语言/C++实在太简单了,所以我可以用逻辑实现世界上所有的功能,然后用gcc生成可执行文件,成功变成造物主!你说得对,但是万一泥人捏丑了怎么办,为了精益求精我们要选择调试器,知道哪个泥人丑了,然后修改,之后重新编译(或许可以叫世界刷新?) 好吧,恶俗无聊的笑话就这样吧。

​ GDB作为GNU工具链里关键的调试工具,可以让我们轻松的得到我们写的.c文件在计算机里面发生了什么,进行了哪些操作,这样根据更底层的相关逻辑推导出表层的.c文件哪个模块有问题

编译+启动调试器
bash
gcc -g  hello.c -o hello.o

-g就是为了编译时保存调试信息,反正记住就好吧...东西有点多,懒得写了,意义有限

bash
gdb ./hello

开始调试!这个时候shell窗口应该会给你提示的(或许是界面的变化?或许是弹窗?希望你可以知道这个提示是什么)

然后就是常见命令(ai你真棒)

命令功能说明
break main在 main 函数设断点
run运行程序
next / n单步执行(不进入函数)
step / s单步执行(进入函数)
print x打印变量 x 的值
bt显示函数调用栈 backtrace
info locals显示当前所有局部变量
quit退出调试器

什么是 Makefile?

​ Makefile 是一个自动化构建脚本。它告诉 make 命令应该如何构建程序,哪些文件依赖哪些,如何自动重编译修改过的文件。

示例 Makefile

makefile
# 指定编译器
CC = gcc
# 编译选项
CFLAGS = -Wall -g

# 最终目标
all: main

# 链接目标文件生成可执行文件
main: main.o utils.o
	$(CC) $(CFLAGS) -o main main.o utils.o

# 编译源文件生成目标文件
main.o: main.c
	$(CC) $(CFLAGS) -c main.c

utils.o: utils.c
	$(CC) $(CFLAGS) -c utils.c

# 清理命令
clean:
	rm -f *.o main

文章标题:GNU快速入门

文章作者:io-wy

文章链接:https://io-wy.github.io/posts/gnu-%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8[复制]

最后修改时间:


商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接,您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但是分发衍生作品时必须采用相同的许可协议。
本文采用CC BY-NC-SA 4.0进行许可。