Makefile初探
例1:
main.cpp
#include "add.h"
#include <iostream>
int main()
{
std::cout << add(3, 4) << std::endl;
}
add.cpp
int add(int x, int y) { return x + y; }
Makefile
main:main.o add.o
g++ -o main main.o add.o
main.o:main.cpp
g++ -c main.cpp
add.o:add.cpp
g++ -c add.cpp
上面是一个简单的Makefile例子,执行make即会自动编译生成main可执行程序,当修改某一个文件比如只修改add.cpp,则
Makefile的变量
Makefile中的变量分为用户自定义变量、自动变量、预定义变量、环境变量
自定义变量
定义方式:
1 变量名:=变量值 普通变量展开 - 常用
2 变量名=变量值 递归变量展开 - 不常用
例1中的Makefile可以改进为
ELF:=main
OBJECTS:=main.o add.o
$(ELF):$(OBJECTS)
g++ -o main main.o add.o
main.o:main.cpp
g++ -c main.cpp
add.o:add.cpp
g++ -c add.cpp
自动变量
在使用的时候,自动用特定的值替换
常用的有:
$@ | 当前规则的目标文件 |
$^ | 当前规则的所有依赖文件,空格隔开,不重复 |
$(@D) | 目标文件的目录名部分 |
$(@F) | 目标文件的文件名部分 |
$+ | 当前规则的所有的依赖文件,空格隔开,可以重复 |
$< | 当前规则的第一个依赖文件的名称 |
通过使用自动变量对上面的Makefile再次改进
ELF:=main
OBJECTS:=main.o add.o
$(ELF):$(OBJECTS)
g++ -o $@ $^
main.o:main.cpp
g++ -c $^
add.o:add.cpp
g++ -c $^
预定义变量
Makefile内置的变量
常用的有:
CC | c编译器,默认为cc |
CPP | c预处理器,默认为$(cc) -E |
CXX | c++编译器,默认为g++ |
RM | 删除,默认为rm -rf |
ARFLAGS | 库选项,无默认值 |
ASFLAGS | 汇编选项,无默认值 |
CFLAGS | c编译器选项,无默认值 |
CPPFLAGS | c预处理器选项,无默认值 |
CXXFLAGS | c++编译器选项值,无默认值 |
通过使用预定义变量对上面的Makefile再次改进
ELF:=main
OBJECTS:=main.o add.o
CXXFLAGS:=-w -g -std=c++11
CXX:=g++
$(ELF):$(OBJECTS)
$(CXX) -o $@ $^
main.o:main.cpp
$(CXX) -c $^
add.o:add.cpp
$(CXX) -c $^
环境变量
export + 变量名
Makefile隐含规则
makefile中*.o文件会自动依赖 .c或.cc文件,所以上面例子中最后四步可以省略,即优化后为
ELF:=main
OBJECTS:=main.o add.o
CXXFLAGS:=-w -g -std=c++11
CXX:=g++
$(ELF):$(OBJECTS)
$(CXX) -o $@ $^
Makefile常用函数
1、wildcard 在Makefile规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数wildcard。
2、$(patsubst 要查找的子串,替换后的目标子串,源字符串)
更多函数见:https://blog.youkuaiyun.com/qq_31860135/article/details/84253289
进一步优化后为
ALL_CPP:=$(wildcard *cpp)
OBJECTS:=$(patsubst %.cpp,%.o,$(ALL_CPP))
ELF:=main
CXXFLAGS:=-w -g -std=c++11
CXX:=g++
$(ELF):$(OBJECTS)
$(CXX) -o $@ $^
Makefile伪目标
如果当前目录下存在文件名为 clean 的文件时,在 shell 中执行命令 make clean,由于这个规则没有依赖文件,所以目标被认为是最新的而不去执行规则所定义的命令。因此命令 rm 将不会被执行。为了解决这个问题,删除 clean 文件或者是在 Makefile 中将目标 clean 声明为伪目标。
ALL_CPP:=$(wildcard *cpp)
OBJECTS:=$(patsubst %.cpp,%.o,$(ALL_CPP))
ELF:=main
CXXFLAGS:=-w -g -std=c++11
CXX:=g++
$(ELF):$(OBJECTS)
$(CXX) -o $@ $^
.PHONY:clean
clean:
RM $(OBJECTS) $(ELF)
参考资料:http://c.biancheng.net/view/7097.html