一、好处

自动化编译,一条make命令,整个工程可以完全自动编译,make命令是构建大型项目的首选方案。

makefile就像一个shell脚本一样,用来定义规则,一个名称包含一条或多条命令,在终端make 规则,即可执行某项规则定义的命令。

二、问题记录

1、mac系统明明没有安装make命令,为什么可以直接使用?

电脑系统没有安装GNU Make, 但是可以在mac终端使用make,但是为什么没有安装git,就不能直接使用git?

shell是命令解析器,又是一种程序设计语言,它类似于DOS下的command.com和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。shell是linux,unix系统的外壳,也可以理解为命令行,就是你输入命令的地方。
bash是大多数Linux系统以及Mac OS X默认的shell,温习一下linux系统
git是版本控制工具,通过命令行和图形界面两种方式使用shell。

2、直接在终端输入make,会怎么样?

如果Make命令运行时没有指定目标,默认会执行Makefile文件的第一个目标。

3、如何让两行代码在一个进程执行?
要么将两行命令写在一行,中间用分号分隔,这样就可以共享变量;
要么在每行换行前,加反斜杠\,转义。

4、格式不对,不是tab。

makefile:: *** missing separator.  Stop.

把代码重新tab下。

5、检查语法是否有问题

t1 is up to date

make t1,显示上述问题,说明t1已经存在,最新。排除法,查看和解决。

三、参考学习

https://www.gnu.org/software/make/manual/make.html

https://www.w3cschool.cn/mexvtg/sriygozt.html

http://www.ruanyifeng.com/blog/2015/02/make.html

http://www.ruanyifeng.com/blog/2015/03/build-website-with-make.html

linux其他命令:https://www.cnblogs.com/camille666/p/linux.html

四、格式

1、定义一个规则

目标:前置条件
TAB  命令

目标可以是文件名,也可以是某个操作名,称为伪目标。

如果当前目录中,正好有一个文件和某个目标名一样,那么这个命令不会执行。因为Make发现文件已经存在,就认为没有必要重新构建了,就不会执行指定的命令。
为了避免这种情况,可以明确声明clean是"伪目标",加上temp。

目标:前置条件
TAB 命令 temp

命令表示如何更新目标文件,由一行或多行shell命令组成,每行命令之前必须有一个tab键。

五、语法

1、定义变量

用等号给变量赋值,用$()引用变量。

entryPath="./bin/server"
start: node $(entryPath)
2、调用shell变量
#比如命令,两个$$@echo  $$branch
3、打印说明语句
用echo关键字定义。
echo "这是一句话"
4、【-】在规则前:代表即便该条命令出错,也往下执行。
5、【@】在规则前:代表不在终端中输入该命令。
6、注释
用#定义。
# 定义服务器启动文件路径

7、回声

make会打印每条命令,然后执行,这叫做回声。如果在命令前加@,可以关闭回声。

  • 一个进程一条命令

7.1 执行make printRedBg,终端没有任何输出。

# 定义红色背景
RED_BG=`echo "\033[41m"`

printRedBg:
    @ # echo "$(RED_BG) Background in red"    

7.2 执行make printRedBg,终端输出# echo "`echo "\033[41m"` Background in red"

# 定义红色背景
RED_BG=`echo "\033[41m"`

printRedBg:
    # echo "$(RED_BG) Background in red"    

7.3 执行make printRedBg,终端输出红色背景的Background in red【正确】

# 定义红色背景
RED_BG=`echo "\033[41m"`

printRedBg:
    @ echo "$(RED_BG) Background in red"    

7.4 执行make printRedBg,终端第一行输出echo "`echo "\033[41m"` Background in red",第二行输出红色背景的Background in red

# 定义红色背景
RED_BG=`echo "\033[41m"`

printRedBg:
    echo "$(RED_BG) Background in red"   
  • 一个进程多条命令

7.5 执行 make t1,终端不会打印下列命令,只会执行。【正确】

可以看到,在一条进程里面,export进程开头有一个@,就可以关闭回声,不必在内部命令比如echo前写@,如果写了,也会报错。因为每行用&&\做了连接,说明它们共享同一个进程。

t%:
    @ export branch=`git branch | grep \* | grep -Eo ' .+'` && \
            echo "当前分支: $$branch" && \
            git checkout t$* && \
            git pull --rebase && \
            echo "merging: \033[0;31morigin/develop\033[0m" && \
            git merge origin/develop && \
            echo "merging: \033[0;31m$$branch\033[0m" && \
            git merge $$branch && \
            git push && \
            git checkout $$branch;
     @ echo "\n 自动发布中,查看进度:https://gitlab.pinganfang.com/f2e/webApp/pipelines";

7.6 执行 make t1,终端会打印下列所有命令,然后会执行。其实没必要让开发者看到命令行是什么。

t%:
    @ export branch=`git branch | grep \* | grep -Eo ' .+'` && \
            echo "当前分支: $$branch" && \
            git checkout t$* && \
            git pull --rebase && \
            echo "merging: \033[0;31morigin/develop\033[0m" && \
            git merge origin/develop && \
            echo "merging: \033[0;31m$$branch\033[0m" && \
            git merge $$branch && \
            git push && \
            git checkout $$branch;
     @ echo "\n 自动发布中,查看进度:https://gitlab.pinganfang.com/f2e/webApp/pipelines";

8、函数

# 定义一个函数,取第1个参数$(1),实际值比如t1,t2
define mytest
    - git branch -D $();
    git fetch;
    @ export branch=`git branch | grep \* | grep -Eo ' .+'` && \
            echo "当前分支: $$branch" && \
            git checkout t$* && \
            git pull --rebase && \
            echo "merging: \033[0;31morigin/develop\033[0m" && \
            git merge origin/develop && \
            echo "merging: \033[0;31m$$branch\033[0m" && \
            git merge $$branch && \
            git push && \
            git checkout $$branch;
    @ echo "\n 自动发布中,查看进度:https://gitlab.pinganfang.com/f2e/webApp/pipelines";
endef

# 定义规则,调用函数
t%:
    $(call mytest, t$*)

# 执行规则,在终端输入
make t1

t1的1和t%匹配成功,$*就等值于1,传给mytest参数值为t1。

9、目标只是一个%的时候,它会匹配任何一个文件名,称作match-anything规则。

六、使用

在根目录新建一个makefile文件,里面按照语法定义一些规则,然后make 规则。

七、从命令行给makefile传值

1、传数字

# 定义规则,打印来自命令行的传值
val%:
    @ echo $*

# 执行规则,在终端输入make val1
会看到结果为1

val1的1和val%匹配成功,$*就等值于1。

# 定义规则,打印来自命令行的传值
val%:
    @ echo $@

# 执行规则,在终端输入make val1
会看到结果为val1

val1的1和val%匹配成功,$@就等值于val1。

2、传字符串

# 定义规则,打印来自命令行的传值
testArgs:
    @echo '当前分支:'$(CURRENT_BRANCH)' 构建分支:'$(TARGET_BRANCH)

# 执行规则,在终端输入make testArgs CURRENT_BRANCH=master TARGET_BRANCH=master
会看到结果为【前分支:master 构建分支:master】

makefile那些事儿的更多相关文章

  1. 说说Makefile那些事儿

    说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...

  2. 关于makefile的那些事儿

    最近越来越感觉到,在linux下面身为一个程序员,不会makefile就不是一个合格的程序员,所以今天我们介绍下常用的makefile编写. 了解知识: 编译:把高级语言书写的代码转换为机器可识别的机 ...

  3. Linux就这个范儿 第8章 我是Makefile

    Linux就这个范儿 第8章 我是Makefile P287 Makefile的作用就是——自动化编译,一旦写好,只需要一个make命令(解析Makefile,执行Makefile中描述的操作),整个 ...

  4. 如何自己编译apue.3e中代码 & 学习写makefile

    本来是搜pthread的相关资料,看blog发现很多linux程序员都看的一本神书<APUE>,里面有系统的两章内容专门讲pthread(不过是用c语言做的代码示例,这个不碍事,还是归到原 ...

  5. [apue] linux 文件系统那些事儿

    前言 说到 linux 的文件系统,好多人第一印象是 ext2/ext3/ext4 等具体的文件系统,本文不涉及这些,因为研究具体的文件系统难免会陷入细节,甚至拉大段的源码做分析,反而不能从宏观的角度 ...

  6. 彻底掌握Makefile(一)

    彻底掌握Makefile(一) 介绍 makefile就是一个可以被make命令解析的文件,他定义了一系列编译的规则,帮助我们更加方便.简洁的去完成编译的过程.在一个大工程当中我们会有各种各样的文件, ...

  7. 总结iOS开发中的断点续传那些事儿

    前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...

  8. 编写一个通用的Makefile文件

    1.1在这之前,我们需要了解程序的编译过程 a.预处理:检查语法错误,展开宏,包含头文件等 b.编译:*.c-->*.S c.汇编:*.S-->*.o d.链接:.o +库文件=*.exe ...

  9. 编写简单的Makefile文件

    makefile中的编写内容如下: www:hello.c x.h gcc hello.c -o hello clean: rm hello www:hello.c  x.h 表示生成www这个文件需 ...

随机推荐

  1. 使用icepdf将pdf文件转换成照片(以及隐藏的一个bug)

    首先引入依赖: <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox ...

  2. javascript学习3、数据类型、数据类型转换、运算符

    数据类型包括:基本数据类型和引用数据类型 基本数据类型指的是简单的数据段,引用数据类型指的是有多个值构成的对象. 当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值 ...

  3. jmeter,badboy,jar包文件 常数吞吐量计时器?

    badboy录制脚本 1.按f2 红色开始录制 URL输入:https://www.so.com/ 2.搜索框输入zxw 回车键搜索 3.选中关键字(刮例如zxw软件——>tools——> ...

  4. 关于python Tk中实时的输出.

    源码如下: import time from Tkinter import * def run(): while True: txt.insert(END,'...') print '...' tim ...

  5. 指针*和取地址&函数输入使用

    函数输入问题: 1 带&和不带& (参数本身还是拷贝一份参数) 2 函数输入指针 #include <iostream> using namespace std; int ...

  6. 在阿里云CentOS服务器上安装Python3.7并设置为默认Python

    1.引言 Linux操作系统自带一个python2.7,没有python3,在开发的时候非常不便,因此需要安装一个python3,并且将python3设置系统默认python,同时还不能影响那些Lin ...

  7. UmiJS可插拔的企业级 react 应用框架,配合ant-design-pro使用

    入门非常简单 # 安装 $ yarn global add umi # 或者 npm install -g umi # 新建应用 $ mkdir myapp && cd myapp # ...

  8. SpringCloud:搭建基于Gateway的微服务网关(一)

    1.需求 最近在尝试着写一个开放平台,于是先搭建网关. 作用:统一的请求入口,完成对请求的跟踪,限流(未做),鉴权,分发,封装响应 2.工作原理 2.1.请求 在开放平台中申请对接口的使用,申请通过后 ...

  9. “未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0”提供程序

    一.背景: 开发一个工具的小项目,因为数据少,我就不想安装sqlserver数据库,就用Access数据库. 二.问题: 在客户安装程序的时候,接口访问Access数据库的时候,报错“未在本地计算机上 ...

  10. 二叉树 排序二叉树-可以通过中序遍历得到排序的数据 二叉排序树时间复杂度O(logn),

    二叉树是一种非常重要的数据结构,它同时具有数组和链表各自的特点:它可以像数组一样快速查找,也可以像链表一样快速添加.但是他也有自己的缺点:删除操作复杂. 虽然二叉排序树的最坏效率是O(n),但它支持动 ...