#××××××××××××××××××××××××××××××
#AVR-GCCmakefile模板×
#semilog×
#E-mail:semilog@163.com
#时间:2007年11月9日×
#地点:南京理工大学×
#注:在原来的WinAVR的例程的基础上修改,翻译,注释,并且测试×
#××××××××××××××××××××××××××××××
#HeyEmacs,thisisa--makefile--
#----------------------------------------------------------------------------
#WinAVRMakefileTemplatewrittenbyEricB.Weddington,JoergWunsch,etal.
#
#ReleasedtothePublicDomain
#
#Additionalmaterialforthismakefilewaswrittenby:
#PeterFleury
#TimHenigan
#ColinO''Flynn
#ReinerPatommel
#MarkusPfaff
#SanderPool
#FrederikRouleau
#CarlosLamas
#
#----------------------------------------------------------------------------
#编译操作命令如下:
#
#makeall=编译整个工程.
#
#makeclean=删除所有前一次编译的整个工程所产生的文件
#
#makecoff=转换ELF调试文件到AVR的COFF调试文件.适用于AVRStudio.3.X及以前的版本.
#VMLAB<3.10##makeextcoff=转换ELF调试文件到AVR的ExtendedCOFF调试文件.VMLAT3.10+#适用于AVRStudio.4.07及以后的版本。也就是现在我们要使用的版本#但是好像AVRStdio.4.10及以上的版本开始支持ELF调试文##makeprogram=用avrdude(gnu的avr单片机下载软件)下载hex文件到AVR单片机内,#不要再这之前要先配置好avrdude.注:我们可以用双龙的下载软件等。##makedebug=启动simulavr或avarice进行调试,你用avr-gdb或是avr-insight作的你的调试前端##makefilename.s=单独编译filename.c到汇编文件filename.s.##makefilename.i=通过这个命令进行预编译,来查看GCC工程是否有错.##说了这么多,最有用的就是下面这两句:#makeclean#makeall#这样你的工程就编译完成了。#----------------------------------------------------------------------------
#下面对AVR-GCC参数的说明
#注:关于Makefile的知识网上有很多,看看Makefile的手册
#AVR单片机的名字。这个很重要,不可写错,因为这个参数真接关系到
文件所包含的
文件
#这个
文件包含了所以的对于你所选的AVR单片机的所有引脚和寄存器定义。
#就如keil51中的引用
或
一样
MCU=atmega128
#MCU的运行频率.
#下面是给出的一些典型值:
#F_CPU=1000000
#F_CPU=1843200
#F_CPU=2000000
#F_CPU=3686400
#F_CPU=4000000
#F_CPU=7372800
#F_CPU=8000000
#F_CPU=11059200
#F_CPU=14745600
#F_CPU=16000000
#F_CPU=18432000
#F_CPU=20000000
#在使用
中的延时程序时很有用
F_CPU=7372800
#输出文件格式,对于单片机编程来说,一般我们先intel的hex格式.(可以是:srec,ihex,binary)
FORMAT=ihex
#目标文件名,一般就是你最main()函数所在文件名,也是最后输的hex文年的文件名(不带扩展名).
TARGET=m128
#目标文件的临时目录,就选"obj"这个名子吧,一般不用修改
OBJDIR=obj
#列出你的C语言的工程中的所有的.C源文件名.(C的所有的文件依赖关系会自己动建立,后面会说.)
#对于只有一个源文的工程也可以写成:SRC=$(TARGET).c
SRC=m128.c
#列出你的C++工程中的所有的.cpp源文件名.(C++的所有的文件依赖关系也会自己动建立.)
#对于我们对AVR单片机编程来说,一般我们只用C语言就可以了。所以这里我们什么都不用写
#如果你要用C++也可以,这里你就要配置下。
CPPSRC=
#列出你的工程中的所有的汇编源程序
#记住要用大写.S保存你的汇编文件名,不要用小写的.s。要不然AVR-GCC不认为它是个汇编源文件
#而且在执行makeclean时也删除.s的文件,因为它会认为是编译C文件生成的汇编过程文件
ASRC=
#AVR-GCC代码优化级别,选项:[0,1,2,3,s].级别越高,优化程度越大
#0=不优化.s=2+优化代码大小,3优化并不总是最好的.使用-O时表示-O1;
OPT=s
#调试文件格式.
#如果是用Winavr的GDB调试的话选dwarf-2[默认]或者stabs也行。
#从AVRStudio4.10(我不知道是不是从这个版本开始,反正4.12是可以的)
#开始AVRStudio已开始支持ELF/DWARF的调试文件,所以这时你可以选dwarf-2.
#编译你的工程然后开始调试,我测试过,而且在AVRStudio4.12的帮助文档中找到了
#AVRStudio目前支持的DebuggingFile的说明,你们也可以自己去看一下。
#当然AVR[Extended]COFF格式还是支持,不过你要在编译时在这里选stabs选项
#然后在用"makeall"编译后再用"makeextcoff"调用avr-objcopy生成[Extended]COFF.
#这时你会觉得有点烦,呵呵。那就选dwarf-2选项吧,不用动它就可以了
DEBUG=dwarf-2
#列出你的用#include包含的.h头文件的目录.make会在当前目录或标准库的目录找不到时
#到这个目录在寻找例:EXTRAINCDIRS=c:\m128\inc如果是makefile当前目内的子目录inc
#那么就直接写EXTRAINCDIRS=inc.如果有多个目录,中间用空格隔开。都在一个目录就不用写
EXTRAINCDIRS=
#编译标记,用来选标准C的级别,一般不用动
#c89="ANSI"C
#gnu89=c89plusGCCextensions
#c99=ISOC99standard(还没有完全完成)
#gnu99=c99plusGCCextensions
CSTANDARD=-std=gnu99
#在C语言源文件前面加上-Dor-U选项(具体什么意思我还没有弄明白)
CDEFS=-DF_CPU=$(F_CPU)UL
#这个和上面的说明一样,不过是对于C++文件的
CPPDEFS=-DF_CPU=$(F_CPU)UL
#-----------------------C编译选项-------------------------------
#-g:产生调试信息
#-O:代码优代级别
#-f...:用于改变内建一些默认的函数,具体的看avr-libc手册
#-Wall..:警告的级别
#-Wa,...:告诉GCC后面的选项不用管,把它传给汇编选项.
#-Wl,...:和-Wa选项差不多,告诉GCC传递后面的选项给liker链接器.
#-a[cdhlmns=file]:创建汇编列表文件,默认的一般选-adhlns
#子选项如下:
#c省略错误的条件
#d省略调试的指令
#h包含最高层的源文件
#l包含汇编文件
#m包含宏的展开
#n省略处理的框架(formsprocessing)(我不知是什么意思)
#s包含标号
#=file设置生成的汇编列表文件的文件名,可以包含目录名用"/"隔开.
#-------------------------集合所有C编译选项到变量CFLAGS中-------------------
#DUBUG选项
CFLAGS=-g$(DEBUG)
#CPU时钟频率
CFLAGS+=$(CDEFS)
#优化级别
CFLAGS+=-O$(OPT)
#把int当成8-bitinteger,avr-libc并不真的支持,所以一般不要用.
#CFLAGS+=-mint8
#在大于8K单片机使用rjmp/rcall(默认情况用jmp/call)
#CFLAGS+=-mshort-calls
#这个选项会关掉自动内建的函数(但是可以在实际使用的函数前加上__builtin_)
#当你使用这个参数时,voidmain()不出现警告
#这个参数同时也会影响你的代码的优化,使代码增加。一般不使用就可以了。
#更多的说明请参考avr-libc说明。
#CFLAGS+=-ffreestanding
#编译器总认为char=unsignedchar
CFLAGS+=-funsigned-char
#当你定义一个位变量bit区时,总认为它是unsignedbitfields,所以定义aa:4=unsignedaa:4
CFLAGS+=-funsigned-bitfields
#定义结构体的时候,使里面的每一个元素的存储空间都是连续,一个接一个存,中间没有存储间隔
CFLAGS+=-fpack-struct
#定义枚举类型的时候,使用里面存储空间最大的一个变量作为整个枚举变量的存储空间
CFLAGS+=-fshort-enums
#在制作执行文件前分析整个编译单位。提供某些额外最佳化套用的机会,但会使用更多内存。
#这个参数我也不知是什么意思。不用它吧。
#CPPFLAGS+=-fno-unit-at-a-time
#很多警告的集合,具体参见GCC手册
CFLAGS+=-Wall
#如果函数的声明或定义没有指出参数类型,编译器就发出警告
CFLAGS+=-Wstrict-prototypes
#如果使用未定义宏,则进行警告
CFLAGS+=-Wundef
#对程序中没有使用的代码作出警告
#CFLAGS+=-Wunreachable-code
#在有符号数和无符号数进行值比较时,有符号数可能在比较之前被转换为无符号数而导致结果错误
#CFLAGS+=-Wsign-compare
#创建汇编列表文件,$(<:%.c=$(OBJDIR)/%.lst)的意思是把"<"表示的目标的#所有.c文件换成.lst文件,作为输出lst文件的文件名CFLAGS+=-Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
#这句的意思是在$(EXTRAINCDIRS)定义目录变量中,为每一个用空格隔开的目录前加上-I
CFLAGS+=$(patsubst%,-I%,$(EXTRAINCDIRS))
#标准C的级别
CFLAGS+=$(CSTANDARD)
#---------------------------C编译选项CFLAGS结束---------------------------
#----------------下面是C++的编译选项(见C编译选顶,不重复说了)-------------
#-g:generatedebugginginformation
#-O:optimizationlevel
#-f...:tuning,seeGCCmanualandavr-libcdocumentation
#-Wall...:warninglevel
#-Wa,...:tellGCCtopassthistotheassembler.
#-adhlns...:createassemblerlisting
CPPFLAGS=-g$(DEBUG)
CPPFLAGS+=$(CPPDEFS)
CPPFLAGS+=-O$(OPT)
#CPPFLAGS+=-mint8
#CPPFLAGS+=-mshort-calls
CPPFLAGS+=-funsigned-char
CPPFLAGS+=-funsigned-bitfields
CPPFLAGS+=-fpack-struct
CPPFLAGS+=-fshort-enums
CPPFLAGS+=-fno-exceptions
#CPPFLAGS+=-fno-unit-at-a-time
CPPFLAGS+=-Wall
#CPPFLAGS+=-Wstrict-prototypes
CPPFLAGS+=-Wundef
#CPPFLAGS+=-Wunreachable-code
#CPPFLAGS+=-Wsign-compare
CPPFLAGS+=-Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)CPPFLAGS+=$(patsubst%,-I%,$(EXTRAINCDIRS))#CPPFLAGS+=$(CSTANDARD)#---------------------------C++编译选项CFLAGS结束-------------------------
#----------------AssemblerOptions----------------
#-Wa,...:告诉GCC后面的选项不用管,把它传给汇编选项..
#-ahlms:创建列表文件
#-gstabs:stabsdebuggingsymbolsforassemblersourcelines.
#Thisenablesavr-gdbtotracethroughassemblersourcefiles
#当源文件中由C编译产生的.s汇编文件时不要用这个选项,因为
#其已包含了合适的行信息。
#ASMFLAGS+=-xassembler-with-cpp-Wa,-gdwarf2#汇编文件由C产生时用
ASFLAGS=-Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs
#---------------------------------有关库的选项-------------------------------
#printf函数最小的版本
PRINTF_LIB_MIN=-Wl,-u,vfprintf-lprintf_min
#标准printf还加上Floatingpoint(requiresMATH_LIB=-lmbelow)
PRINTF_LIB_FLOAT=-Wl,-u,vfprintf-lprintf_flt
#如果PRINTF_LIB不写为空,那么gcc-libc就使用标准版的printf函数.
PRINTF_LIB=
#PRINTF_LIB=$(PRINTF_LIB_MIN)
#PRINTF_LIB=$(PRINTF_LIB_FLOAT)
#最小的scanf函数的版本
SCANF_LIB_MIN=-Wl,-u,vfscanf-lscanf_min
#Floatingpoint+%[scanfversion(requiresMATH_LIB=-lmbelow)
SCANF_LIB_FLOAT=-Wl,-u,vfscanf-lscanf_flt
#Ifthisisleftblank,thenitwillusetheStandardscanfversion.
SCANF_LIB=
#SCANF_LIB=$(SCANF_LIB_MIN)
#SCANF_LIB=$(SCANF_LIB_FLOAT)
#-l[lib-name]库名去掉lib和.a后缀如libm.a则写成-lm如下所示:
MATH_LIB=-lm
#----------------------外部存储器选项---------------------------
#关于--defsym的说明
#--defsymsymbol=expr#定义一个全局的标志,用expr作为symbol的值.
#-Tbssorg
#-Tdataorg
#-Ttextorg
#64KBofexternalRAM,startingafterinternalRAM(ATmega128!),
#64KB的外部扩展的RAM,地址接在内部RAM后面
#usedforvariables(.data/.bss)andheap(malloc()).
#变量(.data/.bss)还有heap(malloc()),都使用这个区不用内部RAM
#前面加上0x800000表示是RAM数据区,而不是程序区,因为AVR是哈弗结构
#EXTMEMOPTS=-Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
#64KBofexternalRAM,startingafterinternalRAM(ATmega128!),
#外部RAM只用作heap区,供malloc()分配的空间存储,变量(.data/.bss)仍在内部RAM.
#EXTMEMOPTS=-Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS=-Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x807fff
#显示地注明堆栈最高地址,也就是栈顶地址,C语言堆栈是向下生长,一般定义在RAM的尾部
EXTMEMOPTS+=-minit-stack=0x1100
#----------------链接选项LDFLAGS----------------
#-Wl,...:告诉GCC传递后面的选项给liker链接器.
#-Map:创建map文件
#--cref:把对照信息加到map文件中
LDFLAGS=-Wl,-Map=$(TARGET).map,--cref
LDFLAGS+=$(EXTMEMOPTS)
LDFLAGS+=$(PRINTF_LIB)$(SCANF_LIB)$(MATH_LIB)
#链接器使用linker_script.x脚本,avr-gcc自带脚本存在WinAVR\avr\lib\ldscripts下
#LDFLAGS+=-Tlinker_script.x
#----------------编程下载选项(avrdude)----------------
#用到少,我就不翻译了,而且也很简单。
#Programminghardware:alfavr910avrispbascombsd
#dt006pavrpicowebpony-stk200sp12stk200stk500
#
#Type:avrdude-c?
#togetafulllisting.
#
AVRDUDE_PROGRAMMER=stk500
#com1=serialport.Uselpt1toconnecttoparallelport.
AVRDUDE_PORT=com1#programmerconnectedtoserialdevice
AVRDUDE_WRITE_FLASH=-Uflash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM=-Ueeprom:w:$(TARGET).eep
#Uncommentthefollowingifyouwantavrdude''serasecyclecounter.
#Notethatthiscounterneedstobeinitializedfirstusing-Yn,
#seeavrdudemanual.
#AVRDUDE_ERASE_COUNTER=-y
#Uncommentthefollowingifyoudo/not/wishaverificationtobe
#performedafterprogrammingthedevice.
#AVRDUDE_NO_VERIFY=-V
#Increaseverbositylevel.Pleaseusethiswhensubmittingbug
#reportsaboutavrdude.See
#tosubmitbugreports.
#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)
#---------------------调试选项--------------------
#Forsimulavronly-targetMCUfrequency.
#MCU的频率(onlyforsimulavr)
DEBUG_MFREQ=$(F_CPU)
#SettheDEBUG_UItoeithergdborinsight.
#DEBUG_UI=gdb
DEBUG_UI=insight
#Setthedebuggingback-endtoeitheravarice,simulavr.
DEBUG_BACKEND=avarice
#DEBUG_BACKEND=simulavr
#GDBInitFilename.
GDBINIT_FILE=__avr_gdbinit
#WhenusingavaricesettingsfortheJTAG
JTAG_DEV=/dev/com1
#DebuggingportusedtocommunicatebetweenGDB/avarice/simulavr.
DEBUG_PORT=4242
#DebugginghostusedtocommunicatebetweenGDB/avarice/simulavr,normally
#justsettolocalhostunlessdoingsomesortofcrazydebuggingwhen
#avariceisrunningonadifferentcomputer.
DEBUG_HOST=localhost
#============================================================================
#---------------定义编译软件和命令的别名,便于移植--------------------
SHELL=sh
CC=avr-gcc
#----------------------复制和翻译目标文件成其他的格式,如:elf->ihex
OBJCOPY=avr-objcopy
#----------------------avr-objdump显示关于目标文件和汇编文件的一些信息
OBJDUMP=avr-objdump
SIZE=avr-size
#----------------------avr-nm从目标文件中列出所有标号
NM=avr-nm
AVRDUDE=avrdude
REMOVE=rm-f
#----------------------删除目标及目录内文件
REMOVEDIR=rm-rf
COPY=cp
WINSHELL=cmd
#-------------------定义一些用于编译时显示的信息-------------------
#English(英文)
MSG_ERRORS_NONE=Errors:none
MSG_BEGIN=--------begin--------
MSG_END=--------end--------
MSG_SIZE_BEFORE=Sizebefore:
MSG_SIZE_AFTER=Sizeafter:
MSG_COFF=ConvertingtoAVRCOFF:
MSG_EXTENDED_COFF=ConvertingtoAVRExtendedCOFF:
MSG_FLASH=CreatingloadfileforFlash:
MSG_EEPROM=CreatingloadfileforEEPROM:
MSG_EXTENDED_LISTING=CreatingExtendedListing:
MSG_SYMBOL_TABLE=CreatingSymbolTable:
MSG_LINKING=Linking:
MSG_COMPILING=CompilingC:
MSG_COMPILING_CPP=CompilingC++:
MSG_ASSEMBLING=Assembling:
MSG_CLEANING=Cleaningproject:
MSG_CREATING_LIBRARY=Creatinglibrary:
#定义所有的目标文件.
OBJ=$(SRC:%.c=$(OBJDIR)/%.o)$(CPPSRC:%.cpp=$(OBJDIR)/%.o)$(ASRC:%.S=$(OBJDIR)/%.o)
#定义所有的listing文件.
LST=$(SRC:%.c=$(OBJDIR)/%.lst)$(CPPSRC:%.cpp=$(OBJDIR)/%.lst)$(ASRC:%.S=$(OBJDIR)/%.lst)
#编译选项,用来生成所有的依赖文件.-MF用于指定写入的.d的文件名,-MMD不包系统头文件名
GENDEPFLAGS=-MD-MP-MF.dep/$(@F).d
#合并所有需要的flags和可选项的flags
#并且把MCU型号加入到flags中.
ALL_CFLAGS=-mmcu=$(MCU)-I.$(CFLAGS)$(GENDEPFLAGS)
ALL_CPPFLAGS=-mmcu=$(MCU)-I.-xc++$(CPPFLAGS)$(GENDEPFLAGS)
ALL_ASFLAGS=-mmcu=$(MCU)-I.-xassembler-with-cpp$(ASFLAGS)
#默认的目标,也就是Makefile中出现的第一个目标.
all:begingccversionsizebeforebuildsizeafterend
#把编译工程生成的目标文件转换成.HEX文件或是.a库文件等等.默认不生成库文件
build:elfhexeeplsssym
#build:lib
elf:$(TARGET).elf
hex:$(TARGET).hex
eep:$(TARGET).eep
lss:$(TARGET).lss
sym:$(TARGET).sym
LIBNAME=lib$(TARGET).a
lib:$(LIBNAME)
#Eyecandy.
#AVRStudio3.x不会检查make退出的代码,但是却依赖下面的字符串
#echo是用来显示的命令,和DOS中的命令不一样,不是一个显示开关。
begin:
@echo
@echo$(MSG_BEGIN)
end:
@echo$(MSG_END)
@echo
#显示各个文件的大小
HEXSIZE=$(SIZE)--target=$(FORMAT)$(TARGET).hex
ELFSIZE=$(SIZE)-A$(TARGET).elf
AVRMEM=avr-mem.sh$(TARGET).elf$(MCU)
sizebefore:
@iftest-f$(TARGET).elf;thenecho;echo$(MSG_SIZE_BEFORE);$(ELFSIZE);\
$(AVRMEM)2>/dev/null;echo;fi
sizeafter:
@iftest-f$(TARGET).elf;thenecho;echo$(MSG_SIZE_AFTER);$(ELFSIZE);\
$(AVRMEM)2>/dev/null;echo;fi
#显示avr-gcc的版本信息.
gccversion:
@$(CC)--version
#下载程序到目标MCU
program:$(TARGET).hex$(TARGET).eep
$(AVRDUDE)$(AVRDUDE_FLAGS)$(AVRDUDE_WRITE_FLASH)$(AVRDUDE_WRITE_EEPROM)
#生成avr-gdb配置/初始化文件,主要按下面来做:
#定义复位信号,加载目标文件,连接目标,把断点设置在main()函数
gdb-config:
@$(REMOVE)$(GDBINIT_FILE)
@echodefinereset>>$(GDBINIT_FILE)
@echoSIGNALSIGHUP>>$(GDBINIT_FILE)
@echoend>>$(GDBINIT_FILE)
@echofile$(TARGET).elf>>$(GDBINIT_FILE)
@echotargetremote$(DEBUG_HOST):$(DEBUG_PORT)>>$(GDBINIT_FILE)
ifeq($(DEBUG_BACKEND),simulavr)
@echoload>>$(GDBINIT_FILE)
endif
@echobreakmain>>$(GDBINIT_FILE)
debug:gdb-config$(TARGET).elf
ifeq($(DEBUG_BACKEND),avarice)
@echoStartingAVaRICE-Pressenterwhen"waitingtoconnect"messagedisplays.
@$(WINSHELL)/cstartavarice--jtag$(JTAG_DEV)--erase--program--file\
$(TARGET).elf$(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL)/cpause
else
@$(WINSHELL)/cstartsimulavr--gdbserver--device$(MCU)--clock-freq\
$(DEBUG_MFREQ)--port$(DEBUG_PORT)
endif
@$(WINSHELL)/cstartavr-$(DEBUG_UI)--command=$(GDBINIT_FILE)
#把ELF文件转换成COFF文件,供AVRStudio或VMLAB调试与仿真.
COFFCONVERT=$(OBJCOPY)--debugging
COFFCONVERT+=--change-section-address.data-0x800000
COFFCONVERT+=--change-section-address.bss-0x800000
COFFCONVERT+=--change-section-address.noinit-0x800000
COFFCONVERT+=--change-section-address.eeprom-0x810000
coff:$(TARGET).elf
@echo
@echo$(MSG_COFF)$(TARGET).cof
$(COFFCONVERT)-Ocoff-avr$<$(TARGET).cof
extcoff:$(TARGET).elf
@echo
@echo$(MSG_EXTENDED_COFF)$(TARGET).cof
$(COFFCONVERT)-Ocoff-ext-avr$<$(TARGET).cof
#通过输出的ELF文件创建最终的(.hex,.eep)文件.
%.hex:%.elf
@echo
@echo$(MSG_FLASH)$@
$(OBJCOPY)-O$(FORMAT)-R.eeprom$<$@%.eep:%.elf@echo@echo$(MSG_EEPROM)$@-$(OBJCOPY)-j.eeprom--set-section-flags=.eeprom="alloc,load"\--change-section-lma.eeprom=0-O$(FORMAT)$<$@
#通过ELF文件创建扩展的列表文件.
%.lss:%.elf
@echo
@echo$(MSG_EXTENDED_LISTING)$@
$(OBJDUMP)-h-S$<>$@
#通过ELF文件创建列表文件
%.sym:%.elf
@echo
@echo$(MSG_SYMBOL_TABLE)$@
$(NM)-n$<>$@
#通过.o目标文件创建.a库文
.SECONDARY:$(TARGET).a
.PRECIOUS:$(OBJ)
%.a:$(OBJ)
@echo
@echo$(MSG_CREATING_LIBRARY)$@
$(AR)$@$(OBJ)
#链接:通过.o目标文件创建ELF文件
.SECONDARY:$(TARGET).elf
.PRECIOUS:$(OBJ)
%.elf:$(OBJ)
@echo
@echo$(MSG_LINKING)$@
$(CC)$(ALL_CFLAGS)$^--output$@$(LDFLAGS)
#编译:编译C源文件创建.o目标文件
$(OBJDIR)/%.o:%.c
@echo
@echo$(MSG_COMPILING)$<$(CC)-c$(ALL_CFLAGS)$<-o$@
#编译:编译C++源文件创建.o目标文件
$(OBJDIR)/%.o:%.cpp
@echo
@echo$(MSG_COMPILING_CPP)$<$(CC)-c$(ALL_CPPFLAGS)$<-o$@
#编译:编译C源文件创建.s汇编文件
%.s:%.c
$(CC)-S$(ALL_CFLAGS)$<-o$@
#编译:编译C++源文件创建.s汇编文件
%.s:%.cpp
$(CC)-S$(ALL_CPPFLAGS)$<-o$@
#汇编:编译.S汇编源文件创建.o目标文件(必须大写"S"作后缀)
$(OBJDIR)/%.o:%.S
@echo
@echo$(MSG_ASSEMBLING)$<$(CC)-c$(ALL_ASFLAGS)$<-o$@
#只对源文件进行预处理,查看是源文件是否有错
%.i:%.c
$(CC)-E-mmcu=$(MCU)-I.$(CFLAGS)$<-o$@
#目标:清除整个工程,便于下次编译
clean:beginclean_listend
clean_list:
@echo
@echo$(MSG_CLEANING)
$(REMOVE)$(TARGET).hex
$(REMOVE)$(TARGET).eep
$(REMOVE)$(TARGET).cof
$(REMOVE)$(TARGET).elf
$(REMOVE)$(TARGET).map
$(REMOVE)$(TARGET).sym
$(REMOVE)$(TARGET).lss
$(REMOVEDIR)$(OBJDIR)
$(REMOVE)$(SRC:.c=.s)
$(REMOVE)$(SRC:.c=.d)
$(REMOVEDIR).dep
#创建用于存目标文件的目录$(OBJDIR)
$(shellmkdir$(OBJDIR)2>/dev/null)
#包含依赖文件
-include$(shellmkdir.dep2>/dev/null)$(wildcard.dep/)
#把所有的目标都定义成伪目标,伪目标的特性总是被执行
.PHONY:allbeginfinishendsizebeforesizeaftergccversion\
buildelfhexeeplsssymcoffextcoff\
cleanclean_listprogramdebuggdb-config
|
|