Makefile
可以用文本编辑器编写makefile文件,与源文件保存在同一目录下,名称取为"Makefile"或"makefile".
在确定安装好Mingw并且配置好环境变量后,使用命令行,转到源文件所在的目录下,然后输入命令"mingw32-make", 即可编译成功。如果你的Makefile名称为其他(比如buildFile.mk),则在Build命令执行时需要特别指定,即make -f buildFile.mk 。
A makefile consist of Rules and these Rules consist of three main things:Targets,Dependencies and Commands. In GNU Documentation these are called:Target,Requirements and Recipe. And this is how it looks:
target ... : dependencies ... command ... ...
command 是命令行,如果其不与“target:prerequisites”在一行,那么,必须以[Tab键]开头;如果和 prerequisites 在一行,那么可以用分号(;)做为分隔。
This is how a Rule look as in GNU Documentation:
target ... : requirements ... recipe ... ...
A makefile can consist of other elements that help us write better Rules to handle our source code, some of these elements are:Comments,Macros and Functions. Here you can see how they look:
# MY LINE COMMENT ... myMACRO = myVALUE ... ... $(theFunction ...) ...
# A sample Makefile # This Makefile demonstrates and explains # Make Macros, Macro Expansions, # Rules, Targets, Dependencies, Commands, Goals # Artificial Targets, Pattern Rule, Dependency Rule. # Comments start with a # and go to the end of the line. # Here is a simple Make Macro. LINK_TARGET = test_me.exe # Here is a Make Macro that uses the backslash to extend to multiple lines. # This allows quick modification of more object files. OBJS = \ Test1.o \ Test2.o \ Main.o # Here is a Make Macro defined by two Macro Expansions. # A Macro Expansion may be treated as a textual replacement of the Make Macro. # Macro Expansions are introduced with $ and enclosed in (parentheses). REBUILDABLES = $(OBJS) $(LINK_TARGET) # Make Macros do not need to be defined before their Macro Expansions, # but they normally should be defined before they appear in any Rules. # Consequently Make Macros often appear first in a Makefile. # Here is a simple Rule (used for "cleaning" your build environment). # It has a Target named "clean" (left of the colon ":" on the first line), # no Dependencies (right of the colon), # and two Commands (indented by tabs on the lines that follow). # The space before the colon is not required but added here for clarity. clean : rm -f $(REBUILDABLES) echo Clean done # There are two standard Targets your Makefile should probably have: # "all" and "clean", because they are often command-line Goals. # Also, these are both typically Artificial Targets, because they don't typically # correspond to real files named "all" or "clean". # The rule for "all" is used to incrementally build your system. # It does this by expressing a dependency on the results of that system, # which in turn have their own rules and dependencies. all : $(LINK_TARGET) echo All done # There is no required order to the list of rules as they appear in the Makefile. # Make will build its own dependency tree and only execute each rule only once # its dependencies' rules have been executed successfully. # Here is a Rule that uses some built-in Make Macros in its command: # $@ expands to the rule's target, in this case "test_me.exe". # $^ expands to the rule's dependencies, in this case the three files # main.o, test1.o, and test2.o. $(LINK_TARGET) : $(OBJS) g++ -g -o $@ $^ # Here is a Pattern Rule, often used for compile-line. # It says how to create a file with a .o suffix, given a file with a .cpp suffix. # The rule's command uses some built-in Make Macros: # $@ for the pattern-matched target # $lt; for the pattern-matched dependency %.o : %.cpp g++ -g -o $@ -c $< # These are Dependency Rules, which are rules without any command. # Dependency Rules indicate that if any file to the right of the colon changes, # the target to the left of the colon should be considered out-of-date. # The commands for making an out-of-date target up-to-date may be found elsewhere # (in this case, by the Pattern Rule above). # Dependency Rules are often used to capture header file dependencies. Main.o : Main.h Test1.h Test2.h Test1.o : Test1.h Test2.h Test2.o : Test2.h # Alternatively to manually capturing dependencies, several automated # dependency generators exist. Here is one possibility (commented out)... # %.dep : %.cpp # g++ -M $(FLAGS) $< > $@ # include $(OBJS:.o=.dep)
The following -k flag tells make to continue making other independent rules even when one rule fails. This is helpful for build large projects.
-->>Referenced from http://help.eclipse.org/helios/index.jsp?topic=%2Forg.eclipse.cdt.doc.user%2Fconcepts%2Fcdt_c_makefile.htm
另外,若对上面的g++ 命令后的参数不懂,可以在命令行下输入g++ --help, 以查看它的使用帮助。
下面是另一份makefile的模板:
#makefile的细节: #1.每行命令后面不要带多余的空格 #2.windows和linux下的shell命令、目录表示不同 #3.CINCS = -I.\includes 中I和.之间不能有空格 #几个特殊变量的含义 #$@ 用在生成规则中,表示当前目标 #$< 用在生成规则中,表示当前目标的第一个依赖目标 #$^ 用在生成规则中,表示当前目标的所有依赖目标 ######################################################### #本makefile对应的工程目录组织 # ./ ------- project root # +sources/ # +includes/ # +objs/ # TARGET # resource.rc # resource.h # makefile #修改时,根据实际改变响应的目录名,另外重填./sources下源文件列表 ######################################################### TARGET = winhello.exe #msys ##########目录设置 ########## ####工程根目录 PROJECT_ROOT = . ###源代码根目录#### SRC_DIR = $(PROJECT_ROOT)/sources OBJS_DIR := $(PROJECT_ROOT)/objs APP_CSRCS = main.c RES_SRC = resource.rc ifdef APP_CSRCS CSRCS := $(addprefix $(SRC_DIR)/,$(APP_CSRCS)) endif ############## 添加路径 ############# COBJS := $(addprefix $(OBJS_DIR)/, $(patsubst %.c,%.o,$(notdir $(CSRCS)))) ifdef RES_SRC RES_OBJ = $(addprefix $(OBJS_DIR)/, $(patsubst %.rc,%.o,$(notdir $(RES_SRC)))) endif ###########编译器命令相关######### CC = gcc RESC = windres RM = rm #注意 windows下将等于号后面的rm改为del,linux下RM = rm #头文件目录 INC_DIR := ./includes #编译选项 CFLAGS = -g -Wall CFLAGS += -I$(INC_DIR) all : $(TARGET) version : @echo Show $(CC) Version $(CC) --version $(TARGET) : $(COBJS) $(RES_OBJ) @echo 连接目标文件,生成最终target -- $@ # $(CC) $(COBJS) $(RES_OBJ)-o $@ $(CC) $^ -o $@ # 编译C程序 $(OBJS_DIR)/%.o : $(SRC_DIR)/%.c @echo 正在编译c文件: $< --> $@ $(CC) -c $(CFLAGS) $< -o $@ $(RES_OBJ):$(RES_SRC) $(RESC) $< -o $@ .PHONY:msg clean msg: @echo CSRCS是$(CSRCS) @echo COBJS是$(COBJS) @echo CFLAGS是$(CFLAGS) @echo RM命令是$(RM) @echo RESC是$(RESC) @echo RES_SRC是$(RES_SRC) @echo RES_OBJ是$(RES_OBJ) clean:cleanobj cleanexe @echo obj文件和exe文件已删除 cleanobj: @echo 删除所有.o文件 -$(RM) $(COBJS) -$(RM) $(RES_OBJ) cleanexe: @echo 删除所有.exe文件 -$(RM) $(TARGET)
我的成功实例↓
使用mingw32-make Build指令:
结果:
其实,我们直接在命令行下输入以下语句,也可以编译得到同样的结果,只是少了很多控制的便利,比如根据文件依赖关系和修改时间来重新编译程序等。不过这也证明了g++可以直接根据程序文件(.cpp文件)推断出同名的头文件(.h文件)依赖。