美文网首页
Makefile介绍和编写

Makefile介绍和编写

作者: JeremyL | 来源:发表于2022-03-16 23:14 被阅读0次

makefile是一个辅助程序编译的文件,在其中可以申明编译所需要的依赖和规则。

# 1. 为什么需要makefile文件

  • 常见的编译多个文件:
g++ -o out main.cpp example1.cpp ...

但是,在一个大的项目中,开发者常常会遇到:

## 1.1 有时候程序的依赖和链接是复杂的,需要手动处理;

## 1.2 项目会包含很多源文件,编译过程会很费时间;Makefile 支持多线程并发操作,并且可以编译特定文件(例如修改过的文件);

## 1.3 不同的源文件需要不同的编译器。

# 2. Makefile 规则

targets : prerequisites
    command
#targets: 目标文件;
#prerequisites:依赖文件;
#command:需要执行的shell命令;

  • 例子
main.o : main.cpp  
    g++ -c -I $(INCLUDE) main.cpp 

# 3. 变量

## 3.1 Makefile 有四种基本变量赋值方式

  • 简单赋值 ( := ) :只对当前语句的变量有效。

  • 递归赋值 ( = ): 所有目标变量相关的其他变量都受影响。

  • 条件赋值 ( ?= ): 如果变量未定义,则使用符号中的值定义变量。如果该变量已经赋值,则该赋值语句无效。

  • 追加赋值 ( += ) :原变量添加一个新的值,空格分割;

## 3.2 变量的引用

  • "$(variable)" 或者是 "${variable}"
OBJ=main.o test.o test1.o test2.o
main:$(OBJ)
      gcc -o main $(OBJ)

## 3.3 预定义变量

  • $*:不包含扩展名的目标文件名称。

  • $+:所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。

  • $<:第一个依赖文件的名称。

  • $?:所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。

  • $@:规则定义的目标文件。

  • $^:所有的依赖文件,空格分开,会去重。

  • 例子

main:main.o
    gcc -o $@ $^

# 4. 搜索路径

  • Makefile文件中通过VPATH 或vpath设置搜索路径。

## 4.1 VPATH 设置环境变量

VPATH := src car
或
VPATH := src:car

VPATH=src car
main:main.o
    gcc -o $@ $^

## 4.2 vpath 设置特定搜索模式和路径。

vpath *.c src car         
或
vpath *.c src : car

vpath *.c src car 
main:main.o
    gcc -o $@ $^

# 5. 条件判断

  • ifeq:是否相等,相等返回 true,不相等返回 false。

  • ifneq:是否相等,不相等返回 true,相等返回 false。

  • ifdef:是否定义过,定义过返回返回 true,没有定义过返回 false。

  • ifndef:是否定义过,没有定义过返回 true,有定义过返回 false。

# 6. 函数调用

$(<function> <arguments>)    或
${<function> <arguments>}
  • 例子
OBJ=$(patsubst %.c,%.o,1.c 2.c 3.c)
test:
    @echo $(OBJ)

# 7. makefile文件模版

# makefile template
INCLUDE = ./include
binPath=$(HOME)/bin
OBJS = main.o test1.o test2.o 

HH = ./include/test1.h ./include/teat2.h 

ifndef CXX
CXX = $(CXX) $(CXXFLAGS)
endif
CXXFLAGS=-pipe \
         -g \
         -std=c++11 

Tool : $(OBJS)
    $(CXX) $(CXXFLAGS) -o Tool $(OBJS) 
main.o : main.cpp  
    $(CXX) $(CXXFLAGS) -c -I $(INCLUDE) main.cpp    
test1.o : test1.cpp $(HH)
    $(CXX) $(CXXFLAGS) -c -I $(INCLUDE) test1.cpp
test2.o : test2.cpp $(HH)
    $(CXX) $(CXXFLAGS) -c -I $(INCLUDE) test2.cpp
.PHONY : clean
clean :
    @rm $(OBJS)
    @mv $@ ${BIN}
    @echo "Finish !"
  • 多个命令之间要使用分号隔开,Makefile 中的任何命令都要以tab键开始。

  • make执行时,查找的文件顺序是:"GNUmakefile" 、"makefile" 、"Makefile"。

  • Makefile文件中第一个编译规则目标文件一般就是整个编译的目标文件

  • Tool是整个编译的目标文件; main.o、test1.o 和 test2.o是中间文件。

  • 编译时,处理第一个规则($(CXX) $(CXXFLAGS) -o Tool $(OBJS))的时候,会根据依赖关系先生成依赖文件(main.o test1.o test2.o

  • 例子中使用了通配符(*.c)。当通配符和变量联合使用时,需要函数 "wildcard"。

OBJ=$(wildcard *.c)
test:$(OBJ)
    gcc -o $@ $^
  • 隐含规则中使用的变量:
# 命令的变量
CXX:C++编译程序
AR:函数库打包程序
AS:汇编语言编译程序
CC:C编译程序
CXX:C++编译程序
CO:从 RCS 中提取文件的程序。
CPP:C程序的预处理器
FC:Fortran 和 Ratfor 的编译器和预处理程序
GET:从SCCS文件中扩展文件的程序
LEX:Lex方法分析器程序
PC:Pascal 语言编译器
YACC:Yacc 文法分析器(针对于C程序)
YACCR:Yacc 文法分析器(针对于Ratfor程序)

# 命令参数的变量
CFLAGS: C语言编译器参数
CXXFLAGS: C++语言编译器参数

# 参考:

[GNU make

相关文章

  • Makefile介绍和编写

    makefile是一个辅助程序编译的文件,在其中可以申明编译所需要的依赖和规则。 # 1. 为什么需要makefi...

  • makefile编写,GDB调试

    1.makefile编写的三要素 在学习编写makefile文件以前,我们先来看makefile编写的三要素。 1...

  • 编写Makefile及简单分析

    makefile的好处:一次编写,终身受益 makefile的命名规则: makefile Makefile ma...

  • 二 . 树莓派A20驱动程序编写(模板程序)

    1 Makefile Makefile文件编写如下: 2 *.c文件 建立一个test.文件,编写内容如下: 3 ...

  • Makefile 编写

    1. 原生 Makefile 自己编写 Makefile 文件 2. CMakeLists.txt 文件 CMak...

  • Makefile编写

    背景 以前学的一些东西需要记录下 Makefile 编写 以自己实际项目来阐述每个的用法 目录结构15324023...

  • 编写Makefile

    最近学习了如何编写Makefile,以下是一则实例 文件结构 Makefile实例

  • Makefile 编写

    通配符 $? 所有比目标新的依赖目标的集合 $^ 所有依赖 的集合 $+ 所有依赖的目标的集合,但是不去重 $% ...

  • makefile编写

    1、若是同一个目录下的C文件比如目录下有a.c、b.c两个文件,可编写如下

  • makefile 编写

    1. Makefile 中::=,?=, +=, =的区别 = 是最基本的赋值:= 是覆盖之前的值?= 是如果没有...

网友评论

      本文标题:Makefile介绍和编写

      本文链接:https://www.haomeiwen.com/subject/eummdrtx.html