首页 > 其他分享 >Makefile基础入门

Makefile基础入门

时间:2023-10-21 10:12:56浏览次数:33  
标签:文件 gcc %. obj 入门 Makefile 基础 add hello

第1章 Makefile快速入门

基础概念

make :项目构建工具——用于管理文件的更新 Makefile:规则文件,告诉make如何进行编译与管理 Makefile(取名makefile也行)其实就是一个脚本文件。

快速入门

  1. 创建文本文档——文件名Makefile
  2. #代表注释
  3. 显示规则:一条显示规则由以下构成
 
1 2 目标文件:依赖文件 [Tab键]指令

示例: 1)首先我们新建一个文件夹,在该文件夹内写一个hello.cpp文件 2)我们新建一个Makefile文件。 3)在Makefile内第1个文件通常是我们的目标文件。 4)显然,在下面的文件中我们写上了4条显示规则。Makefile默认情况下会把第一条显示规则当作最终目标,也就是说,如果完成了第一条显示规则,那么Makefile是有可能不执行后面的显示规则的。可以通过ALL命令来指示最终目标:ALL hello,这样就无需将最终目标放在文件开头了。

 
1 2 3 4 5 6 7 8 9 10 11 hello:hello.o     g++ hello.o -o hello   hello.o:hello.s     g++ -c hello.s -o hello.o   hello.s:hello.i     g++ -S hello.i -o hello.s   hello.i:hello.cpp     g++ -E hello.cpp -o hello.i
  1. 伪目标 .PHONY:目标名(可以任意命名),使用伪目标指令就会执行目标后面的命令。
 
1 2 3 .PHONY: clean:     rm  -rf hello.o hello.s hello.i

示例:执行clean命令

 
1 make clean

变量的使用

变量=(替换) 变量+=(追加) 变量:=(常量) 使用变量——$(变量名)

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 TARGET=hello OBJ=hello.o   $(TARGET):$(OBJ)     g++ hello.o -o hello   hello.o:hello.s     g++ -c hello.s -o hello.o   hello.s:hello.i     g++ -S hello.i -o hello.s   hello.i:hello.cpp     g++ -E hello.cpp -o hello.i   .PHONY: clean:     -rm  -rf hello.o hello.s hello.i(rm前面加-表示执行过程中出错了也要继续往下执行)

隐含规则

%.c文件表示任意的.c文件,%.o表示任意的.o文件。

通配符(自动变量 )

 
1 2 3 $@ 表示所有的目标文件 $^ 表示所有的依赖文件 $< 所有的依赖文件的第一个文件

第2章 Makefile详解

1个基本原则

  1. 若想生成目标,检查规则中的依赖条件是否存在,若不存在,则检查是否有规则用来生成该文件。
  2. 检查规则中的目标是否需要更新,必须先检查他的所有依赖,依赖中有任意一个被更新,则目标必须被更新(目标更新时间必须晚于依赖文件的更新时间,否则就会更新目标)。

2个函数

wildcard函数

 
1 2 3 src=$(wildcard *.c) 或者 src=$(wildcard ./*.c)

src是Makefile文件的一个变量,Makefile只有一种变量类型字符串类型。 wildcard是一个函数,函数名意思是通配符。 以上函数语句的意思就是把当前目录下所有.c文件提取出来作为一个列表赋值给src。

patsubst函数

patsubst是patten substitude的缩写,匹配替代的意思。

 
1 obj=$(patsubts %.c, %.o, $(src))

将参数3中,包含参数1的部分,替换为参数2。 比如src = add.c sub.c div.c 则obj =add.o sub.o div.o

3个自动变量

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

注意:在一条规则中,$@只能用于命令行,而不能用于目标文件和依赖文件.看不懂这句话就先忽略

假设我们有Makefile文件内容如下:

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 src=$(wildcard *.c) # add.c sub.c div.c main.c obj=$(patsubts %.c, %.o, $(src)) # add.o sub.o div.o main.o   ALL:a.out   a.out:$(obj)     gcc $(obj) -o a.out   add.o:add.c     gcc -c add.c -o add.o sub.o:sub.c     gcc -c sub.c -o sub.o div.o:div.c     gcc -c div.c -o div.o main.o:main.c     gcc -c main.c -o main.o   clean:     -rm -rf $(obj) a.out

通过自动变量我们可以做出如下替换:

 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 src=$(wildcard *.c) # add.c sub.c div.c main.c obj=$(patsubts %.c, %.o, $(src)) # add.o sub.o div.o main.o   ALL:a.out   #在下面这条规则中, #目标文件是a.out,所以在命令行中$@的值就是a.out #依赖文件是$(obj)——值为add.o sub.o div.o main.o,所以在命令行中$^的值就是以上的4个文件 a.out:$(obj)       gcc $^ -o $@   #在下面的这条规则中,目标文件的值是add.o,依赖文件的值是add.c #所以$<的值就是add.c,$@的值就是add.o,这里由于只有一个依赖文件,所以$<与$^的取值是一样的,我们使用$< add.o:add.c     gcc -c $< -o $@ sub.o:sub.c     gcc -c $< -o $@ div.o:div.c     gcc -c $< -o $@ main.o:main.c     gcc -c $< -o $@   clean:     -rm -rf $(obj) a.out

现在,你知道$@为什么不能用于目标文件和依赖文件的值了吧。因为以上三个自动变量的值就取决于目标文件和依赖文件的值。

模式规则

现在,我们要求再添加进一个功能,我们要添加mul.c文件实现乘法功能。 那么,我们现在也就必须要修改我们的Makefile文件。 但是我们想要实现的最终目标是,添加进新的文件时,不用修改我们的Makefile文件,这就需要用到模式规则。 %.c文件表示任意的.c文件,%.o表示任意的.o文件。 所以,在Makefile文件中,下面的几条规则我们可以进行替换

 
1 2 3 4 5 6 7 8 add.o:add.c     gcc -c $< -o $@ sub.o:sub.c     gcc -c $< -o $@ div.o:div.c     gcc -c $< -o $@ main.o:main.c     gcc -c $< -o $@

我们只用一条规则就可以替换上面的规则了

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

请你思考,在这里为什么不能使用*.c而是必须使用%.c?为什么不能使用*.o而是必须使用%.o?也就是说,通配符*与%的区别是什么? 这样,我们添加新的mul.c文件时,通过模式规则我们就不用修改Makefile文件了。

静态模式规则

$(obj):%.o:%.c 相当于在模式规则的前面加上了个前缀,指定了(obj)应该要套用的模式规则。假设有以下场景:下面有两条模式规则都能产生.o文件,(obj)应该要套用的模式规则。 假设有以下场景:下面有两条模式规则都能产生.o文件,(obj)应该要套用的模式规则。假设有以下场景:下面有两条模式规则都能产生.o文件,(obj)应该套用哪天模式规则呢?这里就产生了歧义。需要用到静态模式规则。

 
1 2 3 4 5 6 7 8 9 10 11 12 13 src=$(wildcard *.c) # add.c sub.c div.c main.c obj=$(patsubts %.c, %.o, $(src)) # add.o sub.o div.o main.o   ALL:a.out   a.out:$(obj)     gcc $(obj) -o a.out %.o:%.c     gcc -c $< -o $@ %.o:%.s     gcc -S $< -o $@ clean:     -rm -rf $(obj) a.out

修改如下:

 
1 2 3 4 5 6 7 8 9 10 11 12 13 src=$(wildcard *.c) # add.c sub.c div.c main.c obj=$(patsubts %.c, %.o, $(src)) # add.o sub.o div.o main.o   ALL:a.out   a.out:$(obj)     gcc $(obj) -o a.out $(obj):%.o:%.c     gcc -c $< -o $@ %.o:%.s     gcc -S $< -o $@ clean:     -rm -rf $(obj) a.out
  举报    

from:https://blog.nowcoder.net/n/16b8c4e009454abda117661f9bfbc212

 

标签:文件,gcc,%.,obj,入门,Makefile,基础,add,hello
From: https://www.cnblogs.com/im18620660608/p/17778514.html

相关文章

  • 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是一......
  • java基础漏洞学习----文件操作漏洞
    java基础漏洞学习----文件操作漏洞前置基础知识https://www.cnblogs.com/thebeastofwar/p/17760812.html文件上传漏洞文件上传的方式1.通过文件流index.jsp<%@pagelanguage="java"contentType="text/html;charset=UTF-8"pageEncoding="UTF-8"%><!DOC......
  • Makefile knowledge summarization
    WildcardThewildcardinmakefileissimilarwithmacroinC/C++,itisn'tsimilarwithwildcardinlinuxshell,soitdoesn'texpendautomatically.object1=*.c//*.cobject2=$(wildcard*.cpp)//main.cppt1.cppt2.cppAutomaticallygene......
  • C++语言基础纲要
    1、C++程序的结构2、输出语句cout<<5<<"hello"<<endl;3、输入语句cin>>a;4、变量 三要素:类型变量名值 命名规则 使用原则5、常量const关键字修饰6、基本数据类型 整型 int 3588 浮点型 double双精度float单精度 字符型 char'A''8' 布尔类型 boolt......
  • 实验2 C语言分支与循环基础应用编程
    1.实验任务1task1源代码1#include<stdio.h>2#include<stdlib.h>3#include<time.h>45#defineN56#defineN13747#defineN246589intmain()10{11intnumber;12inti;1314srand(time(0));//以当前......
  • Rockchip RK3399 - DRM crtc基础知识
    一、LCD硬件原理1.1CRT介绍CRT是阴极射线管(CathodeRayTube)的缩写,它是一种使用电子束在荧光屏上创建图像的显示设备。CRT显示器在过去很长一段时间内是主流的显示技术,现已被液晶显示屏或其他新兴技术所替代。在CRT显示器中,扫描电子束从左到右、从上到下移动,照亮屏幕上的荧光......
  • springdatajpa编写入门接口
    SDJ的一个牛逼的地方就是,它可以只编写JPA规范的接口,然后可以不用写实现类,然后,只要写了这个dao层接口,就可以实现最基本的CRUD操作,然而,要怎么实现JPA规范呢 写这个所谓的JPA规范接口,就是继承JpaRepository和JpaSpecificationExecutor两个接口说说第一个JR,就是它要放一个泛型,然......
  • web基础漏洞-sql注入测试
    sql注入的自动测试,为了便于处理,将其分为两个阶段分别处理,即漏洞测试发现和漏洞利用。前者更加普遍和重要。1、自动测试流程1.1选择业务和sql语句insertdeleteupdateselectwhereid=?selectwheretitlelike'?'selectwhereusername=?andpassword=?...1.2常用......
  • web基础漏洞-sql注入
    1、介绍sql注入,是目标网站提供了接口,使得攻击者可以从前端提交数据,然后未经过严格检查,被拼接到sql语句中,交给sql应用执行。从而导致恶意构造的payload破坏原有的sql语句结构,执行超预期的功能,造成危害。几乎所有的sql应用都存在sql注入漏洞,但一般讨论和测试时以mysql为主预编译......