makefile(01)_初识

0. 声明

本系列(makefile)文章,从零基础开始,通过实验逐步分析makefile的语法特性,并最终打造一个可复用、可移植的专业编译环境。
参考:
1.DT 唐老师门徒计划课程
2.GNU make 手册:http://www.gnu.org/software/make/manual/make.html

1.Make与makefile

  • Make是一个应用程序:接续源程序之间的依赖关系,根据依赖关系自动维护编译工作,执行宿主操作系统中的各种命令。
  • Makefile是一个描述文件:定义了系列的规则来指定源文件编译后的先后顺序,拥有特定的语法规则,支持函数定义和函数调用,能够直接集成操作系统的各种命令,本质上也是一种脚本。
    两者的联系:
  • Makefile中的描述用于指导make程序如何完成工作;
  • make根据Makefile中的规则执行命令,最后完成编译输出;
    简单示例:
    hello: // 目标
    echo “hello makefile” // 实现目标要执行的命令,注意行首是一个table(\t)

make -f mf.txt hello // -f表示指定mf.txt文件为规则定义文件(Makefile),并执行文件里的hello目标

make // 执行默认规则定义文件(Makefile/makefile)中的默认目标(第一个目标)

2.Makefile结构

2.1.Makefile的意义:

Makefile 用于定义源文件和依赖关系,说明如何编译各个源文件并生成可执行文件
依赖的定义:

targets:prerequests; command1
Command2

2.2.Makefile中的元素含义:

targets         // 通常是需要生成的目标文件名,make所需要执行的命令名称
prerequisite        // 当前目标所依赖的其他目标或文件
command         // 完成目标所需要的命令

2.3.注意事项:

目标和依赖可以有多个,使用空格分隔
每一个命令行必须以【tab】字符开始,用于高速make程序(解析器),此行时一个命令行
续行符: \ 可以将内容分开写到下一行,提高可读性
Makefile中可以在命令前加上@符,作用为命令无回显(Makefile默认会打印执行的每一个条命令)

技巧:

开发中可以将可执行文件名和all 同时作为makefile中第一条规则的目标,这样,当执行make命令并且目标已经存在时,将不会继续执行(除非依赖文件有更新)

2.4.依赖规则:

当目标对应的文件不存在,执行对应命令
当依赖在时间上比目标更新,执行对应命令
当依赖关系发生时,对比依赖链上每一个目标

hello.out all : func.o main.o
    gcc -o hello.out func.o main.o

func.o : func.c
    gcc -o func.o -c func.c

main.o : main.c
    gcc -o main.o -c main.c

3.伪目标的引入

3.1.Makefile中的目标究竟是什么?

默认情况下,make认为目标对应着一个文件,make会比较文件和依赖关系的新旧关系,决定执行是否执行命令,make以文件处理作为第一优先级。
所以当出现和目标同名的文件时,则在文件不被更新的前提下,目标不会被执行

3.2.Makefile中的伪目标

通过PHONY关键字声明一个伪目标,伪目标不对应任何实际的文件,不管伪目标的依赖时否更新,命令总是执行。
伪目标的语法:先声明,后使用
本质:伪目标是make中特殊的目标:.PHONY的依赖

.PHONY : clean

clean :
    rm *.o hello.out -rf 

3.3.伪目标的妙用:

规则调用,模拟C语言函数的概念。
原理:当一个目标的依赖包含伪目标时,伪目标所定义的命令总是会被执行。

.PHONY : rebuild clean all

rebuild : clean all

all : hello.out

clean :
    rm *.o hello.out  -rf 

3.4.绕开.PHONY关键字定义伪目标

原理:如果一个规则没有命令或者依赖,并且他的目标不是一个存在的文件名,在执行此规则是,目标总会被认为是最新的。

clean : FORCE
    rm *.o hello.out -rf
FORCE : 

原文地址:http://blog.51cto.com/11134889/2108086

时间: 2024-10-29 10:59:52

makefile(01)_初识的相关文章

Linux系统管理_主题01 :初识Linux_1.7 关闭和重启Linux_shutdown

shutdown [选项] 时间 [警告消息] 系统关机 ? -c 取消前一个 shutdown 命令.值得注意的是,当执行一个如 "shutdown -h 11:10"的命令时,只要按"Ctrl+C"键就可以中断 关机的命令. ? -f 重新启动时不执行 fsck(注:fsck 是 Linux 下的一个检查和修复文 件系统的程序). ? -h 关闭系统所有服务后直接关机. ? -k 只是送出信息给所有用户,但并不会真正关机. ? -n 不调用 init 程序关机,

makefile(07)_路径搜索

17.Make中的路径搜索_上 17.0.实验素材 源文件位于: src目录下源文件:main.c #include <stdio.h> #include "func.h" int main() { foo(); return 0; } 源文件:func.c #include <stdio.h> #include "func.h" void foo() { printf("void foo() : %s\n", "

makefile(08)_打造专业的编译环境

20.打造专业的编译环境(上)_模块Makefile设计 20.0. 实验材料 项目架构:其中各个文件的内容请自己填写. 20.1.大型项目的目录结构(无第三方库) 20.2.项目架构设计分析 项目被划分为不同的多个模块:每个模块用一个文件夹进行管理,文件由inc, src, makefile构成每个模块的对外函数统一放置于common/inc中,如common.h xxxfunc.h 20.3.项目目标 工程项目中不希望源文件夹在编译时被改动(只读文件夹)在编译时自动创建文件夹(build)用

makefile(02)_变量

4.变量与赋值 4.1.变量 Makefile中支持程序设计语言中变量的概率,但没有变量类型,只代表文本数据:变量命名规则:变量可以包含字符.数字.下划线,单不能包含":","#", "="," ",变量名大小写敏感.变量的定义和使用: 4.2.赋值 Makefile中有4中变量赋值方式: 4.2.1.简单赋值(:=) 程序设计语言中的通用赋值方式,只针对当前语句有效,等价于C语言中的赋值.建议无特殊要求时使用简单赋值. x

makefile(03)_条件判断

8.条件判断语句 8.1.语法规则 Makefile中支持条件判断语句,可以直接比较两个不同变量的值和常量值.注意:条件判断语句只能用于控制make实际执行的语句,不能控制规则中命令的执行过程.条件判读语法说明:条件判断关键字:示例: .PHONY : test var1 := A var2 := $(var1) var3 := test: ifeq ($(var1),$(var2)) @echo "var1 == var2" else @echo "var1 != var2

makefile(04)_函数

9.函数定义及调用 Makefile中支持函数的概念,make解析器提供了一系列函数供Makefile使用.同时可以自定义函数. 9.1.自定义函数 在Makefile中支持自定义函数的实现,并调用执行,通过define关键字来实现自定义函数.函数定义的语法规则:自定义函数的本质:1.自定义函数其实是一个多行变量,无法直接调用:通过call 关键字来使用(call的作用就是将实参替换到函数体对应的位置)2.自定义函数是一种过程调用,没有任何的返回值:3.用于定义命令集合,并应用于规则中.示例:

makefile(06)_隐式规则

15.Make的隐式规则 15.1.命令覆盖 问题1:通过各目标的命令拆分写到不同的地方,会发生什么?Makefile中出现同名目标时:依赖:所有的依赖将合并到一起,成为目标的最终依赖命令:当多处出现同一目标的命令时,make发出警告,所有之前定义的命令被最后的命令取代.注意:当使用include包含其他文件(makefile)时,需要确保被包含的文件中的同名目标只有依赖,没有命令:否则,同名目标的命令将被覆盖! 15.2.隐式规则 Make中提供了一些常用的,例行的规则实现,当目标的规则未提供

makefile(09)_扩展支持

23.独立模块的支持 23.1.问题: 一般而言,不同工程师负责不同模块的开发,编译环境中如何支持模块的独立编译? 23.2.问题背景: 大型项目的代码成千上万,完整编译的时间较长, 编写模块代码时,可以通过编译检查语法错误: 为了提高开发效率,需要支持指定模块的独立编译 23.3.解决方案 将模块名(module)作为目标名(伪目标)建立规则 目标(module)对应的依赖为build build/module 规则中的命令进入对应的模块文件夹进行编译 编译结果存放于build文件夹下 23.

每天一个Linux命令(19)find命令_初识

Linux下find命令在目录结构中搜索文件,并执行指定的操作.     (1)用法: 用法: find pathname    -option      [-print | -exec | -ok]      find 路径名           选项参数    [-print | -exec | -ok]     (2)功能: 功能:用于在文件树种查找文件,并作出相应的处理.     (3)命令参数: 1) pathname: find命令所查找的目录路径.例如用.来表示当前目录,用/来表示