Chinaunix首页 | 论坛 | 博客
  • 博客访问: 514753
  • 博文数量: 484
  • 博客积分: 10145
  • 博客等级: 上将
  • 技术积分: 5805
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-27 18:34
文章分类

全部博文(484)

文章存档

2011年(52)

2010年(107)

2009年(287)

2008年(38)

我的朋友

分类:

2010-04-22 00:30:41

# Hey Emacs, this is a -*- makefile -*-

#

# WinAVR Sample makefile written by Eric B. Weddington, J鰎g Wunsch, et al.

# Released to the Public Domain

# Please read the make user manual!

#

# Additional material for this makefile was submitted by:

#  Tim Henigan

#  Peter Fleury

#  Reiner Patommel

#  Sander Pool

#  Frederik Rouleau

#  Markus Pfaff

#

# On command line:

#

# make all = Make software.

#

# make clean = Clean out built project files.

#

# make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB).

#

# make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio

#                4.07 or greater).

#

# make program = Download the hex file to the device, using avrdude.  Please

#                customize the avrdude settings below first!

#

# make filename.s = Just compile filename.c into the assembler code only

#

# To rebuild project do "make clean" then "make all".

#

 

风城少主 于 2008年10月19日  笔

 

E_mail :

 

欢迎转载和与我交流!

 

今天有空,解释 下Winavr中的makefile!

注:从“/*” 到 “*/”之间的内容是我加入的

 

 

 

# MCU name

MCU = atmega128

/*

在makefile文件中定义的变量,有点类似C语言中的宏,它代表了一个文本字符串;在C语言 中,在编译的预处理阶段,用到宏的地方都会用宏的定义进行精确的展开,而在makefile文件执行的时候,变量也会自动按它的值展开在所使用的位置。既 然称作变量,当然就是可改变的,这就是它与C语言中的宏的不同之处。

在上面定义了 一个变量MCU,并赋予它的初值为atmega128。

变量的赋值,有如下三种方 法:

1). MCU = atmega128              //直接赋值

2). MCU := $(AVR)                      //直接赋值,但有限制

3). MCU+ = atmega128            //追加方式

讲下第二种,这句话的意 思是把变量AVR的值赋予变量MCU,使用一个变量时需要用$(),这个要记住!“=”号前有个“:”,这要求变量AVR要在变量MCU定义之前被定义, 这就是限制!

前面讲到它有点类似C语言中的宏,它代表了一个文本字符串,追加方式 可以理解为两个字符串连接在一起。

这个变量的作用主要是传递MCU型号给编译器, 好让它选择与MCU型号对应头文件等。

*/

 

# Output format. (can be srec, ihex, binary)

FORMAT = ihex

/* 定义一个变量FORMAT,值为ihex,作用是选择生成的烧录文件的格式,该变量可设置的值有srec, ihex, binary */

 

# Target file name (without extension).

TARGET = main

/* 定义一个变量TARGET,值为main,作用是告诉编译器最终目标的名字叫什么,在这里就讲下什么叫目标,请看下面:

foo.o: foo.c foo.h

         gcc –c –g foo.c

foo.o也就是 目标!foo.c foo.h是foo.o目标所依赖的文件,如果foo.c与foo.h当中有一个或以上文件比foo.o文件要新的话,就执行命令gcc –c –g foo.c,注意命令必须以Tab键开始!

将它一般化就如下:

target ... : prerequisites ...

command

target 是一个目标文件,可以是中间代码文件(Object File),也可以是执行文件,还可以是一个标签(Label)。

prerequisites是要生成那个target所需要或依赖的文件或目标。

command是make需要执行的命令(以Tab键开始)。

说白一点就是,prerequisites中如果有一个或以上的文件比target文件要新的 话,command所定义的命令就会被执行。这就是Makefile的规则,也就是Makefile中最核心的内容。

*/

 

# List C source files here. (C dependencies are automatically generated.)

SRC = app.c fun.c

/* 定义一个变量SRC,值为app.c fun.c,作用是选择需要编译的C源文件 */

 

# List Assembler source files here.

# Make them always end in a capital .S.  Files ending in a lowercase .s

# will not be considered source files but generated files (assembler

# output from the compiler), and will be deleted upon "make clean"!

# Even though the DOS/Win* filesystem matches both .s and .S the same,

# it will preserve the spelling of the filenames, and gcc itself does

# care about how the name is spelled on its command-line.

ASRC =

/* 定义一个变量ASRC,值为空,作用是选择需要编译的汇编源文件 */

 

# Optimization level, can be [0, 1, 2, 3, s].

# 0 = turn off optimization. s = optimize for size.

# (Note: 3 is not always the best optimization level. See avr-libc FAQ.)

OPT = s

/* 定义一个变量OPT,值为s,作用是选择编译优化级别,该变量可设置的值有0, 1, 2, 3, s;

这里选择s,也就是告诉编译器,专门优化代码的大小*/

 

# Debugging format.

# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.

# AVR (extended) COFF requires stabs, plus an avr-objcopy run.

DEBUG = stabs

/* 定义一个变量DEBUG,值为stabs,作用是选择调试格式,可设置的值有stabs [缺省],dwarf-2;

而COFF调试文件要求选择stabs,以插入avr-objcopy文件运行。*/

 

# List any extra directories to look for include files here.

#     Each directory must be seperated by a space.

EXTRAINCDIRS = ./include

/* 定义一个变量EXTRAINCDIRS,值为./include,作用是设置编译器编译时搜索包含文件的路径,可以设置多个,但要用空格分开。

假如上面的foo.c包含了foo.h文件,而foo.h文件在foo.c所在目录的子目录 include中,那么EXTRAINCDIRS 设为 ./include,如果foo.h文件在foo.c所在目录的上一级目录的另一子目录iclude中,EXTRAINCDIRS 应设为 ../include

*/

 

# Compiler flag to set the C Standard level.

# c89   - "ANSI" C

# gnu89 - c89 plus GCC extensions

# c99   - ISO C99 standard (not yet fully implemented)

# gnu99 - c99 plus GCC extensions

CSTANDARD = -std=gnu99

/* 定义一个变量CSTANDARD,值为gnu99,作用是选择编译器版本

*/

 

# Place -D or -U options here

CDEFS =

 

# Place -I options here

CINCS =

/* 定义变量CDEFS和CINCS,值为空,作用是设置编译选项,前面命令gcc –c –g foo.c中–c –g就是编译选项,下面是更多的编译选项: */

 

# Compiler flags.

#  -g*:          generate debugging information    产生调试信息

#  -O*:          optimization level                               优化级别

#  -f...:        tuning, see GCC manual and avr-libc documentation

#  -Wall...:     warning level                                            警告级别

#  -Wa,...:      tell GCC to pass this to the assembler.     传递参数给汇编器

#    -adhlns...: create assembler listing                          创建汇编列表

 

CFLAGS = -g$(DEBUG)

CFLAGS += $(CDEFS) $(CINCS)

CFLAGS += -O$(OPT)

CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums

CFLAGS += -Wall -Wstrict-prototypes

CFLAGS += -Wa,-adhlns=$(<:.c=.lst)

CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))

CFLAGS += $(CSTANDARD)

/* 定义变量CFLAGS,值为-g$(DEBUG),作用是设置编译选项,前面定义了DEBUG = stabs,

所以CFLAGS值应为-g stabs,之后对变量CFLAGS进行追加,完成之后,CFLAGS值为综合的编译选项!

讲下-adhlns=$(<:.c=.lst)的意思:<是一个临时变量,它的值是一些文件的列表,<:.c=.lst就 是把<变量的值中所有.c扩展符替换为.lst,然后再赋予变量-adhlns。

在这里并不打算细致讲解上面是什么意思

*/

 

# Assembler flags.

#  -Wa,...:   tell GCC to pass this to the assembler.          传递参数给汇编器

#  -ahlms:    create listing                                               创建列表

#  -gstabs:   have the assembler create line number information; note that

#             for use in COFF files, additional information about filenames

#             and function names needs to be present in the assembler source

#             files -- see avr-libc docs [FIXME: not yet described there]

#                        大概就是告诉汇编器产生行号、文件名、函数名信息,因为COFF调试文件

#                          要用到

ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs

/*定义变量ASFLAGS,值为-Wa,-adhlns=$(& lt;:.S=.lst),-gstabs,作用是设置汇编选项,基本和上面差不多 */

 

#Additional libraries.

/* 额外库文件配置选项 */

 

# Minimalistic printf version

PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min

/*定义变量PRINTF_LIB_MIN,值为 -Wl,-u,vfprintf -lprintf_min,作用是设置printf版本为迷你版 */

 

# Floating point printf version (requires MATH_LIB = -lm below)

PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt

/*定义变量PRINTF_LIB_FLOAT,值为 -Wl,-u,vfprintf -lprintf_flt,作用是设置printf版本为支持浮点数版 */

 

/* 上面的两个变量其实并不传给编译器,以下的是起作用的,如果要设置printf版本为迷你版,只需要PRINTF_LIB =$( PRINTF_LIB_MIN),下面空着是代表默认的标准版 */

PRINTF_LIB =

 

# Minimalistic scanf version

/* 有printf当然也有scanf,下面是它的配置选项,和printf差不多,跳过 */

SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min

 

# Floating point + %[ scanf version (requires MATH_LIB = -lm below)

SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt

 

SCANF_LIB =

 

/* 下面是数学库的配置选项,定义变量MATH_LIB,值为-lm */

MATH_LIB = -lm

 

# External memory options

/* 下面是外扩内存的配置选项 */

 

# 64 KB of external RAM, starting after internal RAM (ATmega128!),

# used for variables (.data/.bss) and heap (malloc()).

/*

大概就是MCU为ATmega128时,外扩了64 KB的 RAM,如果你想既想用它来做数据区和堆栈区,又想用它来做堆区(动态内存分配),就设置EXTMEMOPTS为这个值

*/

 

#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff

# 64 KB of external RAM, starting after internal RAM (ATmega128!),

# only used for heap (malloc()).

/*

大概就是MCU为ATmega128时,外扩了64 KB的 RAM,仅用它来做堆区(动态内存分配),就设置EXTMEMOPTS为这个值

*/

#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff

/* 一般MCU不扩外部RAM,就让它空着 */

EXTMEMOPTS =

 

# Linker flags.

#  -Wl,...:     tell GCC to pass this to linker.      传给链接器

#    -Map:      create map file                                     建立映射文件

#    --cref:    add cross reference to  map file        增加交叉重映射文件

/* 首先解析一下什么叫编译和链接(一位前辈写的):

一般来说,无论是C、C++、还 是pas,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头 文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。一般来说,每个源文件 都应该对应于一个中间目标文件(O文件或是OBJ文件)。

链接时,主要是链接函数 和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件 (Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给 中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

总结一下,源文件首先会生成中间目标文件,再由中 间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。如果函数未被声明,编译器会给出一个警告,但可以生成Object File。而在链接程序时,链接器会在所有的Object File中找寻函数的实现,如果找不到,那到就会报链接错误码(Linker Error),在VC下,这种错误一般是:Link 2001错误,意思说是说,链接器未能找到函数的实现。你需要指定函数的Object File.

*/

LDFLAGS = -Wl,-Map=$(TARGET).map,--cref

LDFLAGS += $(EXTMEMOPTS)

LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)

/* 定义变量LDFLAGS,作用是设置链接选项,传给链接器,可以看出链接跟内存分布和库有很大关系 */

 

# Programming support using avrdude. Settings and variables.

/* 以下是使用avrdude调试器的编程支持,一般用不上,略过 */

# Programming hardware: alf avr910 avrisp bascom bsd

# dt006 pavr picoweb pony-stk200 sp12 stk200 stk500

#

# Type: avrdude -c ?

# to get a full listing.

#

AVRDUDE_PROGRAMMER = stk500

 

# com1 = serial port. Use lpt1 to connect to parallel port.

AVRDUDE_PORT = com1    # programmer connected to serial device

 

AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex

#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep

 

 

# Uncomment the following if you want avrdude's erase cycle counter.

# Note that this counter needs to be initialized first using -Yn,

# see avrdude manual.

#AVRDUDE_ERASE_COUNTER = -y

 

# Uncomment the following if you do /not/ wish a verification to be

# performed after programming the device.

#AVRDUDE_NO_VERIFY = -V

 

# Increase verbosity level.  Please use this when submitting bug

# reports about avrdude. See <

# to submit bug reports.

#AVRDUDE_VERBOSE = -v -v

 

AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)

AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)

AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)

AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)

 

 

 

# ---------------------------------------------------------------------------

/* 定义目录,一般不需要,略过 */

# Define directories, if needed.

DIRAVR = c:/winavr

DIRAVRBIN = $(DIRAVR)/bin

DIRAVRUTILS = $(DIRAVR)/utils/bin

DIRINC = .

DIRLIB = $(DIRAVR)/avr/lib

 

 

# Define programs and commands.

/* 下面都是定义了一些命令 */

SHELL = sh                                    命令行

CC = avr-gcc                                 gcc编译器的avr 版本(唯一的8位mcu版本)

OBJCOPY = avr-objcopy            链接有关

OBJDUMP = avr-objdump        链接有关

SIZE = avr-size                             文件大小

NM = avr-nm

AVRDUDE = avrdude                 avrdude调试器

REMOVE = rm –f                         这个是删除文件  f前有” –“,代表删除不成功,也不报错

COPY = cp                                     文件复制

 

 

 

 

# Define Messages

# English

/* 下面都是定义了一些消息,编译过程看到的就是这些了!*/

MSG_ERRORS_NONE = Errors: none

MSG_BEGIN = -------- begin --------

MSG_END = --------  end  --------

MSG_SIZE_BEFORE = Size before:

MSG_SIZE_AFTER = Size after:

MSG_COFF = Converting to AVR COFF:

MSG_EXTENDED_COFF = Converting to AVR Extended COFF:

MSG_FLASH = Creating load file for Flash:

MSG_EEPROM = Creating load file for EEPROM:

MSG_EXTENDED_LISTING = Creating Extended Listing:

MSG_SYMBOL_TABLE = Creating Symbol Table:

MSG_LINKING = Linking:

MSG_COMPILING = Compiling:

MSG_ASSEMBLING = Assembling:

MSG_CLEANING = Cleaning project:

 

 

 

 

# Define all object files.

OBJ = $(SRC:.c=.o) $(ASRC:.S=.o)

/* 定义所有中间目标文件,前面讲过$(<:.c=.lst)的意思,这里不再详述,OBJ赋予

$(SRC:.c=.o) $(ASRC:.S=.o) 后,OBJ的值就是一个与C源文件或S汇编文件同名的扩展名为.o为文件列表

 */

 

# Define all listing files.

/* 所有文件列表,和上面的饼是同一个炉出的 */

LST = $(ASRC:.S=.lst) $(SRC:.c=.lst)

 

 

# Compiler flags to generate dependency files.

GENDEPFLAGS = -Wp,-M,-MP,-MT,$(*F).o,-MF,.dep/$(@F).d

/*为自动生成依赖关系而定义的编译选项,

举个例子:

foo.o: foo.c foo.h

         gcc –c –g foo.c

foo.h文件 是个头文件,foo.c是个包含foo.h文件的C源文件,那么是否可写成

foo.o: foo.c

         gcc –c –g foo.c

答案是肯定的,但当foo.h文件改变了时,尽管它的日期比foo.o新,但因foo.o不依赖 foo.h,所以foo.o并不重新生成,只能得到以前的结果,你可能认为foo.c包含了foo.h,foo.h改变了,foo.c文件也会改变,但很 遗憾地告诉你,编译器还没智能到这种程度,你可以做的就只能是先make clean(清除所有的之前生成的中间目标文件)再make all(生成最终目标文件),当文件较多时,这必然带来很多的时间上浪费。

但是要 知道一个中间目标文件间接又依赖于那几个头文件是很困难的,而且也会带来另外的麻烦:当一个C源文件不再包含一个H头文件时,H头文件还在 makefile的某个目标的依赖文件列表里,你还得修改一下makefile——这是一个很没有维护性的工作!

我们可以使用编译器的一个“-M”的选项,即自动寻找源文件中包含的头文件,并生成一个依赖关系。

每一个源文件的依赖关系统都记录在与源文件同名而扩展名为.o的文件里!

*/

 

# Combine all necessary flags and optional flags.

# Add target processor to flags.

/* 前面定义了那么多编译选项,该把它们集中了 */

ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)

ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)

 

# Default target.

all: begin gccversion sizebefore build sizeafter finished end

/* 缺省的all目标,all目标又依赖于很多目标,但是这些依赖目标都是不存在的,结果编译器每次都尝试去建立这些依赖目标,但“我们的目标”并不是all 目标,也不是这些依赖目标,而是这些依赖目标所依赖的目标,请看下面 */

build: elf hex eep lss sym          //build依赖elf目标,

 

elf: $(TARGET).elf                       //elf目标依赖$(TARGET).elf文件!

hex: $(TARGET).hex

eep: $(TARGET).eep

lss: $(TARGET).lss

sym: $(TARGET).sym

 

 

 

# Eye candy.

# AVR Studio 3.x does not check make's exit code but relies on

# the following magic strings to be generated by the compile job.

/*@echo 把它放成C语言中puts函数就可以了,把后面的字符串输出到屏幕*/

begin:

         @echo

         @echo $(MSG_BEGIN)

/* 记住命令要以Tab开头,最后begin并没有生成 */

 

/* 完成时的屏幕输出 */

finished:

         @echo $(MSG_ERRORS_NONE)

 

/* 结束时的屏幕输出 */

end:

         @echo $(MSG_END)

         @echo

 

# Display size of file.

/* 显示文件大小 */

HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex

ELFSIZE = $(SIZE) -A $(TARGET).elf

sizebefore:

         @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); echo; fi

/* 有个if 判断,有点像basic语言,就是文件存在就输出文件大小 */

 

sizeafter:

         @if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi

 

# Display compiler version information.

/* 显示编译器版本 */

gccversion :

         @$(CC) --version

 

# Program the device.

/* 对器件编程,跳过 */

program: $(TARGET).hex $(TARGET).eep

         $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)

 

# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.

/* 转换elf文件为coff,定义了变量COFFCONVERT,有点类似C语言中宏的作用 */

COFFCONVERT=$(OBJCOPY) --debugging \

--change-section-address .data-0x800000 \

--change-section-address .bss-0x800000 \

--change-section-address .noinit-0x800000 \

--change-section-address .eeprom-0x810000

/* 主要是对各段进行重新分布 */

 

/*转换elf文件为 coff */

coff: $(TARGET).elf

         @echo

         @echo $(MSG_COFF) $(TARGET).cof

         $(COFFCONVERT) -O coff-avr $< $(TARGET).cof

 

/*转换elf文件为extcoff */

extcoff: $(TARGET).elf

         @echo

         @echo $(MSG_EXTENDED_COFF) $(TARGET).cof

         $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof

 

# Create final output files (.hex, .eep) from ELF output file.

/*从elf文件中创建hex文件 */

%.hex: %.elf

         @echo

         @echo $(MSG_FLASH) $@

         $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@

 

/*从elf文件中创建eep文件 */

%.eep: %.elf

         @echo

         @echo $(MSG_EEPROM) $@

         -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \

         --change-section-lma .eeprom=0 -O $(FORMAT) $< $@

 

/*从elf文件中创 建Lss文件列表文件 */

# Create extended listing file from ELF output file.

%.lss: %.elf

         @echo

         @echo $(MSG_EXTENDED_LISTING) $@

         $(OBJDUMP) -h -S $< > $@

 

/*从elf文件中创 建sym标号列表文件 */

# Create a symbol table from ELF output file.

%.sym: %.elf

         @echo

         @echo $(MSG_SYMBOL_TABLE) $@

         $(NM) -n $< > $@

 

# Link: create ELF output file from object files.

/* 链接,最为核心之一,把编译过程产生的obj中间生成文件链接在一起 */

.SECONDARY : $(TARGET).elf

.PRECIOUS : $(OBJ)

%.elf: $(OBJ)

         @echo

         @echo $(MSG_LINKING) $@

         $(CC) $(ALL_CFLAGS) $(OBJ) --output $@ $(LDFLAGS)

 

# Compile: create object files from C source files.

/* 编译C源文件,最为核心之一,编译过程将产生的obj中间生成文件,供链接使用 */

%.o : %.c

         @echo

         @echo $(MSG_COMPILING) $<

         $(CC) -c $(ALL_CFLAGS) $< -o $@

 

# Compile: create assembler files from C source files.

/* 编译C源文件为S汇编源文件,最为核心之一*/

%.s : %.c

         $(CC) -S $(ALL_CFLAGS) $< -o $@

 

# Assemble: create object files from assembler source files.

/* 编译S汇编源文件,最为核心之一,编译过程将产生的obj中间生成文件,供链接使用 */

%.o : %.S

         @echo

         @echo $(MSG_ASSEMBLING) $<

         $(CC) -c $(ALL_ASFLAGS) $< -o $@

 

# Target: clean project.

/* clean目标,用于清除工程 */

clean: begin clean_list finished end

 

/*清除工程 */

clean_list :

         @echo

         @echo $(MSG_CLEANING)

         $(REMOVE) $(TARGET).hex

         $(REMOVE) $(TARGET).eep

         $(REMOVE) $(TARGET).obj

         $(REMOVE) $(TARGET).cof

         $(REMOVE) $(TARGET).elf

         $(REMOVE) $(TARGET).map

         $(REMOVE) $(TARGET).obj

         $(REMOVE) $(TARGET).a90

         $(REMOVE) $(TARGET).sym

         $(REMOVE) $(TARGET).lnk

         $(REMOVE) $(TARGET).lss

         $(REMOVE) $(OBJ)

         $(REMOVE) $(LST)

         $(REMOVE) $(SRC:.c=.s)

         $(REMOVE) $(SRC:.c=.d)

         $(REMOVE) .dep/*

 

# Include the dependency files.

/* 包含依赖文件 */

-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)

/*shell mkdir .dep 2>/dev/null好像是删除dep目录,依赖文件*.d都放在dep目录中 */

 

# Listing of phony targets.

/* 告诉Make,all等是伪目标,不管是否有all等文件,都要运行这些目标,生成不了的,不要难过 */

.PHONY : all begin finish end sizebefore sizeafter gccversion \

build elf hex eep lss sym coff extcoff \

clean clean_list program

 

阅读(633) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~