Makefile学习

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内置的变量
常用的有:

CCc编译器,默认为cc
CPPc预处理器,默认为$(cc) -E
CXXc++编译器,默认为g++
RM删除,默认为rm -rf
ARFLAGS库选项,无默认值
ASFLAGS汇编选项,无默认值
CFLAGSc编译器选项,无默认值
CPPFLAGSc预处理器选项,无默认值
CXXFLAGSc++编译器选项值,无默认值

通过使用预定义变量对上面的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值