您的位置:首页 > 其它

Makefile 编写实例

2016-06-12 20:35 393 查看
近几天因工作需要编写Makefile,于是在网上搜索相关资料学写Makefile 时间比较仓促 但总还算达到了软件代码自动化编译的目的,参考主要资料来源于网上一位大神《跟我学写Makefile》博客,现主要记录自己在编写过程体会及注意要点:

对Makefile 理解:始于起点也终于起点,即从目标文件、依赖文件、依赖规则这里开始,也在这儿结束。整个Makefile围绕目标文件:依赖文件展开的,进行一系列变量替换与推导,直到所有显式内容全都替换出来 先编译生成所需要的*.o中间文件,最后将所需的*.o文件链接起来生成最终可执行的目标文件。

在编写Makefile过程用到的函数:

addprefix 增加前缀函数 主要用在搜索.h文件路径

addsuffix 增加后缀函数 主要用于将源文件集合到一块与wildcard函数搭配使用

widcard 通配符扩展函数

patsubst 通配符替换 主要用于源文件到中间目标文件替换

notdir 去路径

vpath 制定查找路径 用于.c、.cpp .o 等路径搜索查找

下面给出我的简单Makefile代码:

TARGET_NAME = test

DIR_ALL := .

DIR_ALL += ./main

DIR_ALL += ./namespace

DIR_ALL += ./type

DIR_C := $(DIR_ALL)

DIR_CPP := $(DIR_ALL)

DIR_BIN := ./release

DIR_OBJ := $(DIR_BIN)/obj

DIR_DEP := $(DIR_BIN)/dep

TARGET = $(DIR_BIN)/$(TARGET_NAME)

INC_ALL := $(DIR_ALL)

CC = gcc

CPP = g++

INCFLAGS = $(addprefix -I,$(INC_ALL))

CFLAGS = -Wall $(INCFLAGS) -g -std=gnu99

CPPFLAGS = -Wall $(INCFLAGS) -g

LDFLAGS = -lpthread -lrt

SOURCES_C := $(wildcard $(addsuffix /*.c, $(DIR_C)))

SOURCES_CPP := $(wildcard $(addsuffix /*.cpp, $(DIR_CPP)))

OBJS := $(patsubst %.c,%.o,$(notdir $(SOURCES_C))) $(patsubst %.cpp,%.o,$(notdir $(SOURCES_CPP)))

DEPS := $(patsubst %.cpp,%.d,$(notdir $(SOURCES_CPP))) $(patsubst %.c,%.d,$(notdir $(SOURCES_C)))

VPATH_H := $(subst .,:.,$(INC_ALL))

VPATH_C := $(subst .,:.,$(DIR_C))

VPATH_CPP := $(subst .,:.,$(DIR_CPP))

vpath %.h $(VPATH_H)

vpath %.c $(VPATH_C)

vpath %.cpp $(VPATH_CPP)

vpath %.o $(DIR_OBJ)

vpath %.d $(DIR_DEP)

all:$(TARGET)

$(TARGET):$(OBJS)

$(CPP) $(addprefix $(DIR_OBJ)/, $(OBJS)) -o $@ $(LDFLAGS)

%.o:%.c %.d

$(CC) $(CFLAGS) -c $< -o $(DIR_OBJ)/$@

%.o:%.cpp %.d

$(CPP) $(CPPFLAGS) -c $< -o $(DIR_OBJ)/$@

%.d:%.c

@set -e

rm -rf $(DIR_DEP)/*.d

$(CC) $< $(INCFLAGS) -MM -o $(DIR_DEP)/$@

%.d:%.cpp

@set -e

$(CPP) $< $(INCFLAGS) -MM -o $(DIR_DEP)/$@

-include $(addprefix $(DIR_DEP)/,$(DEPS))

.PHONY:clean

clean:

rm -rf $(DIR_OBJ)/*.o

rm -rf $(DIR_DEP)/*.d

rm -rf $(TARGET)

执行make命令后信息如下:

g++ change.cpp -I. -I./main -I./namespace -I./type -MM -o ./release/dep/change.d

g++ -Wall -I. -I./main -I./namespace -I./type -g -c change.cpp -o ./release/obj/change.o

g++ ./main/main.cpp -I. -I./main -I./namespace -I./type -MM -o ./release/dep/main.d

g++ -Wall -I. -I./main -I./namespace -I./type -g -c ./main/main.cpp -o ./release/obj/main.o

g++ ./namespace/namespace.cpp -I. -I./main -I./namespace -I./type -MM -o ./release/dep/namespace.d

g++ -Wall -I. -I./main -I./namespace -I./type -g -c ./namespace/namespace.cpp -o ./release/obj/namespace.o

g++ ./release/obj/change.o ./release/obj/main.o ./release/obj/namespace.o -o release/test -lpthread -lrt

一点点体会:在调试Makefile过程中可能会碰到路径变量写错导致无法编译问题,我通常用@echo命令将可能出错的变量打印出来,好查找问题 一步一步修改。

例如

@echo $(DIR_CPP) 就可以将所以包含.cpp文件路径打印出来 如果路径变量不对的话 编译过程肯定会出错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  makefile 自动化 软件