配色: 字号:
makefile最全的说明
2012-08-06 | 阅:  转:  |  分享 
  
#××××××××××××××××××××××××××××××

#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





献花(0)
+1
(本文系小云蔡首藏)