首页 > 其他分享 > 8.makefile-gdb-文件IO

8.makefile-gdb-文件IO

时间:2023-08-21 18:34:33浏览次数:38  
标签:文件 依赖 变量 makefile 目标 gdb IO 规则

8.makefile-gdb-文件IO

学习目标:

熟练使用规则编写简单的makefile文件

熟练使用makefile中的变量

熟练使用makefile中的函数

熟练掌握gdb相关调试命令的使用

了解概念: pcb和文件描述符,虚拟地址空间

熟练掌握Linux系统IO函数的使用

1.makefile

makefile文件中定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

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

makefile文件中会使用gcc编译器对源代码进行编译,最终生成可执行文件或者是库文件。

makefile文件的命名:makefile或者Makefile

1.1 makefile的基本规则

makefile由一组规则组成,规则如下:

目标: 依赖
(tab)命令

makefile基本规则三要素:

▶目标: 要生成的目标文件

▶ 依赖: 目标文件由哪些文件生成

▶ 命令: 通过执行该命令由依赖文件生成目标

下面以具体的例子来讲解:

当前目录下有main.c fun1.c fun2.c sum.c,根据这个基本规则编写一个简单的makefile文件,生成可执行文件main。

第一个版本的makefile:

缺点:效率低,修改一个文件,所有的文件会全部重新编译。

1.2 makefile工作原理

基本原则

☀若想生成目标,检查规则中的所有的依赖文件是否都存在:

●如果有的依赖文件不存在,则向下搜索规则,看是否有生成该依赖文件的规则:

如果有规则用来生成该依赖文件,则执行规则中的命令生成依赖文件;

如果没有规则用来生成该依赖文件,则报错。

■如果所有依赖都存在,检查规则中的目标是否需要更新,必须先检查它的所有依赖,依赖中有任何一个被更新,则目标必须更新(检查的规则是哪个时间大哪个最新)

▶ 若目标的时间 > 依赖的时间,不更新

▶ 若目标的时间 < 依赖的时间,则更新

总结:

▶ 分析各个目标和依赖之间的关系

▶ 根据依赖关系自底向上执行命令

▶ 根据依赖文件的时间和目标文件的时间确定是否需要更新

▶ 如果目标不依赖任何条件,则执行对应命令,以示更新(如:伪目标)

第二个版本:

缺点: 冗余,若.c文件数量很多,编写起来比较麻烦。

1.3 makefile中的变量

在makefile中使用变量有点类似于C语言中的宏定义, 使用该变量相当于内容替换, 使用变量可以使makefile易于维护, 修改起来变得简单。

makefile有三种类型的变量:

▶ 普通变量

▶ 自带变量

▶ 自动变量

普通变量

▶ 变量定义直接用 =

▶ 使用变量值用 $(变量名)

如:下面是变量的定义和使用

foo = abc          // 定义变量并赋值

bar = $(foo)        // 使用变量,$(变量名)

定义了两个变量: foo、bar,其中bar的值是foo变量值的引用。

除了使用用户自定义变量,makefile中也提供了一些变量(变量名大写)供用户直接使用,我们可以直接对其进行赋值:

CC = gcc #arm-linux-gcc

CPPFLAGS : C预处理的选项 -I

CFLAGS:  C编译器的选项 -Wall -g -c

LDFLAGS :  链接器选项 -L  -l

自动变量

▶ $@: 表示规则中的目标

▶ $<: 表示规则中的第一个条件

▶ $^: 表示规则中的所有条件, 组成一个列表, 以空格隔开, 如果这个列表中有重复的项则消除重复项。

特别注意:自动变量只能在规则的命令中使用.

模式规则

至少在规则的目标定义中要包含’%’,‘%’表示一个或多个,在依赖条件中同样可以使用’%’,依赖条件中的’%’的取值取决于其目标:

比如: main.o:main.c fun1.o: fun1.c fun2.o:fun2.c,说的简单点就是: xxx.o:xxx.c

makefile的第三个版本:

1.4makefile函数

makefile中的函数有很多,在这里给大家介绍两个最常用的。

1.wildcard – 查找指定目录下的指定类型的文件

src=$(wildcard *.c)  //找到当前目录下所有后缀为.c的文件,赋值给src
  1. patsubst – 匹配替换
obj=$(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o

在makefile中所有的函数都是有返回值的。

当前目录下有main.c fun1.c fun2.c sum.c

src=$(wildcard *.c) 等价于src=main.c fun1.c fun2.c sum.c

obj=$(patsubst %.c,%.o, $(src))等价于obj=main.o fun1.o fun2.o sum.o

makefile的第四个版本:

在makefile中所有的函数都是有返回值的。

当前目录下有main.c fun1.c fun2.c sum.c

src=$(wildcard *.c) 等价于src=main.c fun1.c fun2.c sum.c

obj=$(patsubst %.c,%.o, $(src))等价于obj=main.o fun1.o fun2.o sum.o

makefile的第四个版本:

缺点: 每次重新编译都需要手工清理中间.o文件和最终目标文件

1.5 makefile的清理操作

用途: 清除编译生成的中间.o文件和最终目标文件

make clean 如果当前目录下有同名clean文件,则不执行clean对应的命令, 解决方案:

  ▶ 伪目标声明:

  .PHONY:clean

  ■声明目标为伪目标之后, makefile将不会检查该目标是否存在或者该目标是否需要更新

  • l clean命令中的特殊符号:

  ▶ “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”

  rm -f: 强制执行, 比如若要删除的文件不存在使用-f不会报错

  ▶ “@”不显示命令本身, 只显示结果。如:“@echo clean done”

  • 其它

– make 默认执行第一个出现的目标, 可通过make dest指定要执行的目标

– make -f : -f执行一个makefile文件名称, 使用make执行指定的makefile: make -f mainmak

makefile的第5个版本:

在makefile的第5个版本中, 综合使用了变量, 函数, 模式规则和清理命令,是一个比较完善的版本。

标签:文件,依赖,变量,makefile,目标,gdb,IO,规则
From: https://www.cnblogs.com/codemagiciant/p/17646756.html

相关文章

  • 10.文件IO
    10.文件IO从本章开始学习各种Linux系统函数,这些函数的用法必须结合Linux内核的工作原理来理解,因为系统函数正是内核提供给应用程序的接口,而要理解内核的工作原理,必须熟练掌握C语言,因为内核也是用C语言写的,我们在描述内核工作原理时必然要用“指针”、“结构体”、“链表”这些名......
  • C# 通过DynamicObject让Dictionary可以通过dynamic进行操作
    测试代码DynamicDictionarydict=newDynamicDictionary();dict.Value["ID"]=1;dict.Value["Name"]="李二";dict.Value["Address"]="李家坡";dynamic......
  • GLPI资产管理系统+fusioninventory
    准备环境系统环境:centos7mariadb:10.5.18php:7.4.33apache:2.4.6#关闭selinuxsetenforce0vim/etc/selinux/config改成如图下selinux=disabled所示#关闭防火墙systemctlstopfirewalldsystemctldisablefirewalld开始安装1.安装所需工具yum-yinstallwgetvim2.更新系统补丁yum-......
  • SpringBoot复习:(40)@EnableConofigurationProperties注解的用法
    一、配置文件:server.port=9123二、配置类:packagecn.edu.tju.config;importcom.mysql.fabric.Server;importorg.springframework.boot.autoconfigure.web.ServerProperties;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.......
  • SpringBoot复习:(44)MyBatisAutoConfiguration
    可以看到MyBatisAutoConfiguration引入了MyBatisProperties这个属性:MyBatisAutoConfiguration中配置了一个SqlSessionFactoryBean,代码如下:可以配置mybatis-config.xml,需要配置文件里指定:mybatis.config-locatinotallow=classpath:/mybatis-config.xml同样可配置MyBatis的xml......
  • SpringBoot复习:(55)在service类中的方法上加上@Transactional注解后,Spring底层是怎么生
    SpringBootrun方法代码如下:可以看到它会调用refreshContext方法来刷新Spring容器,这个refreshContext方法最终会调用AbstractApplicationContext的refresh方法,代码如下如上图,refresh方法最终会调用finisheBeanFactoryInitialization方法,代码如下:从上图可以看出,它最终会调用preIn......
  • SpringBoot复习:(48)RedisAutoConfiguration自动配置类
    RedisAutoConfiguration类代码如下:可以看到在这个类中配置了2个bean:redisTemplate和stringRedisTemplate.而它通过@EnableConfigurationProperties(RedisProperties.class)注解,把配置文件中配置的Redis相关的信息引入进来了,RedisProperties代码如下:还可以看到RedisAutoConfigu......
  • SpringBoot复习:(53)TransactionInterceptor是在哪里配置的?
    我们知道SpringBoot的事务(@Transactional)最终是通过TransactionInterceptor的invoke方法调用invokeWithinTransaction方法来开启事务控制的。TransactionInterceptorbean在哪里配置的呢?在ProxyTransactionManagementConfiguration:可以看到这里创建了一个TransactionIntercept......
  • SpringBoot复习:(33)WebMvcAutoconfiguration内部静态类WebMvcAutoConfigurationAdapter
    WebMvcAutoconfiguration内部静态类WebMvcAutoConfigurationAdapter实现了WebMvcConfigurer接口,重写了一些方法,也就是默认对SpringMvc进行了一些配置:该静态类上有个**@Import**注解:@Import(EnableWebMvcConfiguration.class)它的父类DelegatingWebMvcConfiguration,通过注入......
  • kotlin协程异常处理之-CoroutineExceptionHandler
    转载请标明出处:https://www.cnblogs.com/tangZH/p/17307406.htmlkotlin协程小记协程的async使用kotlin协程异常处理之-trycatchkotlin协程异常处理之-CoroutineExceptionHandlerCoroutineExceptionHandler用于在协程中捕获异常。一、CoroutineExceptionHandler只能处......