前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Makefile文件编写

Makefile文件编写

作者头像
用户2929716
发布2018-08-23 13:26:03
1.2K0
发布2018-08-23 13:26:03
举报
文章被收录于专栏:流媒体流媒体

语法

代码语言:javascript
复制
target ... : prerequisites ...
    command
    ...
    ...
  • target可以是一个object file(目标文件),也可以是一个执行文件,还可以是一个标签(label)。对于标签这种特性,在后续的“伪目标”章节中会有叙述。
  • prerequisites就是,要生成那个target所需要的文件或是目标。
  • command也就是make需要执行的命令。(任意的shell命令)

make工作

  • 默认执行 make 命令时, GNU make在当前目录下依次搜索下面3个文件 "GNUmakefile", "makefile", "Makefile",
  • 如果找到,它会找文件中的第一个目标文件(target),并把这个文件作为最终的目标文件。
  • 如果target文件不存在,或是target所依赖的后面的 .o 文件的文件修改时间要比target这个文件新,那么,他就会执行后面所定义的命令来生成target这个文件。
  • 如果target所依赖的文件也不存在,那么make会在当前文件中找依赖文件,如果找到则再根据那一个规则生成依赖文件。(这有点像一个堆栈的过程)
  • 最终生成target文件

make 参数介绍

make 的参数有很多, 可以通过 make -h 去查看, 下面只介绍几个我认为比较有用的。

参数

含义

--debug[=<options>]

输出make的调试信息, options 可以是 a, b, v

-j --jobs

同时运行的命令的个数, 也就是多线程执行 Makefile

-r --no-builtin-rules

禁止使用任何隐含规则

-R --no-builtin-variabes

禁止使用任何作用于变量上的隐含规则

-B --always-make

假设所有目标都有更新, 即强制重编译

注意

  • 所有的命令前要用tab分割

变量

定义变量(= or := )
  • := 只能使用前面定义好的变量
  • = 可以使用后面定义的变量
代码语言:javascript
复制
OBJS = programA.o programB.o
OBJS-ADD = $(OBJS) programC.o
# 或者
OBJS := programA.o programB.o
OBJS-ADD := $(OBJS) programC.o
使用变量 $()
变量追加值 +=
代码语言:javascript
复制
SRCS := programA.c programB.c programC.c
SRCS += programD.c
变量覆盖 override
目标变量

作用是使变量的作用域仅限于这个目标(target), 而不像之前例子中定义的变量, 对整个Makefile都有效.

语法:

  • <target ...> :: <variable-assignment>
  • <target ...> :: override <variable-assignment> (override作用参见 变量覆盖的介绍)
代码语言:javascript
复制
# Makefile 内容
SRCS := programA.c programB.c programC.c

target1: TARGET1-SRCS := programD.c
target1:
    @echo "SRCS: " $(SRCS)
    @echo "SRCS: " $(TARGET1-SRCS)

target2:
    @echo "SRCS: " $(SRCS)
    @echo "SRCS: " $(TARGET1-SRCS)

# bash中执行make
$ make target1
SRCS:  programA.c programB.c programC.c
SRCS:  programD.c

$ make target2     <-- target2中显示不了 $(TARGET1-SRCS)
SRCS:  programA.c programB.c programC.c
SRCS:

Makefile 命令前缀(@ or -)

Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不用前缀.

  • 不用前缀 。输出执行的命令以及命令执行的结果, 出错的话停止执行
  • 前缀 @ 只输出命令执行的结果, 出错的话停止执行
  • 前缀 - 命令执行有错的话, 忽略错误, 继续执行

伪目标

伪目标并不是一个"目标(target)", 不像真正的目标那样会生成一个目标文件.

典型的伪目标是 Makefile 中用来清理编译过程中中间文件的 clean 伪目标, 一般格式如下:

代码语言:javascript
复制
.PHONY: clean   <-- 这句没有也行, 但是最好加上
clean:
    -rm -f *.o      

引用其他的 Makefile

语法: include <filename> (filename 可以包含通配符和路径)

代码语言:javascript
复制
# Makefile 内容
all:
    @echo "主 Makefile begin"
    @make other-all
    @echo "主 Makefile end"

include ./other/Makefile

# ./other/Makefile 内容
other-all:
    @echo "other makefile begin"
    @echo "other makefile end"

# bash中执行 make
$ ll
total 20K
-rw-r--r-- 1 wangyubin wangyubin  125 Sep 23 16:13 Makefile
-rw-r--r-- 1 wangyubin wangyubin  11K Sep 23 16:15 makefile.org   <-- 这个文件不用管
drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 23 16:11 other
$ ll other/
total 4.0K
-rw-r--r-- 1 wangyubin wangyubin 71 Sep 23 16:11 Makefile

$ make
主 Makefile begin
make[1]: Entering directory `/path/to/test/makefile'
other makefile begin
other makefile end
make[1]: Leaving directory `/path/to/test/makefile'
主 Makefile end

Makefile 隐含规则

这里只列一个和编译C相关的.

编译C时,<n>.o 的目标会自动推导为 <n>.c

代码语言:javascript
复制
# Makefile 中
main : main.o
    gcc -o main main.o

#会自动变为:
main : main.o
    gcc -o main main.o

main.o: main.c    <-- main.o 这个目标是隐含生成的
    gcc -c main.c

自动变量

自动变量

含义

$@

目标集合

$%

当目标是函数库文件时, 表示其中的目标文件名

$<

第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标

$?

比目标新的依赖目标的集合

$^

所有依赖目标的集合, 会去除重复的依赖目标

$+

所有依赖目标的集合, 不会去除重复的依赖目标

$*

这个是GNU make特有的, 其它的make不一定支持

all

一种简写,可以让多个目标操作顺次执行

代码语言:javascript
复制
all: server.out client.out
objects = server.cpp
server.out : $(objects)
    g++ -o server.out $(objects)

client.out : client.cpp
    g++ -o client.out client.cpp

直接 make 或 make all 的话会执行 server.out 和client.out 的编译命令,后面不加参数的话,会把第一个目标作为默认的。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.09.19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 语法
  • make工作
  • make 参数介绍
  • 注意
  • 变量
    • 定义变量(= or := )
      • 使用变量 $()
        • 变量追加值 +=
          • 变量覆盖 override
            • 目标变量
            • Makefile 命令前缀(@ or -)
            • 伪目标
            • 引用其他的 Makefile
            • Makefile 隐含规则
            • 自动变量
              • all
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档