【转】GNU makefile命令行参数

GNU makefile

所有的makefile工具中,我最喜欢用的是GNU make。
GNU make 比之 微软的nmake, 正如unix shell V/S windows cmd,
前者总要比后者功能丰富且强大的多。

我初次接触GNU make是大二暑假的一个linux 下的软件项目,当时因为使用glide开发,代码框架是由其直接生成的,包括makefile, 所以不需要我去手动修改,也因此只是略知皮毛。真正开始细心研究是在工作之后研究ARM和LEON处理器的项目当中。这其中基本把GNU make的各种功能用了个遍,有了不少的心得体会,今日整理了一番,觉得很有必要把其中的一些体会纪录下来,以备今后查询。

GNU make的最新版本是3.80,说新也不是太新了,2002发布之后就再也没有更新过,足见该版本还是相当稳定的。
我的参考资料来源是随其发布的用户手册。

1. 命令行参数

-B
-always-make 将所有文件都看成需要update,彻底地重新make所有文件
-t
与-B相反, 将所有文件都设为update-to-date,不做任何make动作
-q
不执行任何make动作,只检查目标是否update-to-date, 需要更新则返回1,不需则返回0
-C <dir>
指定在<dir>目录下运行make, 搭配 $(MAKE) -C <subdir> 可用于recursive make.

2. 内部变量

  1. ) : MAKECMDGOALS : 用户指定的target名,默认为第一个target。
  2. ) : CURDIR : 运行MAKE的当前目录
  3. ) : MAKELEVEL : recursive make时的级别,顶层为0,可用来判断出是直接调用方式还是recursive调用方式,以进行不同的行为
  4. ) : MAKEFILE_LIST: 所有的makefile, 按include顺序排列,原makefile排首位。
  5. ) : VPATH : Prerequisites搜索路径,也可用”vpath %.c src”分别指定。
  6. ) : SHELL : 指定命令使用的SHELL?(对其效果尚有疑问)

3. 特殊变量

$@
target
$^
prerequisites (no duplicate)
$+
prerequisites (allow duplicate)
  1. ) 以上变量可以扩展为目录或文件名形式,例如:$(@D)代表$@的目录部分, $(@F)代表$@的文件名部分
  2. ) 变量均可用export导出到子进程空间中,类似环境变量。故可由此修改子进程的环境如PATH等。unexport可以取消某个变量的导出。
  3. ) 变量可以针对某个target局部定义,例如 <target>:n=3;echo ${n}
  4. ) 变量定义的形式:
=
动态定义,变量使用时估值,
:=
静态定义,makefile解析到该句时立即估值,
?=
定义前先判断是否已定义过,没有则设置默认值,类似#ifndef <VAR> #define <VAR> #endif

4. 规则书写

1) .PHONY <target>
指定 <target>为无须prerequisites的强制target

2) pattern:
Prerequisites多为固定的静态值,若要根据target动态修改prereq,可使用static pattern。

Static pattern rule :
[<target>:]%.o:%.c 其中<target>限制了pattern应用的范围。若省略则针对所有可能的文件,即为implicit pattern rule。
此时在命令中可使用$*获取%部分。

3) archive
tar : lib.tar(${files})

会执行 $AR $ARFLAGS ${files} 将指定文件进行打包

5. 命令书写

  1. ) 可用空文件标记时间,sh可用touch, cmd可用echo.>tag(echo.输出空行0D0A)
  2. ) define … endef 可定义命令序列,类似#define,但实际是用变量实现。
  3. ) @前缀关闭回显,-前缀忽略错误。
  4. ) 用cmd /c ${cmds} 或sh ${cmds}可强制指定时候用的SHELL(使用SHELL变量未必管用?)

6. 函数

$(SHELL ${cmd})
得到${cmd}命令的输出
$(words ${list})
list中word个数
$(patsubst )
按样式替换
$(warning $msg)
在命令行中输出$msg
$(wildcard ${dir}/*.c)
获得符合样式的所有文件或目录
$(if $cond, $var1, $var2)
可根据条件选择,类似于?:操作符

7. 宏

ifdef
ifeq
include
类似C中的用法

原文地址:https://www.cnblogs.com/seaney/p/2526370.html