万能make file
生活随笔
收集整理的這篇文章主要介紹了
万能make file
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#################################################
# 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級優化;
##
# 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級優化;
##
總結
以上是生活随笔為你收集整理的万能make file的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TensorFlow 相关 URL
- 下一篇: Tensorflow简单教程