一、好处

自动化编译,一条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. python爬虫中遇到的问题以及解决方法

    (1)运行后报错:“TypeError: cannot use a string pattern on a bytes-like” 原因:content用decode(‘utf-8’)进行解码,由by ...

  2. laravel 配置路由 api和web定义的路由的区别详解

    1.路由经过中间件方面不同 打开kerenl.php就可以看到区别 protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware ...

  3. Error handling in Swift does not involve stack unwinding. What does it mean?

    Stack unwinding is just the process of navigating up the stack looking for the handler. Wikipedia su ...

  4. 排序算法-堆排序(Java)

    package com.rao.linkList; import java.util.Arrays; /** * @author Srao * @className HeapSort * @date ...

  5. MongoDB db.stats()&&db.db.serverStatus()

    db.stats()   示例图 参数解释: "db" : "test" ,表示当前是针对"test"这个数据库的描述.想要查看其他数据库, ...

  6. 洛谷p1967货车运输(kruskal重构树)

    题面 题解中有很多说最优解是kruskal重构树 所以 抽了个早自习看了看这方面的内容 我看的博客 感觉真的挺好使的 首先对于kruskal算法来说 是基于贪心的思想把边权排序用并查集维护是否是在同一 ...

  7. bzoj4868 期末考试 题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4868 显然我们只关注最后出分的学科. 刚开始想的是dp,然而不知道如何记录状态. 突然就想到了正解 ...

  8. mysql(四)缓存

    参考文档: http://www.cnblogs.com/zemliu/archive/2013/08/03/3234372.html

  9. NIOBuffer 缓冲区

    Java NIO 由以下几个核心部分组成: Channels Buffers Selectors 虽然Java NIO 中除此之外还有很多类和组件,但是,Channel,Buffer 和 Select ...

  10. python测试mysql数据库性能(二)

    一,普通写入数据库 二,批量写入数据库 三,普通写入数据库添加事务 config = { 'host': 'localhost', 'port': 3306, 'database': 'test', ...