首页 > 系统相关 >Linux下gcc编译,动态库和静态库,makefile,gdb调试

Linux下gcc编译,动态库和静态库,makefile,gdb调试

时间:2023-10-24 20:56:22浏览次数:35  
标签:gcc sub makefile add gdb mul hello 变量

1.编译过程

1.1 预处理(Pre-Processing)

  展开头文件, 宏替换(变量宏、函数宏)、替换空格等

gcc -E hello.c  -o hello.i     // -E 预处理选项, -o 重命名

1.2 编译(Compilation)

  逐行检查程序中出现的语法错误,简单的逻辑错误

gcc -S hello.i -o hello.s

1.3 汇编(Assemble)

  将 .s 汇编文件中所有的汇编指令翻译成二进制机器码(下面就是来了个截图,二进制显示了乱码)

gcc -c hello.s -o hello.o

1.4 链接(Linking)

  将 .o 的目标文件,链接库文件、数据段合并,地址回填(把汇编里相对地址替换成程序运行后真正可以运行的地址)。生成可执行文件 hello

gcc hello.o -o hello

1.5 gcc常用参数

-E // 展开头文件
-s // 生成汇编文件
-c // 编译生成2进制文件
-I // 指定头文件路径 大i
-L // 指定库文件路径
-l // 指定库名 小L
-g // 包含调试信息 
-On // n取 0-3, n 越大优化级别越高
-Wall //warning all 显示所有警告
-D // 编译时动态注入一个宏, 编译的时候控制#define的具体数值

2.动态库和静态库

2.1 函数库

  本质:把具有相同功能的一组函数放到同一份文件中(源码或二进制的形式)

2.2 静态库

  对执行速度有要求

  • 机制:把引入的库文件通过编译直接复制到 .out 文件中
  • 优点:将函数库中的函数本地化,寻址方便,速度快(函数库执行效率 = 自定义函数的执行效率)
  • 缺点:每个程序都需要复制一份,会浪费内存

  制作静态库: 

gcc -c add.c sub.c mul.c    // 制作 .o 文件
ar rs libmymath.a add.o sub.o mul.o    // 制作静态库
gcc hello.c -L ./ -lmymath -o app    // 指定头文件路径, 指定库名, 设置文件输出名app

2.3 动态库

  对执行速度不敏感,对系统资源敏感;更新比较频繁(可以避免完全重新编译)

  • 机制:代码共享
  • 优点:节省内存(共享)、易于更新(动态链接)
  • 缺点:相较于静态库函数调用速度慢,函数地址是延时绑定机制
gcc -c -fPIC add.c sub.c mul.c    // -fPIC生成与位置无关的目标文件
gcc -shared -o libmymath.so sub.o mul.o add.o    // 生成一个动态库
gcc hello.c -o app -L ./lib -l mymath -I ./inc    // 生成文件

 启动 ./app 报错,错误原因:”动态链接器“ ld-linux-x86-64.so.2 搜索动态库的路径没有指定

  链接器:工作于 gcc 编译过程中的链接阶段。工作结束后生成可执行文件

  动态链接器:工作于可执行程序运行之后,辅助加载器负责将动态库加载到内存

 解决办法

  环境变量法:export LD_LIBRARY_PATH=./lib 将当前动态库所在的目录加入到环境变量,终端退出后环境变量就会失效

  配置文件法:vi .bashrc 加入一行 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./lib,重启终端,每次启动终端自动生效

  拷贝法:把自己的动态库直接拷贝到 /lib 或 /usr/lib 中

  缓存文件法(推荐):修改配置文件,修改缓存文件,生成动态链接器需要搜索的新目录位置

sudo vim /etc/ld.so.conf    // 修改动态链接库的路径
// 将绝对路径增加到文件中
sudo ldconfig -v    // 更新 ld.so.cache 该文件影响动态链接库搜索的位置

3.makefile

3.1 语法

 目标:依赖条件

 tab缩进,指令

hello:hello.o add.o sub.o mul.o
    gcc hello.o add.o sub.o mul.o -o hello
hello.o:hello.c
    gcc -c hello.c -o hello.o
sub.o:sub.c
    gcc -c sub.c -o sub.o
add.o:add.c
    gcc -c add.c -o add.o
mul.o:mul.c
    gcc -c mul.c -o mul.o

 模式规则:在makefile中,具有有严格统一的规则,使用模式规则代替,模式规则中只能使用 $< 符号

%.o:%.c
    gcc -c $< -o $@

 静态模式规则:将模式规则指定给某一个变量使用

$(obj):%.o:%.c
    gcc -c $< -o $@

 伪目标:针对残缺的规则,使之生成目标(比如有一个clean.o文件已经是最新的,就不会执行clean清除命令

.PHONY:clean ALL

3.2 函数介绍

3.2.1 wildcard 函数

// 匹配当前工作目录下的所有 .c 文件,将文件名组成列表,赋值给 src 变量
// src = add.c sub.c mul.c hello.o
src = $(wildcard ./*.c)

3.2.2 patsubst 函数

// 用来替换参数, 将 参数3 中包含 参数1 的部分替换为 参数2
// obj = add.o sub.o mul.o hello.o
obj = $(patsubst %.c, %.o, $(src))

3.3 普通变量和自动变量

 普通变量

  • 定义变量语法:变量名 = 变量值     (foo = abc)
  • 取变量值语法:$(变量)           (bar = $abc ---> bar = abc)

 自动变量

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

3.4 关键字

  ALL: 默认情况下第一组生成文件的目标就是终极目标,或者显示的写ALL:hello表示终极目标,完成后结束makefile

  clean: 借助makefile清除项目中的指定文件,例如(clean: -rm -rf $(obj) hello

  指令 make -n 模拟执行命令,不真正执行,可以先看一次避免出问题

3.5 修改后的 makefile

src = $(wildcard *.c)
obj = $(patsubst %.c, %.o, $(src))

CC = gcc
target = app

ALL:$(target)

$(target):$(obj)
    $(CC) $^ -o $@

$(obj):%.o %.c
    $(CC) -c $< -o $@

clean:
    -rm -rf $(obj) $(target)

.PHONY:clean ALL

4. gdb调试

4.1 基础指令

 基础的断点设置和继续运行等指令

  • -g:使用该指令编译可执行文件,否则没有调试表
  • gdb ./a.out
  • list:list 1 列出源码,根据源码指定行号设置断点,1表示从第一行开始显示源码
  • b:b 55 在第55行添加断点
  • run/r:运行程序,启动调试(可以直接找到停止位置就是出错位置)
  • next/n:下一条指令(越过函数)
  • step/s:下一条执行(进入函数内部)
  • print/p:打印变量值,如p var 查看 var 变量的值
  • continue:执行到下一个断点
  • finish:结束当前函数调用
  • quit:退出调试
  • start:不使用断点,直接开始单步调试

 设置一些条件和查看栈帧及变量

  • set args:启动gdb调试后,通过该指令可以设置main函数的参数,需要在start和run指令之前设置
  • info b:查看当前断点信息表
  • b 23 if i=5:设置断点在23行,如果 i=5 时断点才生效
  • ptybe:查看变量类型
  • display:设置跟踪变量,display i,跟踪变量 i
  • undisplay:取消跟踪变量
  • bt:列出当前程序存活的栈帧
  • frame:如果有多层调用,在内层想查看外层栈帧里的参数,使用 frame n (n 是栈帧编号)切换栈帧,再使用 p var 打印变量

标签:gcc,sub,makefile,add,gdb,mul,hello,变量
From: https://www.cnblogs.com/stux/p/17785144.html

相关文章

  • makefile
    Makefile规则生成目标:make[目标],如果make后面没有跟目标,那就生成makefile中第一个规则的第一个目标(即test);也可以make指定的目标,如makeclean 命令被执行的2个条件:1.依赖文件比目标文件新没有目标文件。为什么要伪目标?因为在执行像makeclean这样的指令时,由于他没有......
  • GDB 的使用
    GDB是一个共用工具,我贴两个链接,知道如何使用就行https://blog.csdn.net/m0_65346989/article/details/130362796https://blog.csdn.net/qq_41960196/article/details/121591749......
  • Makefile基础使用和实战详解
    一、基础Makefile其实只是一个指示make程序如何为我们工作的命令文件,我们说Makefile其实是在说make。而对于项目来说,Makefile是指软件项目的编译环境。Makefile的好坏对于项目开发有些什么影响呢?设计得好的Makefile,当我们重新编译时,只需编译那些上次编译成功后修改过的......
  • Makefile语法详细总结及示例解析(快速掌握)
     文章目录一、简介二、常用规则介绍2.1递归扩展变量2.2常见的自动化变量解析2.3常用的编译器宏定义2.4条件语法2.5其他特殊变量(1)VPATH变量(2).PHONY变量(3)include变量(4)$(Q)变量2.6Makefile实例2.7添加打印信息2.8实例解析2.9objs的用法三、......
  • Replacing gcc and g++ with GNU version in macOS
    AfterweinstallXcodeCommandLineTools,wewillgetgccandg++in/Library/Developer/CommandLineTools/usr/binandthesamecontentsin/usr/bin.Buttheproblemisthatgccandg++aresameasclangandclang++.Proofcanbeobtainedfromthefollowin......
  • Makefile快速入门
    编译概述编译基础:使用GCC编译程序时可以分为4个阶段:(1)预处理(pre-processing)-E.c---->.i-I(Include)将源文件生成中间文件(2)编译(compiling)-S.i---->.s 将中间文件生成汇编(3)汇编(Assembling)-c.s--->.o 将汇编转换成机器代码(4)链接(Linking) .o--->可执行文件......
  • Makefile基础入门
    第1章Makefile快速入门基础概念make:项目构建工具——用于管理文件的更新Makefile:规则文件,告诉make如何进行编译与管理Makefile(取名makefile也行)其实就是一个脚本文件。快速入门创建文本文档——文件名Makefile#代表注释显示规则:一条显示规则由以下构成 1......
  • makefile学习记录 :一个工程里有多个makefile 如何make根目录下的makefile 调用子目录
    注:本文个人学习记录目的:一个工程里有多个makefile如何make根目录下的makefile调用子目录下的makefile,编译所有.c文件如图所示目录结构,根目录server:makefile;子目录so:makefile  根目录makefile:GCC=gccAPP=server ALL_C=$(wildcard./*.c)C_OBJ=$(notdir$......
  • Makefile详解—clean
    每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。这是一个“修养”。一般的风格都是: clean:rmedit$(objects) 更为稳健的做法是: .PHONY:cleanclean:-rmedit$(objects) 前面说过,.PHONY意思表示clean是一......
  • Makefile knowledge summarization
    WildcardThewildcardinmakefileissimilarwithmacroinC/C++,itisn'tsimilarwithwildcardinlinuxshell,soitdoesn'texpendautomatically.object1=*.c//*.cobject2=$(wildcard*.cpp)//main.cppt1.cppt2.cppAutomaticallygene......