万能Makefile

5 篇文章 0 订阅

####################################################
# Generic makefile - 万能Makefile
# for compiling and linking C++ projects on Linux 
# Author: George Foot  Modified:Jackie Lee
####################################################
### Customising
#
# Adjust the following if necessary; EXECUTABLE is the target
# executable's filename, and LIBS is a list of libraries to link in
# (e.g. alleg, stdcx, iostr, etc). You can override these on make's
# command line of course, if you prefer to do it that way.
#
#
EXECUTABLE := main    # 可执行文件名
LIBDIR:=              # 静态库目录
LIBS :=               # 静态库文件名
INCLUDES:=.           # 头文件目录
SRCDIR:=              # 除了当前目录外,其他的源代码文件目录
#
# # Now alter any implicit rules' variables if you like, e.g.:


CC:=g++
CFLAGS := -g -Wall -O3
CPPFLAGS := $(CFLAGS)
CPPFLAGS += $(addprefix -I,$(INCLUDES))
CPPFLAGS += -MMD
#
# # The next bit checks to see whether rm is in your djgpp bin
# # directory; if not it uses del instead, but this can cause (harmless)
# # `File not found' error messages. If you are not using DOS at all,
# # set the variable to something which will unquestioningly remove
# # files.
#


RM-F := rm -f




# # You shouldn't need to change anything below this point.
#
SRCS := $(wildcard *.cpp) $(wildcard $(addsuffix /*.cpp, $(SRCDIR)))
OBJS := $(patsubst %.cpp,%.o,$(SRCS))
DEPS := $(patsubst %.o,%.d,$(OBJS))
MISSING_DEPS := $(filter-out $(wildcard $(DEPS)),$(DEPS))
MISSING_DEPS_SOURCES := $(wildcard $(patsubst %.d,%.cpp,$(MISSING_DEPS)))




.PHONY : all deps objs clean veryclean rebuild info


all: $(EXECUTABLE)


deps : $(DEPS)


objs : $(OBJS)


clean :
@$(RM-F) *.o
@$(RM-F) *.d
veryclean: clean
@$(RM-F) $(EXECUTABLE)


rebuild: veryclean all
ifneq ($(MISSING_DEPS),)
$(MISSING_DEPS) :
@$(RM-F) $(patsubst %.d,%.o,$@)
endif
-include $(DEPS)
$(EXECUTABLE) : $(OBJS)
$(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -L,$(LIBDIR)) $(addprefix -l,$(LIBS))


info:
@echo $(SRCS)
@echo $(OBJS)
@echo $(DEPS)
@echo $(MISSING_DEPS)
@echo $(MISSING_DEPS_SOURCES)






















##
注:1)命令行前的空白符必须为一个制表符(Tab);如,@$(RM-F) *.o前不是空格,而是一个制表符;


内容解析


1.Makefile基本语法


target为要生成的目标文件;dependency为target的依赖文件;command为用于生成target的命令行;


<target> : <dependency> <dependency> ...
(tab)<command>
(tab)<command>
 .
 .
 .
2.赋值符号 := 与 =


  :=与=的区别在于,符号:=表示立即展开变量值。例如:


A:=foo


B:=$(A)


A:=bar


这时,B的值仍为foo,因为它已被展开,不会再随A的值改变而改变。


3.符号#是Makefile的注释符号


4.wildcard函数


SRCS:=$(wildcard *.cpp) 表示列举当前目录中扩展名为.cpp的所有文件,然后赋值给变量SRCS。详细请google之。


5.patsubst函数


OBJS := $(patsubst %.cpp,%.o,$(SRCS))表示,将$(SRCS)中所有满足模式%.cpp的字符串替换为%.o。


6.filter-out函数


$(filter-out $(A),$(B))表示从B中过滤掉A中的内容,返回剩余内容;


7. “.PHONY”


用.PHONY修饰的target是“伪目标”,不需要生成真实的文件;make假定phony target是已经生成的,然后更新它后边的依赖文件和执行它下边的命令(command);


8.all deps objs clean veryclean rebuild info


这些都是“伪目标”。


all是第一个目标,所以输入make时它被默认执行;all生成或更新所有*.cpp文件对应的*.d文件和*.o文件,并链接所有*.o文件生成可执行文件$(EXECUTABLE)。


deps仅仅生成*.d文件;.d文件是什么文件?它包含了代码文件的依赖信息。


objs仅仅生成*.o文件;.o文件是C++代码编译后的中间结果文件,废话!


clean用于删除*.d文件和*.o文件。


veryclean删除*.d文件、*.o文件,还有名为$(EXECUTABLE)的可执行文件。


rebuild先调用veryclean清除结果文件,再调用all重新编译和链接。


info查看某些信息。


使用方法:


make deps即可执行deps;


9.ifneq...else...endif


条件语句,ifneq表示如果不想等,则...;


10.include <files>语句


include表示把<files>的内容包含进来;


$(DEPS)是包含依赖信息的文件,每个源文件对应一个.d文件;-include $(DEPS)表示把这些依赖信息包含进来;


11.链接*.o文件,生成可执行文件


主菜来了!


$(EXECUTABLE) : $(OBJS)
        $(CC) -o $(EXECUTABLE) $(OBJS) $(addprefix -l,$(LIBS))
 


$(EXECUTABLE)为可执行文件名;$(OBJS)为所有.o文件名;$(CC)在这里是g++;$(addprefix -l,$(LIBS)添加引用库;


前面说好的*.d文件和*.o文件是怎么生成的呢?貌似没有命令指出要生成它们呀!请看隐含规则!


12. 隐含规则(Implicit rules)


$(EXECUTABLE)依赖于$(OBJS),但makefile中没有指明$(OBJS)依赖于谁,也没指明命令生成它们;


这时,make的隐含规则开始起作用;针对$(OBJS)中的每个目标,make自动调用:


$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@ 


依次生成.o文件和.d文件;


$<表示依赖文件列表的第一个文件名;


$@表示目标文件名;


之所以会生成.d文件,是由于“-MMD”这一编译选项。为g++加上这一选项后,编译器会生成文件依赖信息,并存放至.d文件中。


每一个.cpp文件相应地生成一个.d文件和一个.o文件。


13.@符号


命令行前的@符号表示不回显命令行;


14.CFLAGS和CPPFLAGS


这两者包含编译选项,更详细内容请Google之。


-g 添加gdb调试信息;


-Wall 提示warning信息;


-O3 表示第3级优化;
##

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值