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

【Makefile语法 02】Makefile语法基础

目录

一、Makefile概述

二、Makefile变量

三、Makefile符号


一、Makefile格式

1. 基本格式:

targets : prerequisties
[tab键]command
  • target:目标文件,可以是 OjectFile,也可以是执行文件,还可以是一个标签(Label)。
  • prerequisite:要生成那个 target 所需要的文件或是目标。
  • command:是 make 需要执行的命令。
# 可以自定义make命令,在系统命令前加 @ 会隐藏系统命令的打印(base) [root@localhost 03_test]# vim makefile
(base) [root@localhost 03_test]# cat makefile 
debug:echo hello
(base) [root@localhost 03_test]# make debug
echo hello
hello
(base) [root@localhost 03_test]# vim makefile
(base) [root@localhost 03_test]# cat makefile 
debug:@echo hello
(base) [root@localhost 03_test]# make debug
hello
(base) [root@localhost 03_test]# vim makefile 
(base) [root@localhost 03_test]# cat makefile 
debug:@echo hellotest:@echo this is a test
(base) [root@localhost 03_test]# make test
this is a test
(base) [root@localhost 03_test]# 

2. Makefile规则:

  • make 会在当前目录下找到一个名字叫 Makefile 或 makefile 的文件
  • 如果找到,它会找文件中第一个目标文件(target),并把这个文件作为最终的目标文件
  • 如果 target 文件不存在,或是 target 文件依赖的 .o 文件(prerequities)的文件修改时间要比 target 这个文件新,就会执行后面所定义的命令 command 来生成 target 这个文件
  • 如果 target 依赖的 .o 文件(prerequisties)也存在,make 会在当前文件中找到 target 为 .o 文件的依赖性,如果找到,再根据那个规则生成 .o 文件

3. 伪目标

伪目标不是一个文件,只是一个标签。我们要显示地指明这个“目标”才能让其生效。

伪目标取名不能和文件名重名,否则不会执行命令。

为了避免 target 和 Makefile 同级目录下 文件/文件夹 重名的这种情况,我们可以使用一个特殊的标记 .PHONY 来显式地指明一个目标是 "伪目标",向 make 说明,不管是否有这个文件/文件夹,这个目标就是 "伪目标"。

.PHONY : clean

只要有这个声明,不管是否有 "clean" 文件/文件夹,要运行 "clean" 这个目标,只有"make clean" 这个命令。

二、Makefile变量

# 变量的定义,需要给初值cpp := src/main.cpp
obj := objs/main.o
# 变量的引用,用()或{}$(obj) : ${cpp}@g++ -c $(cpp) -o ${obj}compile: $(obj)
# 预定义变量$@ :目标(targe)的完整名称
$< :第一个依赖项(prerequisties)的名称
@^ :所有依赖项(prerequisties)的名称
(base) [root@localhost 04_test]# ls
makefile  objs  src
(base) [root@localhost 04_test]# ls src/
main.cpp
(base) [root@localhost 04_test]# ls objs/
(base) [root@localhost 04_test]# vim makefile 
(base) [root@localhost 04_test]# cat makefile 
cpp := src/main.cpp
obj := objs/main.o$(obj) : $(cpp)g++ -c $(cpp) -o $(obj)compile: $(obj)debug:@echo $(cpp)@echo $(obj)clean:rm -rf objs.PHONY: debug clean
(base) [root@localhost 04_test]# make compile
g++ -c src/main.cpp -o objs/main.o
(base) [root@localhost 04_test]# ls objs/
main.o
(base) [root@localhost 04_test]# make debug
src/main.cpp
objs/main.o
(base) [root@localhost 04_test]# make clean
rm -rf objs
(base) [root@localhost 04_test]# ls
makefile  src
(base) [root@localhost 04_test]# 

三、Makefile符号

# 可变赋值符 =(base) [root@localhost 05_test]# vim makefile 
(base) [root@localhost 05_test]# cat makefile 
HOST_ARCH   = aarch64
TARGET_ARCH = $(HOST_ARCH)# ...
#
# ...HOST_ARCH = amd64debug:@echo ${TARGET_ARCH}
(base) [root@localhost 05_test]# make debug
amd64
(base) [root@localhost 05_test]#
# 立即赋值符 :=(base) [root@localhost 05_test]# vim makefile 
(base) [root@localhost 05_test]# cat makefile 
HOST_ARCH   := aarch64
TARGET_ARCH := $(HOST_ARCH)# ...
#
# ...HOST_ARCH := amd64debug:@echo ${TARGET_ARCH}
(base) [root@localhost 05_test]# make debug
aarch64
(base) [root@localhost 05_test]#
# 默认赋值符 ?=
# 若该变量已定义,则不做任何操作
# 若该变量未定义,则求值并分配(base) [root@localhost 05_test]# vim makefile 
(base) [root@localhost 05_test]# cat makefile 
HOST_ARCH  = aarch64
HOST_ARCH ?= amd64
TARGET_ARCH ?= amd64debug:@echo ${HOST_ARCH}@echo ${TARGET_ARCH}
(base) [root@localhost 05_test]# make debug
aarch64
amd64
(base) [root@localhost 05_test]#
# 累加 +=(base) [root@localhost 05_test]# vim makefile 
(base) [root@localhost 05_test]# cat makefile 
include_path = /usr/include
CXXFLAGS := -m64 -fPIC -g -00 -std=c++11 -w -fopenmp
CXXFLAGS += $(include_path)debug:@echo ${CXXFLAGS} 
(base) [root@localhost 05_test]# make debug
-m64 -fPIC -g -00 -std=c++11 -w -fopenmp /usr/include
(base) [root@localhost 05_test]#
# 续行符 /(base) [root@localhost 05_test]# vim makefile 
(base) [root@localhost 05_test]# cat makefile 
LDLIBS := cudart opencv_core \gomp nvinfer protobuf cudnn pthread \cublas nvcaffe_parser nvinfer_plugin debug:@echo ${LDLIBS}
(base) [root@localhost 05_test]# make debug
cudart opencv_core gomp nvinfer protobuf cudnn pthread cublas nvcaffe_parser nvinfer_plugin
(base) [root@localhost 05_test]#
# 通配符 * %# *: 通配符表示匹配任意字符串,可以用在目录名或文件名中
# %: 通配符表示匹配任意字符串,并将匹配到的字符串作为变量使用

相关文章:

【Makefile语法 02】Makefile语法基础

目录 一、Makefile概述 二、Makefile变量 三、Makefile符号 一、Makefile格式 1. 基本格式&#xff1a; targets : prerequisties [tab键]command target&#xff1a;目标文件&#xff0c;可以是 OjectFile&#xff0c;也可以是执行文件&#xff0c;还可以是一个标签&…...

如何写一个其他人可以使用的GitHub Action

前言 在GitHub中&#xff0c;你肯定会使用GitHub Actions自动部署一个项目到GitHub Page上&#xff0c;在这个过程中总要使用workflows工作流&#xff0c;并在其中使用action&#xff0c;在这个使用的过程中&#xff0c;总会好奇怎么去写一个action呢&#xff0c;所以&#xff…...

排序算法的时间复杂度存在下界问题

对于几种常用的排序算法&#xff0c;无论是归并排序、快速排序、以及更加常见的冒泡排序等&#xff0c;这些排序算法的时间复杂度都是大于等于O(n*lg(n))的&#xff0c;而这些排序算法存在一个共同的行为&#xff0c;那就是这些算法在对元素进行排序的时候&#xff0c;都会进行…...

详解洛谷P2016 战略游戏/BZOJ0495. 树的最小点覆盖之战略游戏(贪心/树形DP)

Description Bob喜欢玩电脑游戏&#xff0c;特别是战略游戏。但是他经常无法找到快速玩过游戏的办法。现在他有个问题。 他要建立一个古城堡&#xff0c;城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵&#xff0c;使得这些士兵能了望到所有的路。 注意&…...

解决The Tomcat connector configured to listen on port 8080 failed to start

问题 启动javar报错&#xff0c;提示如下 Description: The Tomcat connector configured to listen on port 8080 failed to start. The port may already be in use or the connector may be misconfigured. Action: Verify the connector’s configuration, identify a…...

深度学习自然语言处理(NLP)模型BERT:从理论到Pytorch实战

文章目录 深度学习自然语言处理&#xff08;NLP&#xff09;模型BERT&#xff1a;从理论到Pytorch实战一、引言传统NLP技术概览规则和模式匹配基于统计的方法词嵌入和分布式表示循环神经网络&#xff08;RNN&#xff09;与长短时记忆网络&#xff08;LSTM&#xff09;Transform…...

C语言的循环结构

目录 前言 1.三种循环语句 1.while循环 2.for循环 2.1缺少表达式的情况 3.do while循环 2.break语句和continue语句 2.1在while循环中 2.2在for循环中 2.3在do while 循环中 3.循环的嵌套 4.go to语句 前言 C语⾔是结构化的程序设计语⾔&#xff0c;这⾥的结构指的是…...

C#用Array类的FindAll方法和List<T>类的Add方法按关键词在数组中检索元素并输出

目录 一、使用的方法 1. Array.FindAll(T[], Predicate) 方法 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;示例 2.List类的常用方法 &#xff08;1&#xff09;List.Add(T) 方法 &#xff08;2&#xff09;List.RemoveAt(Int32) 方法 &#xff08;3&…...

【前后端接口AES+RSA混合加解密详解(vue+SpringBoot)附完整源码】

前后端接口AES+RSA混合加解密详解(vue+SpringBoot) 前后端接口AES+RSA混合加解密一、AES加密原理和为什么不使用AES加密二、RSA加密原理和为什么不使用rsa加密三、AES和RSA混合加密的原理四、代码样例前端1. 请求增加加密标识2. 前端加密工具类3.前端axios请求统一封装,和返…...

React环境配置

1.安装Node.js Node.js官网&#xff1a;https://nodejs.org/en/ 下载之后按默认选项安装好 重启电脑即可自动完成配置 2.安装React 国内使用 npm 速度很慢&#xff0c;可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm。 ①使用 winR 输入 cmd 打开终端 ②依…...

Pandas 数据处理-排序与排名的深度探索【第69篇—python:文本数据处理】

文章目录 Pandas 数据处理-排序与排名的深度探索1. sort_index方法2. sort_values方法3. rank方法4. 多列排序5. 排名方法的参数详解6. 处理重复值7. 对索引进行排名8. 多级索引排序与排名9. 更高级的排序自定义10. 性能优化技巧10.1 使用nsmallest和nlargest10.2 使用sort_val…...

第8节、双电机多段直线运动【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;前面章节主要介绍了bresenham直线插值运动&#xff0c;本节内容介绍让两个电机完成连续的直线运动,目标是画一个正五角星 一、五角星图介绍 五角星总共10条直线&#xff0c;10个顶点。设定左下角为原点…...

Elasticsearch:基本 CRUD 操作 - Python

在我之前的文章 “Elasticsearch&#xff1a;关于在 Python 中使用 Elasticsearch 你需要知道的一切 - 8.x”&#xff0c;我详细讲述了如何建立 Elasticsearch 的客户端连接。我们也详述了如何对数据的写入及一些基本操作。在今天的文章中&#xff0c;我们针对数据的 CRUD (cre…...

1992-2022年全国及31省对外开放度测算数据(含原始数据+计算结果)(无缺失)

1992-2022年全国及31省对外开放度测算数据&#xff08;含原始数据计算结果&#xff09;&#xff08;无缺失&#xff09; 1、时间&#xff1a;1992-2022年 2、来源&#xff1a;各省年鉴、国家统计局、统计公报、 3、指标&#xff1a;进出口总额&#xff08;万美元&#xff09…...

JVM之GC垃圾回收

GC垃圾回收 如何判断对象可以回收 引用计数法 如果有对象引用计数加一&#xff0c;没有对象引用&#xff0c;计数减一&#xff0c;如果计数为零&#xff0c;则回收 但是如果存在循环引用&#xff0c;即A对象引用B对象&#xff0c;B对象引用A对象&#xff0c;会造成内存泄漏 可…...

自然语言学习nlp 六

https://www.bilibili.com/video/BV1UG411p7zv?p118 Delta Tuning&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;和机器学习领域中&#xff0c;通常指的是对预训练模型进行微调的一种策略。这种策略不是直接更新整个预训练模型的权重&#xff0c;而是仅针对模型…...

fpga 需要掌握哪些基础知识?

个人根据自己的一些心得总结一下fpga 需要掌握的基础知识&#xff0c;希望对你有帮助。 1、数电&#xff08;必须掌握的基础&#xff09;&#xff0c;然后进阶学模电&#xff0c; 2、掌握HDL&#xff08;verilog或VHDL&#xff09;一般建议先学verilog&#xff0c;然后可以学…...

Qt未来市场洞察

跨平台开发&#xff1a;Qt作为一种跨平台的开发框架&#xff0c;具有良好的适应性和灵活性&#xff0c;未来将继续受到广泛应用。随着多设备和多平台应用的增加&#xff0c;Qt的前景在跨平台开发领域将更加广阔。 物联网应用&#xff1a;由于Qt对嵌入式系统和物联网应用的良好支…...

GPT-4模型中的token和Tokenization概念介绍

Token从字面意思上看是游戏代币&#xff0c;用在深度学习中的自然语言处理领域中时&#xff0c;代表着输入文字序列的“代币化”。那么海量语料中的文字序列&#xff0c;就可以转化为海量的代币&#xff0c;用来训练我们的模型。这样我们就能够理解“用于GPT-4训练的token数量大…...

宽字节注入漏洞原理以及修复方法

漏洞名称:宽字节注入 漏洞描述: 宽字节注入是相对于单字节注入而言的&#xff0c;该注入跟HTML页面编码无关&#xff0c;宽字节注入常见于mysql中&#xff0c;GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节&#xff0c;实际上只有两字节。宽字节带来的安全问…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

高防服务器能够抵御哪些网络攻击呢?

高防服务器作为一种有着高度防御能力的服务器&#xff0c;可以帮助网站应对分布式拒绝服务攻击&#xff0c;有效识别和清理一些恶意的网络流量&#xff0c;为用户提供安全且稳定的网络环境&#xff0c;那么&#xff0c;高防服务器一般都可以抵御哪些网络攻击呢&#xff1f;下面…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...