Makefile编写和使用技巧

来源:互联网 发布:如何注销淘宝网账号 编辑:程序博客网 时间:2024/05/16 09:06

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 ...) ...
-->>Referenced from  http://www.captaincps.net/2011/11/28/writting-simple-mingw-makefile/

Sample Makefile

# 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.hTest1.o : Test1.h Test2.hTest2.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)/sourcesOBJS_DIR := $(PROJECT_ROOT)/objsAPP_CSRCS = main.cRES_SRC      = resource.rcifdef APP_CSRCSCSRCS := $(addprefix $(SRC_DIR)/,$(APP_CSRCS))endif############## 添加路径 #############COBJS := $(addprefix $(OBJS_DIR)/, $(patsubst %.c,%.o,$(notdir $(CSRCS))))ifdef RES_SRCRES_OBJ = $(addprefix $(OBJS_DIR)/, $(patsubst %.rc,%.o,$(notdir $(RES_SRC))))endif###########编译器命令相关#########CC = gcc RESC = windresRM = rm#注意 windows下将等于号后面的rm改为del,linux下RM = rm#头文件目录INC_DIR := ./includes #编译选项CFLAGS = -g -WallCFLAGS += -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 cleanmsg:        @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)


我的成功实例↓





makefile文件的内容:

LINK_TARGET= AirlineTicketTest.exe
OBJS = \
 AirlineTicketTest.o \
 AirlineTicket.o


 
$(LINK_TARGET) :$(OBJS)
 g++ -g -o $@ $^
AirlineTicketTest.o : AirlineTicketTest.cpp
 g++ -g -o $@ -c $<
AirlineTicket.o : AirlineTicket.cpp
 g++ -g -o $@ -c $<

AirlineTicketTest.o
: AirlineTicket.h
AirlineTicket.o
: AirlineTicket.h

clean
:
# rm -f $(OBJS)

 -del
$(OBJS)
 echo Clean done
all :$(LINK_TARGET)
 echo All done

























使用mingw32-make Build指令:

C:\workspace>mingw32-make
g++ -g -o AirlineTicketTest.o -c AirlineTicketTest.cpp
g++ -g -o AirlineTicket.o -c AirlineTicket.cpp
g++ -g -o AirlineTicketTest.exe AirlineTicketTest.o AirlineTicket.o








结果:

C:\workspace>mingw32-make -k clean all
del AirlineTicketTest.o AirlineTicket.o
echo Clean done
Clean done
g++ -g -o AirlineTicketTest.o -c AirlineTicketTest.cpp
g++ -g -o AirlineTicket.o -c AirlineTicket.cpp
g++ -g -o AirlineTicketTest.exe AirlineTicketTest.o AirlineTicket.o
echo All done
All done












其实,我们直接在命令行下输入以下语句,也可以编译得到同样的结果,只是少了很多控制的便利,比如根据文件依赖关系和修改时间来重新编译程序等。不过这也证明了g++可以直接根据程序文件(.cpp文件)推断出同名的头文件(.h文件)依赖


C:\workspace>g++ -g -o AirlineTicketTest.o -c AirlineTicketTest.cpp
g++ -g -o AirlineTicket.o -c AirlineTicket.cpp
g++ -g -o AirlineTicketTest.exe AirlineTicketTest.o AirlineTicket.o







原创粉丝点击