当前位置: 首页 > news >正文

文件编译、调试及库制作

文章目录

  • rwx对于目录和文件的区别
  • gcc编译器
    • 编译过程
    • gcc的其他参数
  • 动态库和静态库
    • 函数库
    • 静态库
      • 简述
      • 制作
    • 动态库(共享库)
      • 简述
      • 重点强调
      • 制作
  • makefile
    • makefile的规则
    • 2个函数
    • 3个自动变量
      • 普通变量(自定义变量)
      • 自动变量
    • 其他关键字
    • 模式规则
    • 伪目标
    • 其他参数
  • gdb调试器
    • 要求
    • 基础指令
    • 其他指令

rwx对于目录和文件的区别

文件目录
r文件的内容可以被查看。cat、more、vim目录的内容可以被查看。ls、 tree
w文件的内容可以被添加、修改、删除。vim、>、>>目录的内容可以被添加、修改、删除。rm、touch、mv、cp
x可执行、可运行。(可执行程序、脚本该目录可以被进入。cd

gcc编译器

编译过程

  1. 预处理:预处理器。
    • 将源文件,展开头文件,替换宏(变量宏、函数宏)、替换空行、空格、table。
    • gcc -E hello.c -o hello.i
      • -E:预处理选项
      • -o:重命名
  2. 编译:编译器。(所有编译过程中,最耗时)
    • 逐行检查程序中出现的语法和词法错误,简单的逻辑错误。(编译过程中,最耗时)
    • gcc -S hello.i -o hello.s
      • -S:编译选项,如果编译无误。生成 .s 汇编文件。
  3. 汇编:汇编器。
    • 将 .s 汇编文件中的所有汇编指令,翻译成二进制机器码。
    • gcc -c hello.s -o hello.o
      • -c:汇编选项。无错误检查。机械翻译。
  4. 链接:链接器。
    • 将 .o 的目标文件,链接库文件,数据段合并,地址回填。生成可执行文件。
    • gcc hello.o -o hello
      • 此过程无专用参数。

在这里插入图片描述

gcc的其他参数

  • -c:只生成目标文件。(过程包含:预处理、编译、汇编)
  • -v:查看 gcc 版本。
  • -I(大i):指定文件所在的目录位置。
  • -L:指定库文件所在的目录位置。
  • -l(小L):指定库名。(去掉前缀 lib 和后缀 .so或 .a)
  • -g:使用 gdb 调试前,编译程序添加。加 -g 编译的可执行文件,带有调试表。给 gdb 提供调试环境。
  • -Wall:显示所有的警告信息。
  • -D:在编译期间动态的向程序中注册变量宏。
    • 例:gcc -o test test.c -D MAX=10

动态库和静态库

函数库

  • 本质:一组函数。具有相近功能或操作同一数据结构。
    • <string.h>:strcpy/strcmp/strcat/strlen…
    • 自定义库:<mysort.h>:bubble_sort/select_sort/quick_sort/insert_sort…
  • 作用:
    1. 代码复用。
    2. 程序积累。
  • 发布形式:
    1. 源码形式:
      • 优点:方便使用者学习和使用
      • 缺点:1. 保密性差。2. 编译程序耗时。3. 编译受平台、版本限制。
    2. 二进制形式:
      • 优点、缺点,与上述相反。

静态库

简述

  • 机制:在编译程序时,复制静态库的代码片段到可执行程序中。

  • 优点:将函数库中的函数本地化,寻址方便,速度快。(库函数执行效率 = 自定义函数执行效率)

  • 缺点:消耗系统资源大,每个使用静态库的程序都要复制一份静态库,浪费内存。

  • 使用场景:多用于核心程序,保证时效性,可以忽略空间。

  • 静态库使用的原理:

    在这里插入图片描述

制作

  1. 生成 .o 目标文件。

    gcc add.c sub.c mul.c -c  -->add.o sub.o mul.o
    
  2. 制作静态库

    ar rcs lib静态库名.a add.o sub.o mul.o
    #ar:制作静态库的工具,gcc 不具备制作静态库功能
    #r:更新。c:创建(可省)。s:建立索引。
    #静态库库名,必须 lib 开头,以 .a 结尾。 
    
  3. 使用静态库

    gcc ./src/hello.c -o app -L ./ -l mymath -I ./inc 
    
  4. 查看静态库

    使用file lib静态库库名.a 查看。
    file libmymath.a
    

动态库(共享库)

简述

  • 机制:代码共享。
  • 优点:节省内存(共享)、易于更新(动态链接)。
  • 缺点:相较于静态库而言,函数调用速度慢(函数地址延时绑定)
  • 使用场景:
    1. 对程序执行速度要求不是很强烈,而对系统资源有一定要求的场景。
    2. 对应更新比较频繁的程序。
      • 停止运行程序。
      • 使用新库覆盖旧库(保证新库、旧库名称一致。接口一致。)
      • 重启程序。

在这里插入图片描述

重点强调

  1. 动态库是否加载到内存,取决于“程序是否运行”。
  2. 动态库加载到内存的位置不固定。

制作

  1. 生成与位置无关的目标文件

    gcc -fPIC -c add.c mul.c sub.c
    
  2. 制作动态库

    gcc -shared -o libmymath.so add.o sub.o mul.o
    
  3. 测试使用动态库

    gcc hello.c -o app -L ./lib -l mymath -I ./inc
    
  4. 查看动态库

    file libmymath.so
    
  5. 启动程序 ./app —>报错

    • 错误原因:“动态链接器”搜索动态库的路径没有指定。
      • 链接器:工作于 gcc 编译四过程中的“链接阶段”。工作结束后,生成可执行文件。
      • 动态链接器:工作于可执行程序运行之后,辅助加载器负责将动态库加载到内存。
  6. 解决上述错误: 基本思想:给动态链接器指定动态路径。

    1. 环境变量法:export LD_LIBRARY_PATH=./lib

      • 将当前动态库所在目录加入到环境变量中。
      • 终端一旦退出,环境变量的修改无效。
    2. 配置文件法:将上述修改环境变量的指令,写入到 ~/.bashrc 中

      • 每次启动终端,自动生效

      • export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: ./lib
        
    3. 拷贝法:受程序使用 libc 库的启发,将自定义的 libmymath.so 文件拷贝到 /lib 或 /usr/lib 中

      • 为了执行用户自定义程序,需要修改系统配置。
    4. 【推荐使用】缓存文件法:通过修改配置文件,修改缓存文件,生成动态链接器需要搜寻的新目录位置。

      • 打开配置文件:sudo vim /etc/ld.so.conf
      • 修改配置文件:将动态库的绝对路径添加到 /etc/ld.so.conf 文件中。
      • 使用命令 sudo ldconfig -v 动态更新 ld.so.cache 。该文件直接影响动态链接器搜索动态库位置。

makefile

  • 作用:进行项目管理。
  • 初步学习:1个规则、2个函数、3个自动变量。

makefile的规则

语法:

目标:依赖条件命令
  • 目标的时间必须晚于依赖条件的时间,否则更新目标。
  • 依赖条件如果不存在,寻找新的规则去产生依赖条件。
hello:hello.o add.o sub.o mul.ogcc hello.o add.o sub.o mul.o -0 hello
hello.o:hello.cgcc -c hello.c -o hello.o
sub.o:sub.cgcc -c sub.c -o sub.o
add.o:add.cgcc -c add.c -o add.o
mul.o:mul.cgcc -c mul.c -o mul.o

2个函数

wildcard 函数:用来匹配
src = $(wildcard ./*.c) :匹配当前工作目录下所有的.c文件,将文件名组成列表,赋值给变量 src
相当于:src = add.c sub.c mul.cpatsubst 函数:用来替换
obj = $(patsubst %.c, %.o, $(src)) :将参数3中包含参数1的部分,替换为参数2
相当于:obj = add.o sub.o mul.o

3个自动变量

普通变量(自定义变量)

  • 定义变量语法:变量名 = 变量值 (都是字符串)
    • 举例:foo = abc
  • 取变量值语法:$(变量)
    • 举例:bar = $(foo) ----> bar = abc

自动变量

  • $@:在规则的命令中,表示规则中目标。
  • $^:在规则的命令中,表示所有依赖条件。
  • $<:在规则的命令中,表示第一个依赖条件。如果将该变量应用在“规则模式”中,它可以将依赖条件中的每一个依赖,依次取出,套用规则模式。

其他关键字

  • ALL:

    • 用来给 makefile 文件指定“终极目标”。
    • makefile 文件,默认的规则为:从上而下,碰到的第一个规则中的目标为“终极目标”。我们可以使用 ALL 指定终极目标。
  • clean:

    • 用来借助 makefile 清除项目中的指定文件。如:*.o、a.out

    • 举例:

      clean:-rm -rf $(obj) a.out
      

模式规则

  • 可以将 makefile 文件中,具有严格统一形式的规则,使用模式规则代替。要求模式规则中,只能使用“$<”符号。
%.o:%.cgcc -c $< -o $@
  • 静态模式规则:
    • 将模式规则指定给某一个变量使用。
$(obj):%.o:%.cgcc -c $< -o $@

伪目标

  • 针对残缺的规则,也能使之生成目标。
.PHONY:clean ALL

其他参数

  • -n:模拟指定 makefile 不真正执行。
  • -f:指定命名为非“makefile”的文件,执行 make 命令。

gdb调试器

要求

  • 只能用来调试逻辑错误。
  • 必须添加 -g 参数,使用 gcc 编译生成的可执行文件,才能调试。

基础指令

  • -g:必须使用该参数编译可执行文件,否则没有调试表。
  • gdb ./a.out
  • list:list 1 列出源码,根据源码指定行号设置断点。1代表从1行开始。
  • b:b 55 表示在第55行添加断点。
  • run/r:运行程序,启动调试。
    • 代码会自动运行,停止在断点处,断点对应的代码行没有执行。
  • n/next:下一条指令(越过函数,不进入函数)
  • s/step:下一条指令(进入函数)
  • p/print:打印变量值。 如:p var ------查看变量var的值。
  • continue:继续执行断点后续命令。
  • finish:结束当前函数调用。
  • quit:退出当前 gdb 调试。

其他指令

  • start:不使用断点,直接启动程序,开始单步调试。
  • run/r:找出程序中出现段错误的位置。用法:gdb 启动调试,直接 run 。停止的位置就是出现段错误的位置。
  • 设置 main 函数命令行参数:
    1. set args 参1 参2 参3… (在 start/run 之前设置)
    2. run 参1 参2 参3…
  • info b:查看断点信息
  • b 23 if i = 5 :设置条件断点。只有满足该条件时,短点才生效。
  • delete 1:删除编号为1的断点。
  • ptype:查看变量类型。
  • display:设置跟踪变量。如:display i 跟踪变量i。
  • undisplay:取消跟踪变量。如:undisplay 2
  • bt:列出当前程序正存活着的栈帧。
  • frame:根据栈帧编号切换栈帧。
http://www.dtcms.com/a/315454.html

相关文章:

  • 人工智能领域、图欧科技、IMYAI智能助手2025年2月更新月报
  • pyspark中的kafka的读和写案例操作
  • Goby 漏洞安全通告| NestJS DevTools /inspector/graph/interact 命令执行漏洞(CVE-2025-54782)
  • libpq库使用
  • PDF转图片工具技术文档(命令行版本)
  • 【taro react】 ---- useModel 数据双向绑定 hook 实现
  • vue和react的框架原理
  • 基于PD控制器的四旋翼无人机群飞行控制系统simulink建模与仿真
  • SpringBoot原理揭秘--BeanFactory和ApplicationContext
  • day 46 神经网络-简版
  • 2025年渗透测试面试题总结-01(题目+回答)
  • 什么是压接孔?压接孔PCB制造流程
  • Zabbix 企业级高级应用
  • AI赋能复合材料与智能增材制造:前沿技术研修重磅
  • 【MATLAB】(八)矩阵
  • 盟接之桥说制造:价格战与品质:制造企业可持续发展的战略思考
  • 智能融合:增材制造多物理场AI建模与工业应用实战
  • PHP:历经岁月仍熠熠生辉的服务器端脚本语言
  • Spring 的 ioc 控制反转
  • 无人设备遥控器之信号切换技术篇
  • Guava 与 Caffeine 本地缓存系统详解
  • jQuery DOM节点操作详解
  • stm32F407 硬件COM事件触发六步换相
  • AI医疗革命:十大应用场景如何重塑未来医疗
  • 手绘风格制图新选择:如何用Excalidraw+cpolar构建你的视觉化工作流?
  • windos10 安装CentOS7 虚拟机笔记
  • Datawhale AI夏令营 第三期 task2
  • 基于ZYNQ ARM+FPGA的声呐数据采集系统设计
  • 01数据结构-平衡二叉树
  • Prometheus监控学习-安装