Makefile格式范本
Linux学习:Makefile简介及模板
Linux学习:Makefile简介及模板⼀、基本概念介绍: Makefile ⽂件就是告诉make命令需要怎么样的去编译和链接程序。
编写Makefile的基本规则: 1.如果这个⼯程没有编译过,那么我们的所有C⽂件都要编译并被链接。
2.如果这个⼯程的某⼏个C⽂件被修改,那么我们只编译被修改的C⽂件,并链接⽬标程序。
3.如果这个⼯程的头⽂件被改变了,那么我们需要编译引⽤了这⼏个头⽂件的C⽂件,并链接⽬标程序。
$@--⽬标⽂件,$^--所有的依赖⽂件,$<--第⼀个依赖⽂件。
1 直观⽅式 举个例⼦:⼀个⼯程有3个头⽂件,和8个C⽂件,根据规则编写Makefile如下:edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.omain.o : main.c defs.hcc -c main.ckbd.o : kbd.c defs.h command.hcc -c kbd.ccommand.o : command.c defs.h command.hcc -c command.cdisplay.o : display.c defs.h buffer.hcc -c display.cinsert.o : insert.c defs.h buffer.hcc -c insert.csearch.o : search.c defs.h buffer.hcc -c search.cfiles.o : files.c defs.h buffer.h command.hcc -c files.cutils.o : utils.c defs.hcc -c utils.cclean :rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o 在这个makefile中,⽬标⽂件(target)包含:可执⾏⽂件 edit 和中间⽬标⽂件(*.o),依赖⽂件(prerequisites)就是冒号后⾯的那些 .c ⽂件和 .h⽂件。
linux:几个常用makefile模板
linux:⼏个常⽤makefile模板不才,总结个⼈常⽤makefile模板,以备后⽤。
1、编译动态库[plain]1. #############################################################2. # Makefile for shared library.3. # 编译动态链接库4. #############################################################5. #set your own environment option6. CC = g++7. CC_FLAG = -D_NOMNG -D_FILELINE8.9. #set your inc and lib10. INC =11. LIB = -lpthread -L./ -lsvrtool12.13. #make target lib and relevant obj14. PRG = libsvrtool.so15. OBJ = Log.o16.17. #all target18. all:$(PRG)19.20. $(PRG):$(OBJ)21. $(CC) -shared -o $@ $(OBJ) $(LIB)22.23. .SUFFIXES: .c .o .cpp24. .cpp.o:25. $(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o26.27. .PRONY:clean28. clean:29. @echo "Removing linked and compiled files......;30. rm -f $(OBJ) $(PRG)2、编译静态库[plain]1. #############################################################2. # Makefile for static library.3. # 编译静态链接库4. #############################################################5. #set your own environment option6. CC = g++7. CC_FLAG = -D_NOMNG -D_FILELINE8.9. #static library use 'ar' command10. AR = ar11.12. #set your inc and lib13. INC =14. LIB = -lpthread -L./ -lsvrtool15.16. #make target lib and relevant obj17. PRG = libsvrtool.a18. OBJ = Log.o19.20. #all target21. all:$(PRG)22. $(PRG):$(OBJ)23. ${AR} rv ${PRG} $?24.25. .SUFFIXES: .c .o .cpp26. .cpp.o:27. $(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o28.29. .PRONY:clean30. clean:31. @echo "Removing linked and compiled files......"32. rm -f $(OBJ) $(PRG)3、可执⾏程序[plain]1. ###########################################2. #Makefile for simple programs3. ###########################################4. INC=5. LIB= -lpthread6.7. CC=CC8. CC_FLAG=-Wall9.10. PRG=threadpooltest11. OBJ=CThreadManage.o CThreadPool.o CThread.o CWorkerThread.o threadpooltest.o12.13. $(PRG):$(OBJ)14. $(CC) $(INC) $(LIB) -o $@ $(OBJ)15.16. .SUFFIXES: .c .o .cpp17. .cpp.o:18. $(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o19.20. .PRONY:clean21. clean:22. @echo "Removing linked and compiled files......"23. rm -f $(OBJ) $(PRG)随机组合、举⼀反三会写出适合项⽬的makefile。
【最新】makefile范例-word范文 (23页)
本文部分内容来自网络整理,本司不为其真实性负责,如有异议或侵权请及时联系,本司将立即删除!== 本文为word格式,下载后可方便编辑和修改! ==makefile范例篇一:实例—使用make及Makefile文件2.3 实例—使用make及Makefile文件一个工程有3个头文件(head1.h、head2.h、exam2.h)和8个C文件(main.c、exam1.c、exam2.c、exam3.c、exam4.c、exam5.c、exam6.c、exam7.c),建立一个Makefile文件(文件名为makefile),内容如下。
注意,上述12个文件位于同一个目录中。
gcc -o example main.o exam1.o exam2.o exam3.o exam4.o exam5.o exam6.o exam7.omain.o : main.c head1.hgcc -c main.cexam1.o : exam1.c head1.h exam2.hgcc -c exam1.cexam2.o : exam2.c head1.h exam2.hgcc -c exam2.cexam3.o : exam3.c head1.h head2.hgcc -c exam3.cexam4.o : exam4.c head1.h head2.hgcc -c exam4.cexam5.o : exam5.c head1.h head2.hgcc -c exam5.cexam6.o : exam6.c head1.h head2.h exam2.hgcc -c exam6.cexam7.o : exam7.c head1.hgcc -c exam7.cclean :rm example main.o exam1.o exam2.o exam3.o exam4.o exam5.o exam6.o exam7.omakefile文件告诉make命令如何编译和链接这几个文件。
一些通用的makefile模板
一些通用的makefile模板
以下是一个简单的通用Makefile模板,用于编译C/C++程序: Makefile.
# 定义编译器。
CC = gcc.
CXX = g++。
# 定义编译选项。
CFLAGS = -Wall.
CXXFLAGS = -Wall.
# 定义链接选项。
LDFLAGS =。
# 定义目标文件。
TARGET = program.
# 定义源文件。
SRCS = main.c file1.c file2.c. # 生成目标文件列表。
OBJS = $(SRCS:.c=.o)。
# 默认目标。
all: $(TARGET)。
# 生成可执行文件。
$(TARGET): $(OBJS)。
$(CC) $(LDFLAGS) -o $@ $^。
# 生成目标文件。
%.o: %.c.
$(CC) $(CFLAGS) -c -o $@ $<。
# 清理生成的文件。
clean:
rm -f $(OBJS) $(TARGET)。
这个模板包含了常见的Makefile设置,包括了编译器的定义、编译选项、链接选项、目标文件、源文件、生成目标文件和可执行文件的规则,以及清理生成文件的规则。
你可以根据自己的需求对其进行调整和扩展。
makefile的模式规则
Makefile中的模式规则是一种特殊的规则,它允许你使用模式来匹配目标文件,然后根据匹配结果执行相应的命令。
模式规则中的目标文件名包含一个模式字符“%”,该字符可以匹配任何非空字符串。
在模式规则中,目标文件是一个带有模式字符“%”的文件,使用模式来匹配目标文件。
一旦依赖目标中的“%”模式被确定,make 会被要求去匹配当前目录下所有的文件名,一旦找到,make就会执行规则下的命令。
在模式规则中,目标可能会是多个的,如果有模式匹配出多个目标,make就会产生所有的模式目标。
此时,make关心的是依赖的文件名和生成目标的命令这两件事。
以下是一个简单的Makefile模式规则示例:
```makefile
%.o : %.c
$(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@
```
这个规则表示将所有的.c文件编译成.o文件。
其中,“$<”表示了所有依赖目标的挨个值,“$@”表示了所有目标的挨个值。
这些自动化变量将在后面的章节中详细讲述。
总的来说,Makefile的模式规则是一种强大的工具,它可以根据文件名模式自动构建目标文件,并执行相应的命令。
makefile文件语法规则
makefile文件语法规则Makefile文件的基本语法规则包括以下几点:1. 注释:以井号(#)开头的行被视为注释,不会被执行。
2. 规则:每条规则由一个目标文件和一组依赖文件组成,以及一个用于构建目标文件的命令。
规则的格式如下:Css:目标文件:依赖文件命令目标文件和依赖文件之间用冒号(:)分隔,命令部分指定了如何从依赖文件生成目标文件。
3. 变量:Makefile中可以使用变量来存储值,变量的值可以包含文本、空格、数字等。
变量名以美元符号($)开头,例如:Makefile:VAR = value命令= $VAR4. 函数:Makefile支持使用函数来执行更复杂的操作。
函数的语法如下:Scss:函数名(参数)Makefile中内置了一些常用的函数,如字符串操作函数、条件判断函数等。
也可以自定义函数。
5. 通配符:Makefile中可以使用通配符来匹配多个文件,常见的通配符有“*”和“?”。
例如,“*.c”表示匹配所有以“.c”结尾的文件,“a?b”表示匹配“ab”、“axb”、“ayb”等字符串。
6. 回声:在Makefile中,命令前面加上“@”符号可以关闭回声,即不会在执行命令时显示该命令。
例如:Makefile:@echo Hello, world!这条命令执行时不会输出“Hello, world!”的文本。
7. 模式规则:Makefile中的模式规则允许根据一组通配符匹配的文件来定义规则,格式如下:Makefile:模式:目标文件命令1命令2模式匹配的文件将按照指定的命令构建目标文件。
WinAVR(GCC)新手入门的makefile范例
WinAVR(GCC)新手入门的makefile范例#这是一个简单makefile,仅用于初学者使用#修改于WINAVR20050214所生成的makefile#简单实验只需更改[单片机类型][目标文件名][C源文件名][系统时钟频率]即可#修改好参数后另存到单片机程序所在目录,然后执行[make all]命令#生成烧录FLASH的*.hex,烧录EEPROM的*.eep,调试用的*.elf 文件##MCU name# 单片机类型参考格式是:atmega8 / at90s2313 / attiny15MCU = atmega16# Processor frequency.# 系统时钟频率(Hz),用于生成延时_delay_us() _delay_ms() 见delay.h# This will define a symbol, F_CPU, in all source code files equal to the# processor frequency. You can then use this symbol in your source code to# calculate timings. Do NOT tack on a 'UL' at the end, this will be done# automatically to create a 32-bit value in your source code.F_CPU = 1000000# Target file name (without extension).# 目标文件名(即生成的.hex/.eep/.elf的文件名)TARGET = main# List C source files here. (C dependencies are automatically generated.)# C源文件名(不带路径)# 多个文件名间用空格隔开例如SRC = file1.c file2.c file3.c# 不需要加上h头文件SRC = $(TARGET).c#**************后面内容基本不需要修改,除非你是老手*****************************## Output format. (can be srec, ihex, binary)# 输出烧录文件格式FORMAT = ihex# 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# Debugging format.# 输出调试格式# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.# AVR Studio 4.10 requires dwarf-2.# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.DEBUG = dwarf-2# List Assembler source files here.# 汇编源文件名(不带路径,但扩展名 .sS 需大写,否则将会被make clean 所误删)# 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 =# Hey Emacs, this is a -*- makefile -*-#----------------------------------------------------------------------------# WinAVR Makefile Template written by Eric B. Weddington, J鰎g Wunsch, et al.## Released to the Public Domain## Additional material for this makefile was written by:# Peter Fleury# Tim Henigan# Colin O'Flynn# Reiner Patommel# Markus Pfaff# Sander Pool# Frederik Rouleau##----------------------------------------------------------------------------# On command line:## make all = Make software.## make clean = Clean out built project files.## make coff = Convert ELF to AVR COFF.## make extcoff = Convert ELF to AVR Extended COFF.## make program = Download the hex file to the device, using avrdude.# Please customize the avrdude settings below first!## make debug = Start either simulavr or avarice as specified for debugging, # with avr-gdb or avr-insight as the front end for debugging.## make filename.s = Just compile filename.c into the assembler code only. ## make filename.i = Create a preprocessed source file for use in submitting # bug reports to the GCC project.## To rebuild project do "make clean" then "make all".#----------------------------------------------------------------------------# List any extra directories to look for include files here.# Each directory must be seperated by a space.# Use forward slashes for directory separators.# For a directory that has spaces, enclose it in quotes. EXTRAINCDIRS =# 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 extensionsCSTANDARD = -std=gnu99# Place -D or -U options hereCDEFS = -DF_CPU=$(F_CPU)UL# Place -I options hereCINCS =#---------------- Compiler Options ----------------# -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 listingCFLAGS = -g$(DEBUG)CFLAGS += $(CDEFS) $(CINCS)CFLAGS += -O$(OPT)CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums CFLAGS += -Wall -Wstrict-prototypesCFLAGS += -Wa,-adhlns=$(<:.c=.lst)CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))CFLAGS += $(CSTANDARD)#---------------- Assembler Options ----------------# -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]ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs#---------------- Library Options ----------------# Minimalistic printf versionPRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min# Floating point printf version (requires MATH_LIB = -lm below)PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt# If this is left blank, then it will use the Standard printf version.PRINTF_LIB =#PRINTF_LIB = $(PRINTF_LIB_MIN)#PRINTF_LIB = $(PRINTF_LIB_FLOAT)# Minimalistic scanf versionSCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min# Floating point + %[ scanf version (requires MATH_LIB = -lm below)SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt# If this is left blank, then it will use the Standard scanf version.SCANF_LIB =#SCANF_LIB = $(SCANF_LIB_MIN)#SCANF_LIB = $(SCANF_LIB_FLOAT)MATH_LIB = -lm#---------------- External Memory Options ----------------# 64 KB of external RAM, starting after internal RAM (ATmega128!),# used for variables (.data/.bss) and heap (malloc()).#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff# 64 KB of external RAM, starting after internal RAM (ATmega128!),# only used for heap (malloc()).#EXTMEMOPTS = -Wl,--defsym=__heap_start=0x801100,--defsym=__heap_end=0x80ffff EXTMEMOPTS =#---------------- Linker Options ----------------# -Wl,...: tell GCC to pass this to linker.# -Map: create map file# --cref: add cross reference to map fileLDFLAGS = -Wl,-Map=$(TARGET).map,--crefLDFLAGS += $(EXTMEMOPTS)LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)#---------------- Programming Options (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 deviceAVRDUDE_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 </projects/avrdude># to submit bug reports.#AVRDUDE_VERBOSE = -v -vAVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY)AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE)AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER)#---------------- Debugging Options ----------------# For simulavr only - target MCU frequency.DEBUG_MFREQ = $(F_CPU)# Set the DEBUG_UI to either gdb or insight.# DEBUG_UI = gdbDEBUG_UI = insight# Set the debugging back-end to either avarice, simulavr.DEBUG_BACKEND = avarice#DEBUG_BACKEND = simulavr# GDB Init Filename.GDBINIT_FILE = __avr_gdbinit# When using avarice settings for the JTAGJTAG_DEV = /dev/com1# Debugging port used to communicate between GDB / avarice / simulavr.DEBUG_PORT = 4242# Debugging host used to communicate between GDB / avarice / simulavr, normally# just set to localhost unless doing some sort of crazy debugging when# avarice is running on a different computer.DEBUG_HOST = localhost#============================================================================ # Define programs and commands.SHELL = shCC = avr-gccOBJCOPY = avr-objcopyOBJDUMP = avr-objdumpSIZE = avr-sizeNM = avr-nmAVRDUDE = avrdudeREMOVE = rm -fCOPY = cpWINSHELL = cmd# Define Messages# EnglishMSG_ERRORS_NONE = Errors: noneMSG_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)# Define all listing files.LST = $(SRC:.c=.lst) $(ASRC:.S=.lst)# Compiler flags to generate dependency files.GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d# 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 endbuild: elf hex eep lss symelf: $(TARGET).elfhex: $(TARGET).hexeep: $(TARGET).eeplss: $(TARGET).lsssym: $(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.begin:@echo@echo $(MSG_BEGIN)end:@echo $(MSG_END)@echo# Display size of file.HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hexELFSIZE = $(SIZE) -A $(TARGET).elfAVRMEM = avr-mem.sh $(TARGET).elf $(MCU)sizebefore:@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ $(AVRMEM) 2>/dev/null; echo; fisizeafter:@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ $(AVRMEM) 2>/dev/null; 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) # Generate avr-gdb config/init file which does the following:# define the reset signal, load the target file, connect to target, and set# a breakpoint at main().gdb-config:@$(REMOVE) $(GDBINIT_FILE)@echo define reset >> $(GDBINIT_FILE)@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)@echo end >> $(GDBINIT_FILE)@echo file $(TARGET).elf >> $(GDBINIT_FILE)@echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE)ifeq ($(DEBUG_BACKEND),simulavr)@echo load >> $(GDBINIT_FILE)endif@echo break main >> $(GDBINIT_FILE)debug: gdb-config $(TARGET).elfifeq ($(DEBUG_BACKEND), avarice)@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)@$(WINSHELL) /c pauseelse@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \$(DEBUG_MFREQ) --port $(DEBUG_PORT)endif@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. COFFCONVERT=$(OBJCOPY) --debugging \--change-section-address .data-0x800000 \--change-section-address .bss-0x800000 \--change-section-address .noinit-0x800000 \--change-section-address .eeprom-0x810000coff: $(TARGET).elf@echo@echo $(MSG_COFF) $(TARGET).cof$(COFFCONVERT) -O coff-avr $< $(TARGET).cofextcoff: $(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.%.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) $< $@# Create extended listing file from ELF output file.%.lss: %.elf@echo@echo $(MSG_EXTENDED_LISTING) $@ $(OBJDUMP) -h -S $< > $@# 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..SECONDARY : $(TARGET).elf.PRECIOUS : $(OBJ)%.elf: $(OBJ)@echo@echo $(MSG_LINKING) $@$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)# Compile: create object files from C source files.%.o : %.c@echo@echo $(MSG_COMPILING) $<$(CC) -c $(ALL_CFLAGS) $< -o $@# Compile: create assembler files from C source files.%.s : %.c$(CC) -S $(ALL_CFLAGS) $< -o $@# Assemble: create object files from assembler source files. %.o : %.S@echo@echo $(MSG_ASSEMBLING) $<$(CC) -c $(ALL_ASFLAGS) $< -o $@# Create preprocessed source for use in sending a bug report. %.i : %.c$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@# Target: clean project.clean: begin clean_list endclean_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$(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/*)# Listing of phony targets..PHONY : all begin finish end sizebefore sizeafter gccversion \ build elf hex eep lss sym coff extcoff \clean clean_list program debug gdb-config。
ck文档 - makefile写法整理
makefile写法整理1 Makefile基本语法Makefile:程序模块的内部关系决定了源程序编译和链接的顺序,通过建立makefile可以描述模块间的相互依赖关系。
Make命令从中读取这些信息,然后根据这些信息对程序进行管理和维护。
在makefile里主要提供的是有关目标文件(即target)与依靠文件(即dependencyies)之间的关系,还指明了用什么命令生成和更新目标文件。
有了这些信息,make会处理磁盘上的文件,如果目的文件的时间标志(该文件生成或被改动进的时间)比任意一个依靠文件旧,make就执行相应的命令,以便更新目的文件(目的文件不一定是最后的可执行文件,它可以是任何一个文件)。
1)makefile的基本单位是“规则”,即描述一个目标所依赖的文件或模块,并给出其生成和算法语言需要用到的命令。
规则的格式如下:目标[属性]分隔符号 [依赖文件][命令列]{<tab>命令列}与Linux下面的命令格式相同,[]中的内容表示为可选择项,{}中的内容表示可出现多次。
A.目标:目标文件列表,即要维护的文件列表。
B.属性:表示该文件的属性。
C.分隔符:用来分割目标文件和依赖文件的符号,如冒号“:”等。
D.依赖文件:目标文件所依赖的文件的列表。
E.命令列:重新生成目标文件的命令,可以有多条命令。
注意:在makefile中,除了第一条命令,每一个命令行的开头必须是一个<tab>符号,也就是制表符,而不能因为制表符相当于4个空格而不去键入tab符号。
因为make命令是通过每一行的tab符号来识别命令行的。
另外,对于第一条命令而言,不必用<tab>键,就可以直接跟在依赖文件的列表后面。
对于注释的了,起头应该用#符号,并用换行符号结束。
如果要引用#符号,要用到“”。
2)make命令的使用格式为:make [选项][宏定义][目标文件]make命令有多个选项参数,列举参数含义如下:A.-f:指定需要维护的目标。
Makefile使用总结
Makefile使⽤总结1. Makefile 简介Makefile 是和 make 命令⼀起配合使⽤的.很多⼤型项⽬的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项⽬中各种库和代码之间的依赖关系不知会多复杂. Makefile的组织流程的能⼒如此之强, 不仅可以⽤来编译项⽬, 还可以⽤来组织我们平时的⼀些⽇常操作. 这个需要⼤家发挥⾃⼰的想象⼒.本篇博客是基于⽽整理的, 有些删减, 追加了⼀些⽰例.⾮常感谢 gunguymadman_cu 提供如此详尽的Makefile介绍, 这正是我⼀直寻找的Makefile中⽂⽂档.1.1 Makefile 主要的 5个部分 (显⽰规则, 隐晦规则, 变量定义, ⽂件指⽰, 注释)Makefile基本格式如下:target ... : prerequisites ...command......其中,target - ⽬标⽂件, 可以是 Object File, 也可以是可执⾏⽂件prerequisites - ⽣成 target 所需要的⽂件或者⽬标command - make需要执⾏的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头1. 显⽰规则 :: 说明如何⽣成⼀个或多个⽬标⽂件(包括⽣成的⽂件, ⽂件的依赖⽂件, ⽣成的命令)2. 隐晦规则 :: make的⾃动推导功能所执⾏的规则3. 变量定义 :: Makefile中定义的变量4. ⽂件指⽰ :: Makefile中引⽤其他Makefile; 指定Makefile中有效部分; 定义⼀个多⾏命令5. 注释 :: Makefile只有⾏注释 "#", 如果要使⽤或者输出"#"字符, 需要进⾏转义, "\#"1.2 GNU make 的⼯作⽅式1. 读⼊主Makefile (主Makefile中可以引⽤其他Makefile)2. 读⼊被include的其他Makefile3. 初始化⽂件中的变量4. 推导隐晦规则, 并分析所有规则5. 为所有的⽬标⽂件创建依赖关系链6. 根据依赖关系, 决定哪些⽬标要重新⽣成7. 执⾏⽣成命令2. Makefile 初级语法2.1 Makefile 规则2.1.1 规则语法规则主要有2部分: 依赖关系和⽣成⽬标的⽅法.语法有以下2种:target ... : prerequisites ...command...或者target ... : prerequisites ; commandcommand...*注* command太长, 可以⽤ "\" 作为换⾏符2.1.2 规则中的通配符* :: 表⽰任意⼀个或多个字符:: 表⽰任意⼀个字符[...] :: ex. [abcd] 表⽰a,b,c,d中任意⼀个字符, [^abcd]表⽰除a,b,c,d以外的字符, [0-9]表⽰ 0~9中任意⼀个数字~ :: 表⽰⽤户的home⽬录2.1.3 路径搜索当⼀个Makefile中涉及到⼤量源⽂件时(这些源⽂件和Makefile极有可能不在同⼀个⽬录中),这时, 最好将源⽂件的路径明确在Makefile中, 便于编译时查找. Makefile中有个特殊的变量VPATH就是完成这个功能的.指定了VPATH之后, 如果当前⽬录中没有找到相应⽂件或依赖的⽂件, Makefile 回到VPATH指定的路径中再去查找.. VPATH使⽤⽅法:vpath <directories> :: 当前⽬录中找不到⽂件时, 就从<directories>中搜索vpath <pattern> <directories> :: 符合<pattern>格式的⽂件, 就从<directories>中搜索vpath <pattern> :: 清除符合<pattern>格式的⽂件搜索路径vpath :: 清除所有已经设置好的⽂件路径# ⽰例1 - 当前⽬录中找不到⽂件时, 按顺序从 src⽬录 ../parent-dir⽬录中查找⽂件VPATH src:../parent-dir# ⽰例2 - .h结尾的⽂件都从 ./header ⽬录中查找VPATH %.h ./header# ⽰例3 - 清除⽰例2中设置的规则VPATH %.h# ⽰例4 - 清除所有VPATH的设置VPATH2.2 Makefile 中的变量2.2.1 变量定义 ( = or := )OBJS = programA.o programB.oOBJS-ADD = $(OBJS) programC.o# 或者OBJS := programA.o programB.oOBJS-ADD := $(OBJS) programC.o其中 = 和 := 的区别在于, := 只能使⽤前⾯定义好的变量, = 可以使⽤后⾯定义的变量测试 =# Makefile内容OBJS2 = $(OBJS1) programC.oOBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使⽤$ makeprogramA.o programB.o programC.o测试 :=# Makefile内容OBJS2 := $(OBJS1) programC.oOBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执⾏make, 可以看出 OBJS2 中的 $(OBJS1) 为空$ makeprogramC.o2.2.2 变量替换# Makefile内容SRCS := programA.c programB.c programC.cOBJS := $(SRCS:%.c=%.o)all:@echo "SRCS: " $(SRCS)@echo "OBJS: " $(OBJS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.cOBJS: programA.o programB.o programC.o2.2.3 变量追加值 +=# Makefile内容SRCS := programA.c programB.c programC.cSRCS += programD.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ makeSRCS: programA.c programB.c programC.c programD.c2.2.4 变量覆盖 override作⽤是使 Makefile中定义的变量能够覆盖 make 命令参数中指定的变量语法:override <variable> = <value>override <variable> := <value>override <variable> += <value>下⾯通过⼀个例⼦体会 override 的作⽤:# Makefile内容 (没有⽤override)SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: nothing################################################## Makefile内容 (⽤override)override SRCS := programA.c programB.c programC.call:@echo "SRCS: " $(SRCS)# bash中运⾏make$ make SRCS=nothingSRCS: programA.c programB.c programC.c2.2.5 ⽬标变量作⽤是使变量的作⽤域仅限于这个⽬标(target), ⽽不像之前例⼦中定义的变量, 对整个Makefile都有效.语法:<target ...> :: <variable-assignment><target ...> :: override <variable-assignment> (override作⽤参见变量覆盖的介绍)⽰例:# Makefile 内容SRCS := programA.c programB.c programC.ctarget1: TARGET1-SRCS := programD.ctarget1:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)target2:@echo "SRCS: " $(SRCS)@echo "SRCS: " $(TARGET1-SRCS)# bash中执⾏make$ make target1SRCS: programA.c programB.c programC.cSRCS: programD.c$ make target2 <-- target2中显⽰不了 $(TARGET1-SRCS)SRCS: programA.c programB.c programC.cSRCS:2.3 Makefile 命令前缀Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不⽤前缀.3种格式的shell命令区别如下:不⽤前缀 :: 输出执⾏的命令以及命令执⾏的结果, 出错的话停⽌执⾏前缀 @ :: 只输出命令执⾏的结果, 出错的话停⽌执⾏前缀 - :: 命令执⾏有错的话, 忽略错误, 继续执⾏⽰例:# Makefile 内容 (不⽤前缀)all:echo"没有前缀"cat this_file_not_existecho"错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 @)all:@echo "没有前缀"@cat this_file_not_exist@echo "错误之后的命令" <-- 这条命令不会被执⾏# bash中执⾏make$ make没有前缀 <-- 只有命令执⾏的结果, 不显⽰命令本⾝cat: this_file_not_exist: No such file or directorymake: *** [all] Error 1############################################################ Makefile 内容 (前缀 -)all:-echo"没有前缀"-cat this_file_not_exist-echo"错误之后的命令" <-- 这条命令会被执⾏# bash中执⾏make$ makeecho"没有前缀" <-- 命令本⾝显⽰出来没有前缀 <-- 命令执⾏结果显⽰出来cat this_file_not_existcat: this_file_not_exist: No such file or directorymake: [all] Error 1 (ignored)echo"错误之后的命令" <-- 出错之后的命令也会显⽰错误之后的命令 <-- 出错之后的命令也会执⾏2.4 伪⽬标伪⽬标并不是⼀个"⽬标(target)", 不像真正的⽬标那样会⽣成⼀个⽬标⽂件.典型的伪⽬标是 Makefile 中⽤来清理编译过程中中间⽂件的 clean 伪⽬标, ⼀般格式如下: .PHONY: clean <-- 这句没有也⾏, 但是最好加上clean:-rm -f *.o2.5 引⽤其他的 Makefile语法: include <filename> (filename 可以包含通配符和路径)⽰例:# Makefile 内容all:@echo "主 Makefile begin"@make other-all@echo "主 Makefile end"include ./other/Makefile# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 20K-rw-r--r-- 1 wangyubin wangyubin 125 Sep 2316:13 Makefile-rw-r--r-- 1 wangyubin wangyubin 11K Sep 2316:15 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2316:11 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile'主 Makefile end2.6 查看C⽂件的依赖关系写 Makefile 的时候, 需要确定每个⽬标的依赖关系.GNU提供⼀个机制可以查看C代码⽂件依赖那些⽂件, 这样我们在写 Makefile ⽬标的时候就不⽤打开C源码来看其依赖那些⽂件了.⽐如, 下⾯命令显⽰内核源码中 virt/kvm/kvm_main.c 中的依赖关系$ cd virt/kvm/$ gcc -MM kvm_main.ckvm_main.o: kvm_main.c iodev.h coalesced_mmio.h async_pf.h <-- 这句就可以加到 Makefile 中作为编译 kvm_main.o 的依赖关系2.7 make 退出码Makefile的退出码有以下3种:0 :: 表⽰成功执⾏1 :: 表⽰make命令出现了错误2 :: 使⽤了 "-q" 选项, 并且make使得⼀些⽬标不需要更新2.8 指定 Makefile,指定特定⽬标默认执⾏ make 命令时, GNU make在当前⽬录下依次搜索下⾯3个⽂件 "GNUmakefile", "makefile", "Makefile",找到对应⽂件之后, 就开始执⾏此⽂件中的第⼀个⽬标(target). 如果找不到这3个⽂件就报错.⾮默认情况下, 可以在 make 命令中指定特定的 Makefile 和特定的⽬标.⽰例:# Makefile⽂件名改为 MyMake, 内容target1:@echo "target [1] begin"@echo "target [1] end"target2:@echo "target [2] begin"@echo "target [2] end"# bash 中执⾏make$ lsMakefile$ mv Makefile MyMake$ lsMyMake$ make <-- 找不到默认的 Makefilemake: *** No targets specified and no makefile found. Stop.$ make -f MyMake <-- 指定特定的Makefiletarget [1] begintarget [1] end$ make -f MyMake target2 <-- 指定特定的⽬标(target)target [2] begintarget [2] end2.9 make 参数介绍make 的参数有很多, 可以通过 make -h 去查看, 下⾯只介绍⼏个我认为⽐较有⽤的.参数含义--debug[=<options>]输出make的调试信息, options 可以是 a, b, v-j --jobs同时运⾏的命令的个数, 也就是多线程执⾏ Makefile-r --no-builtin-rules禁⽌使⽤任何隐含规则-R --no-builtin-variabes禁⽌使⽤任何作⽤于变量上的隐含规则-B --always-make假设所有⽬标都有更新, 即强制重编译2.10 Makefile 隐含规则这⾥只列⼀个和编译C相关的.编译C时,<n>.o 的⽬标会⾃动推导为 <n>.c# Makefile 中main : main.ogcc -o main main.o#会⾃动变为:main : main.ogcc -o main main.omain.o: main.c <-- main.o 这个⽬标是隐含⽣成的gcc -c main.c2.11 隐含规则中的命令变量和命令参数变量2.11.1 命令变量, 书写Makefile可以直接写 shell时⽤这些变量.下⾯只列出⼀些C相关的变量名含义RM rm -fAR arCC ccCXX g++⽰例:# Makefile 内容all:@echo $(RM)@echo $(AR)@echo $(CC)@echo $(CXX)# bash 中执⾏make, 显⽰各个变量的值$ makerm -farccg++2.11.2 命令参数变量变量名含义ARFLAGS AR命令的参数CFLAGS C语⾔编译器的参数CXXFLAGS C++语⾔编译器的参数⽰例: 下⾯以 CFLAGS 为例演⽰# test.c 内容#include <stdio.h>int main(int argc, char *argv[]){printf ("Hello Makefile\n");return 0;}# Makefile 内容test: test.o$(CC) -o test test.o# bash 中⽤make来测试$ lltotal 24K-rw-r--r-- 1 wangyubin wangyubin 69 Sep 2317:31 Makefile-rw-r--r-- 1 wangyubin wangyubin 14K Sep 2319:51 <-- 请忽略这个⽂件-rw-r--r-- 1 wangyubin wangyubin 392 Sep 2317:31 test.c$ makecc -c -o test.o test.ccc -o test test.o <-- 这个是⾃动推导的$ rm -f test test.o$ make CFLAGS=-Wall <-- 命令中加的编译器参数⾃动追加⼊下⾯的编译中了cc -Wall -c -o test.o test.ccc -o test test.o2.12 ⾃动变量Makefile 中很多时候通过⾃动变量来简化书写, 各个⾃动变量的含义如下:⾃动变量含义$@⽬标集合$%当⽬标是函数库⽂件时, 表⽰其中的⽬标⽂件名$<第⼀个依赖⽬标. 如果依赖⽬标是多个, 逐个表⽰依赖⽬标$?⽐⽬标新的依赖⽬标的集合$^所有依赖⽬标的集合, 会去除重复的依赖⽬标$+所有依赖⽬标的集合, 不会去除重复的依赖⽬标$*这个是GNU make特有的, 其它的make不⼀定⽀持3. Makefile ⾼级语法3.1 嵌套Makefile在 Makefile 初级语法中已经提到过引⽤其它 Makefile的⽅法. 这⾥有另⼀种写法, 并且可以向引⽤的其它 Makefile 传递参数.⽰例: (不传递参数, 只是调⽤⼦⽂件夹 other 中的Makefile)# Makefile 内容all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "other makefile end"# bash中执⾏make$ lltotal 28K-rw-r--r-- 1 wangyubin wangyubin 104 Sep 2320:43 Makefile-rw-r--r-- 1 wangyubin wangyubin 17K Sep 2320:44 <-- 这个⽂件不⽤管drwxr-xr-x 2 wangyubin wangyubin 4.0K Sep 2320:42 other$ ll other/total 4.0K-rw-r--r-- 1 wangyubin wangyubin 71 Sep 2316:11 Makefile$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginother makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end⽰例: (⽤export传递参数)# Makefile 内容export VALUE1 := export.c <-- ⽤了 export, 此变量能够传递到 ./other/Makefile 中VALUE2 := no-export.c <-- 此变量不能传递到 ./other/Makefile 中all:@echo "主 Makefile begin"@cd ./other && make@echo "主 Makefile end"# ./other/Makefile 内容other-all:@echo "other makefile begin"@echo "VALUE1: " $(VALUE1)@echo "VALUE2: " $(VALUE2)@echo "other makefile end"# bash中执⾏make$ make主 Makefile beginmake[1]: Entering directory `/path/to/test/makefile/other'other makefile beginVALUE1: export.c <-- VALUE1 传递成功VALUE2: <-- VALUE2 传递失败other makefile endmake[1]: Leaving directory `/path/to/test/makefile/other'主 Makefile end*补充* export 语法格式如下:export variable = valueexport variable := valueexport variable += value3.2 定义命令包命令包有点像是个函数, 将连续的相同的命令合成⼀条, 减少 Makefile 中的代码量, 便于以后维护.语法:define <command-name>command...endef⽰例:# Makefile 内容define run-hello-makefile@echo -n "Hello"@echo " Makefile!"@echo "这⾥可以执⾏多条 Shell 命令!"endefall:$(run-hello-makefile)# bash 中运⾏make$ makeHello Makefile!这⾥可以执⾏多条 Shell 命令!3.3 条件判断条件判断的关键字主要有 ifeq ifneq ifdef ifndef语法:<conditional-directive><text-if-true>endif# 或者<conditional-directive><text-if-true>else<text-if-false>endif⽰例: ifeq的例⼦, ifneq和ifeq的使⽤⽅法类似, 就是取反# Makefile 内容all:ifeq ("aa", "bb")@echo "equal"else@echo "not equal"endif# bash 中执⾏make$ makenot equal⽰例: ifdef的例⼦, ifndef和ifdef的使⽤⽅法类似, 就是取反# Makefile 内容SRCS := program.call:ifdef SRCS@echo $(SRCS)else@echo "no SRCS"# bash 中执⾏make$ makeprogram.c3.4 Makefile 中的函数Makefile 中⾃带了⼀些函数, 利⽤这些函数可以简化 Makefile 的编写.函数调⽤语法如下:$(<function> <arguments>)# 或者${<function> <arguments>}<function> 是函数名<arguments> 是函数参数3.4.1 字符串函数字符串替换函数: $(subst <from>,<to>,<text>)功能: 把字符串<text> 中的 <from> 替换为 <to>返回: 替换过的字符串# Makefile 内容all:@echo $(subst t,e,maktfilt) <-- 将t替换为e# bash 中执⾏make$ makemakefile模式字符串替换函数: $(patsubst <pattern>,<replacement>,<text>)功能: 查找<text>中的单词(单词以"空格", "tab", "换⾏"来分割) 是否符合 <pattern>, 符合的话, ⽤ <replacement> 替代.返回: 替换过的字符串# Makefile 内容all:@echo $(patsubst %.c,%.o,programA.c programB.c)# bash 中执⾏make$ makeprogramA.o programB.o去空格函数: $(strip <string>)功能: 去掉 <string> 字符串中开头和结尾的空字符返回: 被去掉空格的字符串值# Makefile 内容VAL := " aa bb cc "all:@echo "去除空格前: " $(VAL)@echo "去除空格后: " $(strip $(VAL))# bash 中执⾏make去除空格前: aa bb cc去除空格后: aa bb cc查找字符串函数: $(findstring <find>,<in>)功能: 在字符串 <in> 中查找 <find> 字符串返回: 如果找到, 返回 <find> 字符串, 否则返回空字符串# Makefile 内容VAL := " aa bb cc "all:@echo $(findstring aa,$(VAL))@echo $(findstring ab,$(VAL))# bash 中执⾏make$ makeaa过滤函数: $(filter <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *保留* 符合模式 <pattern> 的单词, 可以有多个模式返回: 符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.o program.a反过滤函数: $(filter-out <pattern...>,<text>)功能: 以 <pattern> 模式过滤字符串 <text>, *去除* 符合模式 <pattern> 的单词, 可以有多个模式返回: 不符合模式 <pattern> 的字符串# Makefile 内容all:@echo $(filter-out %.o %.a,program.c program.o program.a)# bash 中执⾏make$ makeprogram.c排序函数: $(sort <list>)功能: 给字符串 <list> 中的单词排序 (升序)返回: 排序后的字符串# Makefile 内容all:@echo $(sort bac abc acb cab)# bash 中执⾏make$ makeabc acb bac cab取单词函数: $(word <n>,<text>)功能: 取字符串 <text> 中的第<n>个单词 (n从1开始)返回: <text> 中的第<n>个单词, 如果<n> ⽐ <text> 中单词个数要⼤, 则返回空字符串# Makefile 内容all:@echo $(word 1,aa bb cc dd)@echo $(word 5,aa bb cc dd)@echo $(word 4,aa bb cc dd)# bash 中执⾏make$ makeaadd取单词串函数: $(wordlist <s>,<e>,<text>)功能: 从字符串<text>中取从<s>开始到<e>的单词串. <s>和<e>是⼀个数字.返回: 从<s>到<e>的字符串# Makefile 内容all:@echo $(wordlist 1,3,aa bb cc dd)@echo $(word 5,6,aa bb cc dd)@echo $(word 2,5,aa bb cc dd)# bash 中执⾏make$ makeaa bb ccbb单词个数统计函数: $(words <text>)功能: 统计字符串 <text> 中单词的个数返回: 单词个数# Makefile 内容all:@echo $(words aa bb cc dd)@echo $(words aabbccdd)@echo $(words )# bash 中执⾏make$ make41⾸单词函数: $(firstword <text>)功能: 取字符串 <text> 中的第⼀个单词返回: 字符串 <text> 中的第⼀个单词# Makefile 内容all:@echo $(firstword aa bb cc dd)@echo $(firstword aabbccdd)@echo $(firstword )# bash 中执⾏make$ makeaaaabbccdd3.4.2 ⽂件名函数取⽬录函数: $(dir <names...>)功能: 从⽂件名序列 <names> 中取出⽬录部分返回: ⽂件名序列 <names> 中的⽬录部分# Makefile 内容all:@echo $(dir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ make/home/ ./ ../ ./取⽂件函数: $(notdir <names...>)功能: 从⽂件名序列 <names> 中取出⾮⽬录部分返回: ⽂件名序列 <names> 中的⾮⽬录部分# Makefile 内容all:@echo $(notdir /home/a.c ./bb.c ../c.c d.c)# bash 中执⾏make$ makea.c bb.cc.cd.c取后缀函数: $(suffix <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的后缀返回: ⽂件名序列 <names> 中各个⽂件名的后缀, 没有后缀则返回空字符串# Makefile 内容all:@echo $(suffix /home/a.c ./b.o ../c.a d)# bash 中执⾏make$ make.c .o .a取前缀函数: $(basename <names...>)功能: 从⽂件名序列 <names> 中取出各个⽂件名的前缀返回: ⽂件名序列 <names> 中各个⽂件名的前缀, 没有前缀则返回空字符串# Makefile 内容all:@echo $(basename /home/a.c ./b.o ../c.a /home/.d .e)# bash 中执⾏make$ make/home/a ./b ../c /home/加后缀函数: $(addsuffix <suffix>,<names...>)功能: 把后缀 <suffix> 加到 <names> 中的每个单词后⾯返回: 加过后缀的⽂件名序列# Makefile 内容all:@echo $(addsuffix .c,/home/a b ./c.o ../d.c)# bash 中执⾏make$ make/home/a.c b.c ./c.o.c ../d.c.c加前缀函数: $(addprefix <prefix>,<names...>)功能: 把前缀 <prefix> 加到 <names> 中的每个单词前⾯返回: 加过前缀的⽂件名序列# Makefile 内容all:@echo $(addprefix test_,/home/a.c b.c ./d.c)# bash 中执⾏make$ maketest_/home/a.c test_b.c test_./d.c连接函数: $(join <list1>,<list2>)功能: <list2> 中对应的单词加到 <list1> 后⾯返回: 连接后的字符串# Makefile 内容all:@echo $(join a b c d,1234)@echo $(join a b c d,12345)@echo $(join a b c d e,1234)# bash 中执⾏make$ makea1 b2 c3 d4a1 b2 c3 d4 5a1 b2 c3 d4 e3.4.3 foreach语法:$(foreach <var>,<list>,<text>)⽰例:# Makefile 内容targets := a b c dobjects := $(foreach i,$(targets),$(i).o)all:@echo $(targets)@echo $(objects)# bash 中执⾏make$ makea b c da.ob.oc.od.o3.4.4 if这⾥的if是个函数, 和前⾯的条件判断不⼀样, 前⾯的条件判断属于Makefile的关键字语法:$(if <condition>,<then-part>)$(if <condition>,<then-part>,<else-part>)⽰例:# Makefile 内容val := aobjects := $(if $(val),$(val).o,nothing)no-objects := $(if $(no-val),$(val).o,nothing)all:@echo $(objects)@echo $(no-objects)# bash 中执⾏make$ makea.onothing3.4.5 call - 创建新的参数化函数语法:$(call <expression>,<parm1>,<parm2>,<parm3>...)⽰例:# Makefile 内容log = "====debug====" $(1) "====end===="all:@echo $(call log,"正在 Make")# bash 中执⾏make$ make====debug==== 正在 Make ====end====3.4.6 origin - 判断变量的来源语法:$(origin <variable>)返回值有如下类型:类型含义undefined<variable> 没有定义过default<variable> 是个默认的定义, ⽐如 CC 变量environment<variable> 是个环境变量, 并且 make时没有使⽤ -e 参数file<variable> 定义在Makefile中command line<variable> 定义在命令⾏中override<variable> 被 override 重新定义过automatic<variable> 是⾃动化变量⽰例:# Makefile 内容val-in-file := test-fileoverride val-override := test-overrideall:@echo $(origin not-define) # not-define 没有定义@echo $(origin CC) # CC 是Makefile默认定义的变量@echo $(origin PATH) # PATH 是 bash 环境变量@echo $(origin val-in-file) # 此Makefile中定义的变量@echo $(origin val-in-cmd) # 这个变量会加在make的参数中@echo $(origin val-override) # 此Makefile中定义的override变量@echo $(origin @) # ⾃动变量, 具体前⾯的介绍# bash 中执⾏make$ make val-in-cmd=val-cmdundefineddefaultenvironmentfilecommand lineoverrideautomatic3.4.7 shell语法:$(shell <shell command>)它的作⽤就是执⾏⼀个shell命令, 并将shell命令的结果作为函数的返回.作⽤和 `<shell command>` ⼀样, ` 是反引号3.4.8 make 控制函数产⽣⼀个致命错误: $(error <text ...>)功能: 输出错误信息, 停⽌Makefile的运⾏# Makefile 内容all:$(error there is an error!)@echo "这⾥不会执⾏!"# bash 中执⾏make$ makeMakefile:2: *** there is an error!. Stop.输出警告: $(warning <text ...>)功能: 输出警告信息, Makefile继续运⾏# Makefile 内容all:$(warning there is an warning!)@echo "这⾥会执⾏!"# bash 中执⾏make$ makeMakefile:2: there is an warning!这⾥会执⾏!3.5 Makefile中⼀些GNU约定俗成的伪⽬标如果有过在Linux上, 从源码安装软件的经历的话, 就会对 make clean, make install ⽐较熟悉.像 clean, install 这些伪⽬标, ⼴为⼈知, 不⽤解释就⼤家知道是什么意思了.下⾯列举⼀些常⽤的伪⽬标, 如果在⾃⼰项⽬的Makefile合理使⽤这些伪⽬标的话, 可以让我们⾃⼰的Makefile看起来更专业, 呵呵 :)伪⽬标含义all所有⽬标的⽬标,其功能⼀般是编译所有的⽬标clean删除所有被make创建的⽂件install安装已编译好的程序,其实就是把⽬标可执⾏⽂件拷贝到指定的⽬录中去print列出改变过的源⽂件tar把源程序打包备份. 也就是⼀个tar⽂件dist创建⼀个压缩⽂件, ⼀般是把tar⽂件压成Z⽂件. 或是gz⽂件TAGS更新所有的⽬标, 以备完整地重编译使⽤check 或 test⼀般⽤来测试makefile的流程。
makefile典型模板
makefile典型模板Makefile典型模板Sunny.man1.写在前⾯在这篇⽂章之前,曾经因为⾃⼰学习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.txt3.3makefile中的函数makefile⾥的函数使⽤,和取变量的值类似,是以⼀个‘$’开始,然后是⼀个括号⾥⾯是函数名和需要的参数列表,多个变量⽤逗号隔开,像这样return = $(functionname arg1,arg2,arg3...)。
3.4$(wildcard $(SRCPATH)*.c)$(wildcard PATTERN...) ,在Makefile中,它被展开为已经存在的、使⽤空格分开的、匹配此模式的所有⽂件列表。
Makefile编写及通用模板
Makefile 函数说明:wildcard 是扩展通配符函数,功能是展开成一列所有符合由其参数描述的文 件名,文件间以空格间隔。
objects= $(wildcard *.c) , 会产生一个所有以.c结尾的文件列表(本例结果为add.c sub.c div.c mul.c cal.c),然后存入变量objects里patsubst 是匹配替换函数, patsubst 函数需要3个参数,第一个是需要匹配的文件样式,第二个是匹配替换成什么文件,第三个是需要匹配的源文件。
objects : $(patsubst %.c,%.o,$(wildcard *.c))会被处理为objects :=add.o sub.o div.o mul.o cal.onotdir 是去除路径函数,只留下文件名,如:./src/mytest.c, 通过notdir之后得到mytest.c Makefile 变量说明:$@ 表示目标文件;一般是在规则中这么用:gcc $(object) -o $@$^ 表示所有依赖文件;用所有依赖文件链接成目的文件:gcc $^ o $@$< 表示第一个依赖文件;每个依赖文件生成一个目的文件:gcc o $@ c $<$? 表示比目标还要新的依赖文件列表 Makefile 赋值操作:= 是最基本的赋值:= 是覆盖之前的值?= 是如果没有被赋值过就赋予等号后面的值+= 是添加等号后面的值make会将整个makefile展开后,再决定变量的值。
也就是说,变量的值将会是整个makefile中最后被指定的值 Makefile 特殊符号:@表示不显示命令本身,而只显示它的结果,通常用在“规则”行中Makefile 规则:target... : prerequisites ...commandtarget 是一个目标文件,可以是执行文件prerequisites 是要生成那个target所需要的文件或是目标command 是make需要执行的命令(任意的Shell命令),一定要以一个Tab 键作为开头。
sv 中的makefile 写法
SV(SystemVerilog)是一种硬件描述语言,用于设计和验证数字电路。
在进行SV代码编写的过程中,makefile是一种非常有用的工具,可以帮助组织和管理SV项目中的代码文件。
本文将介绍SV中makefile的写法,希望能为SV开发者提供一些参考和帮助。
1. 为什么需要makefile在SV项目中,通常会涉及到多个源文件、库文件、测试文件等。
使用makefile可以帮助我们轻松地组织和管理这些文件,实现自动化编译、信息和运行测试的功能。
makefile还可以帮助我们避免重复编译文件,提高开发效率。
2. makefile的基本结构makefile由一系列规则组成,每个规则由一个目标、依赖列表和命令组成。
一个基本的makefile看起来像这样:```makefiletarget: dependenciesmand```其中,target表示规则的目标文件,dependencies表示该目标文件的依赖文件mand表示需要执行的命令。
3. 使用变量在makefile中,我们可以使用变量来定义一些常量,方便我们在后续的规则中使用。
例如:```makefileSV_SRC = file1.sv file2.sv file3.sv```这样,我们就可以在后续的规则中使用$(SV_SRC)来表示这些文件,而不需要重复地写出它们的文件名。
4. 基本规则在SV项目中,常见的makefile规则包括编译规则、信息规则和运行测试规则。
以下是一个简单的例子:```makefileall: $(SV_SRC)vlog $(SV_SRC)sim: allvsim top_module```在这个例子中,我们定义了两个规则,分别是all和sim。
all规则依赖于$(SV_SRC)中的文件,使用vlog命令对这些文件进行编译。
sim规则依赖于all规则,使用vsim命令来运行测试。
5. 使用通配符在makefile中,我们还可以使用通配符来表示一类文件。
一套的实用完整Makefile参考模板
∙一套的实用完整Makefile参考模板∙近来,经常看到有人询问makefile的写法,这里根据本人经验给出一个应用系统的完整例子,便于各位参考。
应用系统的目录结构如下:代码:~/bin 可执行程式目录~/etc 设置文件目录~/inc 头文件目录~/lib 函数库文件目录~/log 日志文件目录~/src 源程式文件目录~/src/lib 函数库源程式目录~/src/lib/LIB_1 函数库libLIB_1源程式目录~/src/APP_A 子系统APP_A源程式目录~/src/APP_A/mod_a 子系统APP_A模块mod_a源程式目录~/.profile~/makefile∙~/makefile文件内容如下:代码:all:@MakeSubDir() \{ \for DIR in `ls|grep ’lib’;ls|grep -v ’lib’`; do \if [ -d ${DIR} ]; then \cd ${DIR}; \MakeSubDir; \if [ -f makefile -o -f Makefile ]; then \echo ""; \pwd; \make all; \fi; \cd ..; \fi; \done; \}; \MakeSubDirtar:@tar -cf `date +%Y%m%d-%H%M%S`.tar .profile `ls|grep -v ’.tar’`~/src/lib/LIB_1/makefile文件内容如下:代码:ALL: INFO allBASEDIR = $(HOME)INC = $(BASEDIR)/incLIB = $(BASEDIR)/libPRDNAME = $(LIB)/libLIB_1PRODUCT = $(PRDNAME).a $(PRDNAME).soOBJS = LIB_1_f1.o LIB_1_f2.oAR = ar <特定平台ar可选参数>CC = cc <特定平台cc可选参数>all: $(PRODUCT)$(PRDNAME).a: $(OBJS)@echo " Making $@ ..."@$(AR) -r $@ $(OBJS)$(PRDNAME).so: $(OBJS)@echo " Making $@ ..."@$(CC) -G -o $@ $(OBJS).c.o: *.h $(INC)/*.h@echo " Compiling $< ..."@$(CC) -c -I$(INC) $<INFO:@echo " make all - same with ’make’ except this message"@echo " make clear - remove object files"@echo " make clean - remove all object and target files"@echo ""clear: FORCE@rm -f *.oclean: FORCE clear@rm -f $(PRODUCT)FORCE:~/src/APP_A/mod_a/makefile文件内容如下:代码:ALL: INFO allBASEDIR = $(HOME)INC = $(BASEDIR)/incLIB = $(BASEDIR)/libBIN = $(BASEDIR)/binMODULE = $(BIN)/APP_A_mod_aTESTER = APP_A_mod_a_tPRODUCT = $(SERVER) $(TESTER)CC = cc <特定平台cc可选参数>all: $(PRODUCT)$(MODULE): APP_A_mod_a.o@echo " Making $@ ..."@$(CC) $? -o$@ -L$(LIB) -lLIB_1APP_A_mod_a_t: APP_A_mod_a_t.o@echo " Making $@ ..."@$(CC) $? -o$@ -L$(LIB) -lLIB_1.c.o: *.h $(INC)/*.h@echo " Compiling $< ..."@$(CC) -c -I$(INC) $<INFO:@echo " make all - same with ’make’ except this message"@echo " make clear - remove object files"@echo " make clean - remove all object and target files"@echo ""clear: FORCE@rm -f *.oclean: FORCE clear@rm -f $(PRODUCT)FORCE:使用方法:1.在主目录下使用’make’命令能够首先建立函数库,然后建立所有目标。
makefile 函数参数
makefile 函数参数Makefile函数参数Makefile是一种常用的自动化构建工具,可以用于编译、链接、打包等操作。
在Makefile中,函数参数是非常有用的工具,可以使Makefile更加灵活和可扩展。
本文将介绍Makefile函数参数的使用方法和常见应用场景。
1. 函数参数的基本语法Makefile中的函数参数使用$()或者${}来调用,语法格式如下:$(function_name argument)或者${function_name argument}其中function_name是函数的名称,argument是函数的参数。
函数参数可以是变量、字面量或者其他函数。
例如,我们可以定义一个函数hello,用于输出字符串:hello:@echo "Hello, world!"然后在另一个函数中调用hello函数:say_hello:$(hello)或者say_hello:${hello}这样,当我们执行make say_hello命令时,将会输出Hello, world!的字符串。
2. 函数参数的常见应用场景函数参数在Makefile中的应用非常广泛,下面将介绍几个常见的应用场景。
2.1 条件判断函数参数可以用于条件判断。
例如,我们可以定义一个函数check,用于检查某个文件是否存在:check:ifeq ($(wildcard file.txt),)$(error file.txt does not exist!)endif然后在另一个函数中调用check函数:say_hello:$(check)@echo "Hello, world!"这样,当file.txt文件不存在时,执行make say_hello命令将会输出错误信息file.txt does not exist!,否则将会输出Hello, world!的字符串。
2.2 循环遍历函数参数还可以用于循环遍历。
万能makefile模板
万能makefile模板这⾥⼀份万能makefile模板,写opencv项⽬时候使⽤的。
前提是提前配置好包管理⼯具 pkg 然后就不⽤每次都去 -lopencv_xxx了。
##############################################################################source file#源⽂件,⾃动找所有.c和.cpp⽂件,并将⽬标定义为同名.o⽂件SOURCE := $(wildcard *.c) $(wildcard *.cpp)OBJS := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))#target you can change test to what you want#⽬标⽂件名,输⼊任意你想要的执⾏⽂件名TARGET := gpu-basics-similarity#compile and lib parameter#编译参数 := equals =CC := g++LIBS := -L/usr/local/lib#LDFLAGS := -lopencv_imgcodecs -lopencv_highgui -lopencv_xfeatures2d -lopencv_features2d -lopencv_core -lopencv_flann -lopencv_calib3d -lopencv_imgproc LDFLAGS :=`pkg-config --libs opencv`DEFINES :=INCLUDE := -I. -I/usr/local/includeCFLAGS := -g -Wall -O3 $(DEFINES) $(INCLUDE) # CFLAGS 表⽰⽤于 C 编译器的选项#CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H # C++ 编译器的选项CXXFLAGS := -g -std=c++11 -Wall $(INCLUDE)$(TARGET):$(OBJS)$(CC) -o $@ $(OBJS) $(LIBS) $(LDFLAGS) $(CXXFLAGS)#下⾯的基本上不需要做任何改动了.PHONY : everything objs clean veryclean rebuildeverything : $(TARGET)all : $(TARGET)objs : $(OBJS)rebuild: veryclean everything# 换⾏的开始必须是1个tabclean :rm -fr *.sorm -fr *.overyclean : cleanrm -fr $(TARGET)。
省事之通用Makefile模版
省事之通⽤Makefile模版
现在编译⽅案都偏爱使⽤cmake解决问题,这两条做unity插件,还是⽤Makefile,居然忘得光光,好记性不如烂笔头。
后⾯,翻箱倒柜找到以前为炼⾦术写的Makefiel,发现还真是挺好⽤,贴出来,当万能Makefile模板挺好的。
PROJECT_DIR = ..
#PATH:=${ALCHEMY_HOME}/achacks:${PATH}
CC = gcc
AR = ar
CFLAGS := -Wall -W -std=gnu99 -g
LDFLAGS =
INCLUDE_DIR = -I$(PROJECT_DIR)/luajit/src
LIBNAME = libz.a
OBJS = $(patsubst ./%.c, %.o,$(wildcard ./*.c))
.PHONY: all clean
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -c $< $(INCLUDE_DIR)
all: $(LIBNAME)
$(LIBNAME):$(OBJS)
@$(AR) rcs $(LIBNAME) $(OBJS)
ranlib $(LIBNAME)
clean:
@rm -rf $(LIBNAME) $(OBJS)
修改LIBNAME为你想要库名
在源码⽬录⽂件名为Makefile
只实现make 和make clean
如果c++的⾃⼰实现⼀下⾃动推导规则,看着也简单
另外,也改善⼀下对MinGW的印象,其实也挺好⽤的,不⼀定要⽤cmake⽣成vc解决⽅案,既然喜欢linux,为什么不能接受mingw呢?。
我所使用的一个通用的Makefile模板
我所使⽤的⼀个通⽤的Makefile模板话不多说,请看:我的项⽬有的⽬录结构有:dirls/├── include│└── apue.h├── lib│├── error.c│├── error.o│└── Makefile├── src│├── dirls.c│├── dirls.out│└── Makefile└── test_client⽽我的Makefile模板代码如下:SRCS = $(wildcard *.c ../lib/*.c) #wildcard把指定⽬录 ./ 和 ../lib 下的所有后缀是c的⽂件全部展开。
OBJS = $(SRCS:.c = .o) #OBJS将$(SRCS)下的.c⽂件转化为.o⽂件CC = gcc #代表所使⽤的编译器INCLUDES = -I../include \ #头⽂件查找路径-I. \LIBS = -L../lib \ #链接库查找地址CCFLAGS = -g -Wall -O0 #附加参数OUTPUT = dirls.out #输出程序名称all:$(OUTPUT)$(OUTPUT) : $(OBJS)$(CC) $^ -o $@ $(INCLUDES) $(LIBS)%.o : %.c$(CC) -c $< $(CCFLAGS)clean:rm -rf *.out *.o #清除中间⽂件及⽣成⽂件.PHONY:clean另外附上别的⽹站的⼏个Makefile模板:1、编译动态库############################################################## Makefile for shared library.# 编译动态链接库##############################################################set your own environment optionCC = g++CC_FLAG = -D_NOMNG -D_FILELINE#set your inc and libINC =LIB = -lpthread -L./ -lsvrtool#make target lib and relevant objPRG = libsvrtool.soOBJ = Log.o#all targetall:$(PRG)$(PRG):$(OBJ)$(CC) -shared -o $@ $(OBJ) $(LIB).SUFFIXES: .c .o .cpp.cpp.o:$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o.PRONY:cleanclean:@echo "Removing linked and compiled files......;rm -f $(OBJ) $(PRG)2、编译静态库############################################################## Makefile for static library.# 编译静态链接库##############################################################set your own environment optionCC = g++CC_FLAG = -D_NOMNG -D_FILELINE#static library use 'ar' commandAR = ar#set your inc and libINC =LIB = -lpthread -L./ -lsvrtool#make target lib and relevant objPRG = libsvrtool.aOBJ = Log.o#all targetall:$(PRG)$(PRG):$(OBJ)${AR} rv ${PRG} $?.SUFFIXES: .c .o .cpp.cpp.o:$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o.PRONY:cleanclean:@echo "Removing linked and compiled files......"rm -f $(OBJ) $(PRG)3、可执⾏程序############################################Makefile for simple programs###########################################INC=LIB= -lpthreadCC=CCCC_FLAG=-WallPRG=threadpooltestOBJ=CThreadManage.o CThreadPool.o CThread.o CWorkerThread.o threadpooltest.o $(PRG):$(OBJ)$(CC) $(INC) $(LIB) -o $@ $(OBJ).SUFFIXES: .c .o .cpp.cpp.o:$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o.PRONY:cleanclean:@echo "Removing linked and compiled files......"rm -f $(OBJ) $(PRG)。
Makefile文件基本格式
Makefile⽂件基本格式以下是Makefile的基本模板#指定编译器CC = g++#指定编译参数CFLAGS = -std=c++11#指定头⽂件路径,此处⽤于指定⾮标准库的头⽂件路径INC = -I./ -I /usr/include#指定要链接的动态库或静态库 -L是指定动态库路径,⾮标准的动态库需要此参数LIBS = -lm -ldl -L/mylibs/xxx -lxxx#把上⾯放⼀起CXXFLAGS = ${CFLAGS} ${INC} ${LIBS}#指定⽣成可执⾏⽂件名称EXEC = a.out#指定由哪些⽂件来⽣成可执⾏⽂件OBJS = xxx1.o xxx2.o#make执⾏动作${EXEC} : ${OBJS}${CC} -o $@ $^#make clean动作clean:rm -rf ${OBJS}#中间⽂件的⽣成%.o:%.c$(CC) $(CXXFLAGS) $(INC) -o $@ -c $<不⽣成中间.o⽂件#指定编译器CC = g++#指定编译参数CFLAGS = -std=c++11#指定头⽂件路径,此处⽤于指定⾮标准库的头⽂件路径INC = -I./ -I /usr/include#指定要链接的动态库或静态库 -L是指定动态库路径,⾮标准的动态库需要此参数LIBS = -lm -ldl -L/mylibs/xxx -lxxx#把上⾯放⼀起CXXFLAGS = ${CFLAGS} ${INC} ${LIBS}#指定⽣成可执⾏⽂件名称EXEC = a.out#指定由哪些⽂件来⽣成可执⾏⽂件COBJS = xxx1.c xxx2.c#make执⾏动作all:$(CC) -o $(EXEC) $(COBJS) $(CXXFLAGS)#make clean动作clean:rm -rf ${OBJS}关于⽣成 **.o ⽂件(只编译未链接⽂件);若是在⼤型项⽬中,只修改了其中⼀个⽂件的内容,那么没必要全部⽂件重新编译,只需编译修改部分即可。
简单的makefile模板
简单的makefile模板makefile不是总⽤到,每次⽤到的时候总要重新找资料,有点⿇烦(怪⾃⼰基础知识不扎实,汗)。
留⼀个通⽤模板放这,⽅便以后使⽤CC = gccCXX = g++LINK = g++CFLAGS = -g -Wall -O2TARGET = mk0SRCS = $(wildcard *.cpp)SRCS += $(wildcard *.c)CXX_OBJS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))C_OBJS = $(patsubst %.c, %.o, $(wildcard *.c))all:$(TARGET)$(TARGET):$(CXX_OBJS) $(C_OBJS)$(LINK) $(CFLAGS) -o $@ $^%.o:%.cpp$(CXX) $(CFLAGS) -c -o $@ $<%.o:%.c$(CC) $(CFLAGS) -c -o $@ $<.PHONY:cleanclean:rm -rf *.o $(TARGET) $(CXX_OBJS) $(C_OBJS)因为项⽬特殊性,经常c与cpp都会⽤到,所以简单写个这样的makefile⽂件上⾯makefile有很⼤局限性,⽐如只能使⽤与所有源⽂件在⼀个⽬录场景。
下⾯展⽰可以多个⽬录下源⽂件,以及程序使⽤动态库的特殊场景CC = gccCXX = g++LINKC = gccLINKCXX = g++CFLAGS = -g -Wall -O2TOP_DIR := $(shell pwd)SRC_DIRS := $(shell find $(TOP_DIR) -maxdepth 1 -type d)TARGET := $(TOP_DIR)/bin/mk0INC_PATH = -I$(TOP_DIR)/include/LIB_PATH = -L$(TOP_DIR)/lib/EXT_LIB = -Wl,-rpath,$(TOP_DIR)/bin/ -lcsayCXX_SRCS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.cpp))CXX_OBJS = $(patsubst %.cpp, %.o, $(CXX_SRCS))C_SRCS = $(foreach dir, $(SRC_DIRS), $(wildcard $(dir)/*.c))C_OBJS = $(patsubst %.c, %.o, $(C_SRCS))all:$(TARGET)$(TARGET):$(CXX_OBJS) $(C_OBJS) $(shell if [ ! -d $(TOP_DIR)/bin ]; then mkdir $(TOP_DIR)/bin; fi)ifeq ($(CXX_SRCS),) $(LINKC) $(LIB_PATH) $(EXT_LIB) $(CFLAGS) -o $@ $^else $(LINKCXX) $(LIB_PATH) $(EXT_LIB) $(CFLAGS) -o $@ $^endif%.o:%.cpp $(CXX) $(INC_PATH) $(CFLAGS) -c -o $@ $<%.o:%.c $(CC) $(INC_PATH) $(CFLAGS) -c -o $@ $<.PHONY:cleanclean:rm -rf $(TARGET) $(CXX_OBJS) $(C_OBJS)如上所⽰,代码包括了三个⽬录:. func0 func1⽬录。