makefile典型模板

合集下载

Makefile简单编写实例

Makefile简单编写实例

Makefile简单编写实例介绍⼀下Makefile的简单编写例⼦。

编写Makefile的规则就是:⽬标⽂件:依赖⽂件(tab)编译规则现在我有⼀个⽂件⽬录结构为:解释⼀下这⼏个⽂件。

⾸先我创建makefile⽬录,底下有⼀个include⽬录和src⽬录。

include⽬录存放⼀个head.h头⽂件,是我们src中所有cpp⽂件都要引⽤的头⽂件。

这四个cpp⽂件就是实现加减乘除的功能。

把add.cpp看⼀下就知道了:#include "head.h"int add(int a, int b){return a + b;}其余都⼀样,做各⾃的运算⽽已。

⽽main.cpp中我调⽤了它们:int main(int argc, char const *argv[]){printf("sum = %d\n", add(10, 3));printf("mul = %d\n", mul(10, 3));printf("sub = %d\n", sub(10, 3));printf("div = %lf\n", div(10, 3));return 0;}直接编写,易于理解现在我们要实现的功能就很明了了,编译这⼏个cpp,⽣成⼀个可执⾏⽂件,使得我们能够正确运⾏结果。

这⾥⾯我写了两个Makefile⽂件,第⼀个是Makefile_SB(改名之后),这个⽤来理解makefile的编写规则很有⽤:main:main.o add.o mul.o sub.o div.og++ -o main add.o mul.o sub.o div.o main.omain.o:main.cppg++ -c -I ../include main.cppadd.o:add.cpp ../include/head.hg++ -c -I ../include add.cppmul.o:mul.cpp ../include/head.hg++ -c -I ../include mul.cppsub.o:sub.cpp ../include/head.hg++ -c -I ../include sub.cppdiv.o:div.cpp ../include/head.hg++ -c -I ../include div.cpp.PHONY:cleanclean:rm -f *.o以上,我们遵循我们的规则:⽬标⽂件:依赖⽂件(tab)编译规则⾸先,main是我们最后要⽣成的可执⾏⽂件,它依赖于所有的.o⽂件,编译规则就是直接g++ -o .o⽂件即可。

通用makefile的编写

通用makefile的编写

通用makefile的编写Makefile是一种常用的构建工具,它可以通过简洁的语法描述源码的编译和链接过程,方便地实现代码的自动化构建。

在互联网技术领域,Makefile的编写尤为重要,它能帮助开发者管理复杂的项目结构和依赖关系。

本文将介绍通用Makefile的编写方法,帮助读者快速上手。

一、Makefile的基本结构Makefile由一系列规则(Rules)组成,每个规则定义了一个目标(Target)和依赖关系(Prerequisites),以及执行的命令(Commands)。

基本的Makefile结构如下:```target: prerequisitescommand```其中,target表示目标文件,prerequisites表示所依赖的文件,而command则是需要执行的命令。

当目标文件的依赖文件发生变化时,Make工具会自动执行对应的命令以完成构建。

二、Makefile的变量在编写Makefile时,可以使用变量来简化命令的书写和维护。

变量可以用来存储文件名、编译选项等信息。

通过声明变量并在命令中引用,可以提高代码的可读性和可维护性。

变量的声明格式如下:```VARIABLE_NAME = value```在命令中引用变量时,需要使用`$`符号进行替换。

例如,`${VARIABLE_NAME}`表示引用名为`VARIABLE_NAME`的变量。

三、Makefile的规则Makefile中的规则可以根据需要定义多个。

每个规则由一个目标文件、依赖关系和命令组成。

通过定义不同的规则,可以实现对不同文件的编译、链接等操作。

以下是一个示例规则的定义:```main.o: main.cgcc -c -o main.o main.c```上述规则表示要生成`main.o`文件,依赖于`main.c`文件。

命令`gcc -c -o main.o main.c`表示将`main.c`文件编译为`main.o`目标文件。

androidmakefile参数解释及模板

androidmakefile参数解释及模板

androidmakefile参数解释及模板1. LOCAL_MODULE_TAGS解释:控制此模块在什么情况下编译,一般为下面写法:LOCAL_MODULE_TAGS:= optional可选择的几个值:user:指该模块只在user版本下才编译eng: 指该模块只在eng版本下才编译tests: 指该模块只在tests版本下才编译optional:指该模块在所有版本下都编译2. include $(CLEAR_VARS)CLEAR_VARS变量是生成系统提供的,它指向一个特殊的GNU Makefile.这个Makefile将会为你自动清除许多名为LOCAL_XXX的变量(比如:LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES,,,),但LOCAL_PATH是例外,它不会被清除。

这些变量的清除是必须的,因为所有的控制文件是在单一的GNU make执行环境中解析的,在这里所有的变量都是全局的。

3.LOCAL_PATH这个变量用来设置当前文件的路径。

你必须在Android.mk的开始处定义它,比如:LOCAL_PATH := $(call my-dir)这个变量不会被$(CLEAR_VARS)消除,所以每个Android.mk仅需一个定义(以防你在同一个文件里定义几个组件)。

4. LOCAL_MODULE := xxx此mk文件生成的程序名称,包括动态库,静态库和可执行程序,如果为动态库,会生成libxxx.so文件5. LOCAL_SRC_FILES := xxx.c生成目标程序/库需要的源文件(*.c, *.cpp,*.java)列表6. include $(BUILD_SHARED_LIBRARY)编译此模块为动态库7. include $(BUILD_STATIC_LIBRARY)生成静态库8. include $(BUILD_EXECUTABLE)生成可执行程序9. LOCAL_SHARED_LIBRARIES程序依赖的动态库列表,例如LOCAL_SHARED_LIBRARIES := \libutils10. LOCAL_STATIC_LIBRARIES程序依赖的静态库列表11. LOCAL_CFLAGS += -Wall -Werror编译c文件的参数,如设置Wall,优化级别等编译器参数。

makefile elseif写法

makefile elseif写法

makefile elseif写法
在Makefile中,可以使用else if语句来表示"否则如果"的情况。

其基本语法格式如下:
```makefile
ifeq (条件1,条件1的值)
# 条件1成立时执行的命令
else ifeq (条件2,条件2的值)
# 条件2成立时执行的命令
else
# 所有条件都不成立时执行的命令
endif
```
其中,条件1、条件2为逻辑表达式,可以是变量的比较、函
数的返回值或者直接的比较等。

下面是一个使用elseif的示例:
```makefile
ifeq ($(OS),Windows_NT)
# Windows系统下执行的命令
rm = del /s /q
else ifeq ($(shell uname),Darwin)
# Mac系统下执行的命令
rm = rm -rf
else
# 其他系统下执行的命令
rm = rm -rf
endif
clean:
$(rm) obj/*.o
```
在上面的示例中,根据不同的操作系统类型,定义了不同的清理命令。

当`make clean`命令被执行时,将根据当前的操作系统类型选择相应的清理命令来删除`obj/*.o`文件。

“万能makefile”写法详解,一步一步写一个实用的Makefile

“万能makefile”写法详解,一步一步写一个实用的Makefile

“万能makefile”写法详解,一步一步写一个实用的Makefilehttps:///qq1452008/article/details/50865535? share_token=52d10253-88ef-4463-9727-2ebc94e23726&tt_from=copy_link&utm_source=copy_link&ut m_medium=toutiao_android&utm_campaign=client_share?=本文转载自:作者:胡彦 2013-5-21出处:/huyansoft/article/details/8924624 提示:本文在原博文的基础上做了一点点修改与完善,诸如原博文的后面有显示不全的地方,自己已完善!作者:胡彦 2013-5-21代码和文档下载地址:/share/link?shareid=616139&uk=2535441 82一目的:编写一个实用的makefile,能自动编译当前目录下所有.c/.cpp源文件,支持二者混合编译。

并且当某个.c/.cpp、.h或依赖的源文件被修改后,仅重编涉及到的源文件,未涉及的不编译。

二要达到这个目的,用到的技术有:1-使用wildcard函数来获得当前目录下所有.c/.cpp文件的列表。

2-make的多目标规则。

3-make的模式规则。

4-用gcc -MM命令得到一个.c/.cpp文件include了哪些文件。

(具体使用细节,请点击博文链接)5-用sed命令对gcc -MM命令的结果作修改。

6-用include命令包含依赖描述文件.d。

三准备知识(一)多目标对makefile里下面2行,可看出多目标特征,执行make bigoutput或make littleoutput可看到结果:bigoutput littleoutput: defs.h pub.h@echo $@ $(subst output,OUTPUT,$@) $^注释:$@指该规则目标集合中能引起该规则执行的目标,$^指这个规则里所有依赖的集合。

makefile写法

makefile写法

makefile写法Makefile 是代码构建和自动化构建的重要工具,它可以帮助我们高效、准确地管理和构建程序。

在本文中,我将和大家分享几种常见的Makefile 写法,以及一些有用的技巧和注意事项。

1. Makefile 的基本结构Makefile 中包含了以下基本结构:```target: dependencies<tab> command```其中,target 表示目标文件或目标任务名称;dependencies 表示该目标文件或任务所依赖的文件或任务;command 表示需要执行的命令。

比如,下面是一个简单的 Makefile 例子:```all: testtest: main.o func.o<tab> gcc main.o func.o -o testmain.o: main.c<tab> gcc -c main.c -o main.ofunc.o: func.c func.h<tab> gcc -c func.c -o func.o```其中,目标文件 all 是 Makefile 的默认目标,执行 make 命令时会自动执行 all 目标中所列出的任务。

在本例中,all 的唯一任务是test。

test 任务需要依赖 main.o 和 func.o,如果这两个文件不被更新,则 test 任务不会被重新构建。

2. Makefile 的变量在 Makefile 中,我们可以定义变量来方便地管理代码中的重复部分。

变量可以在任何位置使用,使得代码更加清晰易读,同时也方便了维护。

变量的定义格式是:```变量名 = 值```例如:```CC = gccCFLAGS = -Wall -g```在 Makefile 内使用变量的格式是 $+变量名。

例如:```all: testtest: main.o func.o<tab> $(CC) main.o func.o -o test $(CFLAGS)main.o: main.c<tab> $(CC) -c main.c -o main.o $(CFLAGS)func.o: func.c func.h<tab> $(CC) -c func.c -o func.o $(CFLAGS)```在本例中,我们定义了两个变量,CC 和 CFLAGS。

Makefile(for_linux)

为什么要make?可以不用么?试想你有这样的文件:/* main.c */#include “a.h”……/* 2.c */#include “a.h”#include “b.h”……/* 3.c */#include “b.h”#include “c.h”……如果你只是改了c.h,那么……myapp: main.o 2.o 3.ogcc -o myapp main.o 2.o 3.omain.o: main.c a.hgcc -c main.c2.o: 2.c a.h b.hgcc -c 2.c3.o: 3.c b.h c.hgcc -c 3.c什么是makefilemake是一个博大精深的命令,虽然有些东西你一辈子也永不到。

不过光凭make是不能知道你要想什么的,他需要makefile来做。

Make在makefile的指导下不仅可以编译安装软件,卸载软件,还可以安装使用手册等。

这些都可以使用makefile来完成。

.TH MYAPP 1.SH NAMEMyapp \- A simple demonstration application that does very little..SH SYNOPSIS.B myapp[\-option ...].SH DESCRIPTION.PP\fImyapp\fP is a complete application that does nothing useful..PPIt was written for demonstration purposes..SH OPTIONS.PPIt doesn't have any, but lets pretend, to make this template complete:.TP.BI \-optionIf there was an option, it would not be -option..SH RESOURCES.PPmyapp uses almost no resources..SH DIAGNOSTICSThe program shouldn't output anything, so if you find it doing so there's probably something wrong. The return value is zero..SH SEE ALSOThe only other program we know with this this little functionality is the ubiquitous hello world application..SH COPYRIGHTmyapp is Copyright (c) 1996 Wrox Press.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA..SH BUGSThere probably are some, but we don't know what they are yet..SH AUTHORSNeil Matthew and Rick Stones.SH ACKNOWLEDGEMENTThanks to Wrox press for publishing this book.Make本身的几个参数-k,让make在遇到错误的时候可以继续,这样就可以一遍检查出是那些问题。

一个通用的cc++Makefile模版

⼀个通⽤的cc++Makefile模版⼀个codeproject上发现的通⽤c/c++的Makefile模版,⽐较简单好⽤,共享之############################################################################### Generic Makefile for C/C++ Program## License: GPL (General Public License)# Author: whyglinux <whyglinux AT gmail DOT com># Date: 2006/03/04 (version 0.1)# 2007/03/24 (version 0.2)# 2007/04/09 (version 0.3)# 2007/06/26 (version 0.4)# 2008/04/05 (version 0.5)## Description:# ------------# This is an easily customizable makefile template. The purpose is to# provide an instant building environment for C/C++ programs.## It searches all the C/C++ source files in the specified directories,# makes dependencies, compiles and links to form an executable.## Besides its default ability to build C/C++ programs which use only# standard C/C++ libraries, you can customize the Makefile to build# those using other libraries. Once done, without any changes you can# then build programs using the same or less libraries, even if source# files are renamed, added or removed. Therefore, it is particularly# convenient to use it to build codes for experimental or study use.## GNU make is expected to use the Makefile. Other versions of makes# may or may not work.## Usage:# ------# 1. Copy the Makefile to your program directory.# 2. Customize in the "Customizable Section" only if necessary:# * to use non-standard C/C++ libraries, set pre-processor or compiler# options to <MY_CFLAGS> and linker ones to <MY_LIBS># (See Makefile.gtk+-2.0for an example)# * to search sources in more directories, set to <SRCDIRS># * to specify your favorite program name, set to <PROGRAM># 3. Type make to start building your program.## Make Target:# ------------# The Makefile provides the following targets to make:# $ make compile and link# $ make NODEP=yes compile and link without generating dependencies# $ make objs compile only (no linking)# $ make tags create tags for Emacs editor# $ make ctags create ctags for VI editor# $ make clean clean objects and the executable file# $ make distclean clean objects, the executable and dependencies# $ make help get the usage of the makefile##===========================================================================## Customizable Section: adapt those variables to suit your program.##==========================================================================# The pre-processor and compiler options.MY_CFLAGS =# The linker options.MY_LIBS =# The pre-processor options used by the cpp (man cpp for more).CPPFLAGS = -Wall# The options used in linking as well as in any direct use of ld.LDFLAGS =# The directories in which source files reside.# If not specified, only the current directory will be serached.SRCDIRS =# The executable file name.# If not specified, current directory name or `a.out' will be used.PROGRAM =## Implicit Section: change the following only when necessary.##========================================================================== # The source file types (headers excluded).# .c indicates C source files, and others C++ ones.SRCEXTS = .c .C .cc .cpp .CPP .c++ .cxx .cp# The header file types.HDREXTS = .h .H .hh .hpp .HPP .h++ .hxx .hp# The pre-processor and compiler options.# Users can override those variables from the command line.CFLAGS = -g -O2CXXFLAGS= -g -O2# The C program compiler.#CC = gcc# The C++ program compiler.#CXX = g++# Un-comment the following line to compile C programs as C++ ones.#CC = $(CXX)# The command used to delete file.#RM = rm -fETAGS = etagsETAGSFLAGS =CTAGS = ctagsCTAGSFLAGS =## Stable Section: usually no need to be changed. But you can add more.##========================================================================== SHELL = /bin/shEMPTY =SPACE = $(EMPTY) $(EMPTY)ifeq ($(PROGRAM),)CUR_PATH_NAMES = $(subst /,$(SPACE),$(subst $(SPACE),_,$(CURDIR)))PROGRAM = $(word $(words $(CUR_PATH_NAMES)),$(CUR_PATH_NAMES))ifeq ($(PROGRAM),)PROGRAM = a.outendifendififeq ($(SRCDIRS),)SRCDIRS = .endifSOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))HEADERS = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(HDREXTS))))SRC_CXX = $(filter-out %.c,$(SOURCES))OBJS = $(addsuffix .o, $(basename $(SOURCES)))DEPS = $(OBJS:.o=.d)## Define some useful variables.DEP_OPT = $(shell if `$(CC) --version | grep "GCC" >/dev/null`; then \echo "-MM -MP"; else echo "-M"; fi )DEPEND = $(CC) $(DEP_OPT) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS)DEPEND.d = $(subst -g ,,$(DEPEND))COMPILE.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) -cCOMPILE.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -cLINK.c = $(CC) $(MY_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS)LINK.cxx = $(CXX) $(MY_CFLAGS) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS).PHONY: all objs tags ctags clean distclean help show# Delete the default suffixes.SUFFIXES:all: $(PROGRAM)# Rules for creating dependency files (.d).#------------------------------------------%.d:%.c@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.C@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.cc@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.cpp@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.CPP@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.c++@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.cp@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@%.d:%.cxx@echo -n $(dir $<) > $@@$(DEPEND.d) $< >> $@# Rules for generating object files (.o).#----------------------------------------objs:$(OBJS)%.o:%.c$(COMPILE.c) $< -o $@%.o:%.C$(COMPILE.cxx) $< -o $@%.o:%.cc$(COMPILE.cxx) $< -o $@%.o:%.cpp$(COMPILE.cxx) $< -o $@%.o:%.CPP$(COMPILE.cxx) $< -o $@%.o:%.c++$(COMPILE.cxx) $< -o $@%.o:%.cp$(COMPILE.cxx) $< -o $@%.o:%.cxx$(COMPILE.cxx) $< -o $@# Rules for generating the tags.#-------------------------------------tags: $(HEADERS) $(SOURCES)$(ETAGS) $(ETAGSFLAGS) $(HEADERS) $(SOURCES)ctags: $(HEADERS) $(SOURCES)$(CTAGS) $(CTAGSFLAGS) $(HEADERS) $(SOURCES)# Rules for generating the executable.#-------------------------------------$(PROGRAM):$(OBJS)ifeq ($(SRC_CXX),) # C program$(LINK.c) $(OBJS) $(MY_LIBS) -o $@@echo Type ./$@ to execute the program.else # C++ program$(LINK.cxx) $(OBJS) $(MY_LIBS) -o $@@echo Type ./$@ to execute the program.endififndef NODEPifneq ($(DEPS),)sinclude $(DEPS)endifendifclean:$(RM) $(OBJS) $(PROGRAM) $(PROGRAM).exedistclean: clean$(RM) $(DEPS) TAGS# Show help.help:@echo 'Generic Makefile for C/C++ Programs (gcmakefile) version 0.5'@echo 'Copyright (C) 2007, 2008 whyglinux <whyglinux@>'@echo@echo 'Usage: make [TARGET]'@echo 'TARGETS:'@echo ' all (=make) compile and link.'@echo ' NODEP=yes make without generating dependencies.'@echo ' objs compile only (no linking).'@echo ' tags create tags for Emacs editor.'@echo ' ctags create ctags for VI editor.'@echo ' clean clean objects and the executable file.'@echo ' distclean clean objects, the executable and dependencies.'@echo ' show show variables (for debug use only).'@echo ' help print this message.'@echo@echo 'Report bugs to <whyglinux AT gmail DOT com>.'# Show variables (for debug use only.)show:@echo 'PROGRAM :' $(PROGRAM)@echo 'SRCDIRS :' $(SRCDIRS)@echo 'HEADERS :' $(HEADERS)@echo 'SOURCES :' $(SOURCES)@echo 'SRC_CXX :' $(SRC_CXX)@echo 'OBJS :' $(OBJS)@echo 'DEPS :' $(DEPS)@echo 'DEPEND :' $(DEPEND)@echo 'COMPILE.c :' $(COMPILE.c)@echo 'COMPILE.cxx :' $(COMPILE.cxx)@echo 'link.c :' $(LINK.c)@echo 'link.cxx :' $(LINK.cxx)## End of the Makefile ## Suggestions are welcome ## All rights reserved ###############################################################################。

makefile 加法

makefile 加法
以下是一个简单的makefile示例,用于实现两个整数相加的操作:
```
# 定义变量
CC = gcc
CFLAGS = -Wall -g
TARGET = add
OBJS = main.o add.o
# 默认目标
all: $(TARGET)
# 生成可执行文件
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS)
# 生成目标文件
%.o: %.c
$(CC) $(CFLAGS) -c $<
# 清除生成的文件
clean:
rm -rf $(TARGET) $(OBJS)
```
这个makefile中,定义了变量`CC`表示编译器的名称,
`CFLAGS`表示编译选项,`TARGET`表示最终生成的可执行
文件,`OBJS`表示需要编译的目标文件。

默认目标`all`指定了最终生成的可执行文件`$(TARGET)`依赖于目标文件`$(OBJS)`,在编译时使用了编译器和编译选项。

目标文件的生成规则使用了通配符`%`指定了规则,表示将所有的`.c`文件编译成对应的`.o`文件。

clean目标用于清除生成的文件。

编写好makefile文件后,在命令行中运行`make`命令即可编译生成可执行文件。

模块编译Makefile模板 && Nothing to be done for `modules'

最近在linux2.4内核上编译一个动态加载模块时遇到这样一个问题,执行make时编译器不编makefile文件中所指定的目标文件,而是提示一句Nothing to be done for `modules',然后就退出了。

主控Makefile文件中采用的式来编译模块的:$(MAKE) -C $(KERNELPA TH) SUBDIRS=$(shell pwd) modules下面我们来分析一下原因,并寻找解决的方法。

一、先看看执行$(MAKE) -C $(KERNELPA TH) SUBDIRS=$(shell pwd) modules后脚本是怎样执行的:1.进入内核目录,执行modules目标modules: $(patsubst %, _mod_%, $(SUBDIRS))这里把传入的SUBDIRS变量加上一个_mod_前缀,使modules依赖于他$(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h \ include/config/MARKER $(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules这里回到SUBDIRS执行modules,但是带入CFLAGS变量2.回到SUBDIRS执行modules目标,但是Makefile文件中根本就没有这个目标的存在,当然会报Nothing to be done for `modules'了,那么这个modules目标到底是什么呢?找个2.4与2.6内核通用的模块编译Makefile文件看看,它通常在目标all之前有这样几行语句:-include $(TOPDIR)/Rules.makeall_targets:all这就是问题的关键所在!TOPDIR变量内核根Makefile文件中定义的TOPDIR := $(shell /bin/pwd)就是指内核的路径,所以Include前面的“-”就显得尤为重要。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Makefile典型模板
Sunny.man

1.写在前面
在这篇文章之前,曾经因为自己学习makefile文件写了一个笔记,笔记中
简单的传述了文件的书写规范,我把此笔记上传面了一个文档,此文档不能称为
一个合格的文档。我在实际的使用过程中才发现,用上述文档来编写一个合格的
makefile文件是远远不够的,为此我写了一个makefile模块供大家改写,毕竟
我们要写的是应用程序而不是一个makefile文件。我在学习makefile的过程中
查阅了很多的资料,走了不少的弯路。为了同行们把宝贵的时间用在自己的应用
程序开发上,我写了这篇文档。Makefile的要求如下
1. 快速编译,不更新的文件不重新编译。
2. 当一个.c文件做修改时不需要手动添加依赖。
3. 源文件放一个目录,头文件放一个目录,依赖放一个目录,目标一个目
录。
4. 头文件的修改会自动重新编译所有引用它的.c文件
5. 这个makefile文件一定是没有错误可以运行的,我认为这一点太重要的。
我在网上查的许多文件都根本不能运行,好多的文章代码部分都是一样
的,难道只是转载的吗?
2.直接上代码
3.一些必要的解译
3.1宏定义
其实make本身已有许多的default的macro,如果要查看这些macro的
话,可以用make -p的命令.这里不做过多解释。

3.2>debug.txt 2>&1
把输出和错误重新定位到文件debug.txt
3.3makefile中的函数
makefile里的函数使用,和取变量的值类似,是以一个‘$’开始,然后是一个
括号里面是函数名和需要的参数列表,多个变量用逗号隔开,像这样
return = $(functionname arg1,arg2,arg3...)。

3.4$(wildcard $(SRCPATH)*.c)
$(wildcard PATTERN...) ,在Makefile中,它被展开为已经存在的、使用空
格分开的、匹配此模式的所有文件列表。如果不存在任何符合此模式的文件,函
数会忽略模式字符并返回空。
$(wildcard $(SRCPATH)*.c)就是返回宏SRCPATH指定的目录下的所有.c
文件。如果SRCPATH=./SRC/并且目录下有main.c和fun.c两个文件,则返回
的是./SRC/main.c ./SRC/fun.c这个字符串。

3.5$(notdir $(SOURCES))
使用:SRC = $(notdir wildcard)
去除所有的目录信息,SRC里的文件名列表将只有文件名。如果
SOURCES=./SRC/main.c ./SRC/fun.c则返回main.cfun.c

3.6OBJS := $(patsubst %.c, $(OBJPATH)%.o,$(SRC))
格式:$(patsubst,, )
功能:查找中的单词(单词以“空格”、“Tab”或“回车”“换行”分隔)
是否符合模式,如果匹配的话,则以替换。这里,
可以包括通配符“%”,表示任意长度的字串。如果
中也包含“%”,那么,中的这个“%”将是中的那
个“%”所代表的字串。(可以用“\”来转义,以“\%”来表示真实含义的“%”
字符)
OBJS := $(patsubst %.c, $(OBJPATH)%.o,$(SRC))是把main.cfun.c中的.c
用.o来代替,并使用%来代替main fun然后再前后加上./OBJS/最终字符串为
./OBJS/main.o ./OBJS/fun.o

3.7变量的替代
对于一个已经定义的变量,可以使用“替换引用”将其值中的后缀字符(串)使
用指定的字符(字符串)替换。格式为“$(VAR:A=B)”,意思是,替换变量“VAR”
中所有“A”字符结尾的字为“B”结尾的字。“结尾”的含义是空格之前(变量
值多个字之间使用空格分开)。而对于变量其它部分的“A”字符不进行替换。
例如:
MMM:=$( OBJS:%.c=%.d)则MMM=main.dfun.d
这个和那个模式匹配是一样的。

3.8.PHONY伪目标
.PHONY:all clean install#伪目标,就是不管目标文件是否生成,都继续执
行命令

3.9$(OBJS):$(OBJPATH)%.o:$(SRCPATH)%.c
静态模式
静态模式规则是这样一个规则:规则存在多个目标,并且不同的目标可以根据目标
文件的名字来自动构造出依赖文件。但是静态模式规则中的依赖文件必须是相类
似的而不是完全相同的。
TARGETS ...: TARGET-PATTERN: PREREQ-PATTERNS ...
COMMANDS
...
“TAGETS”列出了此规则的一系列目标文件。像普通规则的目标一样可以包含
通配符。“TAGET-PATTERN”和“PREREQ-PATTERNS”说明了如何为每一个
目标文件生成依赖文件。
$(OBJS):$(OBJPATH)%.o:$(SRCPATH)%.c
每个./OBJS/*.o目标文件由相应的./SRC/*.c来生成。

3.10一个重要的理解
all:main
main:./OBJS/main.o
main:./OBJS/sunnyudp.o
gcc -o main $^
上面这种写法一般不会出现在makefile文件中,但它是合法的,并且它等价于
Gcc–o main ./OBJS/main.o./OBJS/sunnyudp.o。
为什么要把这个单独拿出来记一下呢,下面一节就是这个问题的实践。

3.11sinclude $(DEPEND)
“sinclude”和“-include”是同一个意思,都是如果出错继续执行的意思。
sinclude $(DEPEND)就是把main.d和fun.d里面的内容包含进来。这两个文
件是下面的内容。
./OBJS/main.o ./DFILE/main.d:./SRC/main.c ./SRC/include/fun.h
./OBJS/fun.o ./DFILE/fun.d:./SRC/fun.c ./SRC/include/fun.h
接下来是$(OBJS):$(OBJPATH)%.o:$(SRCPATH)%.c
$(CC) $(CFLAGS) -c -o $@ $< $(INCLUDEFLAGS) $(LIBFLAGS)
$(OUTPUTFLAGS)
这和我们上面讲的一个样,现在gcc–o main.o的依赖变成了两者的并集。
3.12$(DFPATH)%.d:$(SRCPATH)%.c
.d文件的生成主要是靠参数-MM。它自动生成除系统头文件外的所有文件依赖。
@$(CC) -MM $(CFLAGS) $<> $@.$$$$mhy; \
sed 's,\($$*\)\.o[ :]*,\1.o $@ :,g' < $@.$$$$mhy> $@.$$$$; \
sed 's,^,$(OBJPATH),' < $@.$$$$ > $@;\
$(RM) $@.$$$$mhy;\
$(RM) $@.$$$$;\
$@.$$$$mhy是根据当前sh的进程ID来生成一个昨时文件。然后用sed命令
在.o后插入main.d。接下来在行首加入路径名。然后删除昨时文件。
注:大家仔细观察可以发现这段内容用的是\来接行,这是为什么呢。因为用到
了昨时文件,而这个文件是以sh的进程ID来命名的,如果两个命令,则启动
了不同的sh会找不到相应的昨时文件。不信?你可以试试,去掉最后rm的两
个连接符,你会发现删除不了昨时文件。在Makefile中,若一行不足以容纳该
命令的时候.可在此行之后加一个反斜线(\)表示下一行为本行的延续,两行应视
为一行处理

3.13符号标志及缺省规则
$@ 代指目标文件
$< 第一个依赖文件
$^ 所有的依赖文件
$? 为该规则的依赖
- 若在command的前面加一个"-",表示若此command发生错误不
予理会,继续执行下去.
3.14%.o:%.c
"%.o:%.c",意思是说,xxx.o 需要xxx.c,注意,如果他们不在一个
路径下,记得改为"%.o:$(path)%.c",这样才能找到.c代码。换句话说,"%"匹
配的是这个文件的名字,并不包括路径!

相关文档
最新文档