在 Makefile 中为什么我的假目标在两个不同的通用规则之间执行
In Makefile why my phony target is execute between two different generic rule
我的问题如下:
我的 Makefile 中有两个目标,toad4 和 toad5。
根据构建的目标,需要设置一些不同的文件和编译器标志。
这适用于实际构建,如下所示:
SDCC = /Volumes/Partition2/Users/nyholku/sdcc340/bin/sdcc
SDCCFLAGS = "-Wl -f 0xffff" -DTOAD_HW_VERSION=${HWVERSION} --verbose --no-crt --ivt-loc=0x800 -V -L /Volumes/Partition2/Users/nyholku/sdcc340/non-free/lib/pic16 -Wa,-S,0 -Wl,-m,-s18f45k50.lkr -mpic16 -p18f45k50 --disable-warning 85 --std-sdcc99 --obanksel=3 --use-non-free
.PHONY: toad4
toad4: $(OBJDIR)/$(TARGET).hex
toad4: HI_SPEED_IRQ_ASM :=hi_speed_irq-hw4.asm
toad4: HWVERSION := HW4
toad4: BOOTLOADER := ../diolan-plus2-toad4/fw/bootloader.hex
.PHONY: toad5
toad5: HI_SPEED_IRQ_ASM :=hi_speed_irq.asm
toad5: HWVERSION := HW5
toad5: BOOTLOADER := ../diolan-plus2-toad5/fw/bootloader.hex
toad5: $(OBJDIR)/$(TARGET).hex
$(OBJDIR)/%.o: %.c $$(@D)/.f
@echo $(PATH)
$(SDCC) -c $(SDCCFLAGS) $< -o $@
但稍后在 Make 文件中我有规则来生成 C 代码依赖项:
# First include the dependencies
include $(addprefix $(OBJDIR)/, $(SRCS:.c=.dep))
# Then recreate them
$(OBJDIR)/%.dep: %.c $$(@D)/.f
set -e; rm -f $@; \
$(SDCC) -c -M $(SDCCFLAGS) $< > $@.$$$$; \
sed -e '1 s,^,$(OBJDIR)/,' -e 's,\($*\)\.o[ :]*,.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
这是根据 GNU Makefile 手册改编的,在我介绍双目标方案之前就已经工作了。
当我评论依赖生成时,make 工作,为 C 编译设置标志 HWVERSION(通过 SDCCFLAGS),就像它们应该的那样,具体取决于目标。
但是如果我保留该依赖项生成,那么显然该规则在 toad4 和 toad5 规则之前应用,因为 HWVERSION 为空并且生成依赖项的 C 编译失败。
那么为什么在 toad4/toad5 规则之前应用其他通用 C 编译规则并且在应用依赖项生成规则之前?
我也同意关于如何更好地组织它以实现从具有不同设置的大部分相同文件构建不同二进制文件的目标的建议。这应该是很普遍的需求。
我在 macOS 11.3.1 上使用 GNU Make 3.81,编译器是小型设备 C 编译器,即 SDCC
为了完整起见,完整的 Make 文件在这里
#-------------------------------------------------------------------------------
#
# Copyright (c) 2011, Kustaa Nyholm / SpareTimeLabs
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this list
# of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
# contributors may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# Everyone should have this
.SUFFIXES:
# The output file name
TARGET = toad4
# This is necessary so that pk2cmd (used by 'load' script) is found and for the
# pk2cmd to find its support files (it seems to search current dir which is wrong)
PATH := ${PATH}
UPLOADER := java -cp ~/EazyCNC-Project/classes:/Volumes/Partition2/Users/nyholku/EazyCNC-Project/lib/purejavahidapi-0.0.12.jar:/Volumes/Partition2/Users/nyholku/EazyCNC-Project/lib/jna-5.6.0.jar diolanupdater.UpdateFirmware
ENCODER := /Volumes/Partition2/Users/nyholku/diolan-plus2/encoder/build/encoder
HEXMATE := /Applications/microchip/xc8/v2.32/pic/bin/hexmate
# The source files that make up the project go here
SRCS = main.c toad4.c usb_hid.c usb_core.c usb_pic_defs.c usb_user_config.c command_queue.c crt0iz_toad4.c swuart.c
# The libraries that are used go here
LIBS = libc18f.lib libm18f.lib libsdcc.lib
# Where to find the compiler
SDCC = /Volumes/Partition2/Users/nyholku/sdcc340/bin/sdcc
# Compiler flags go here
# --use-crt=crt0.o TOAD_HW_VERSION
SDCCFLAGS = "-Wl -f 0xffff" -DTOAD_HW_VERSION=${HWVERSION} --verbose --no-crt --ivt-loc=0x800 -V -L /Volumes/Partition2/Users/nyholku/sdcc340/non-free/lib/pic16 -Wa,-S,0 -Wl,-m,-s18f45k50.lkr -mpic16 -p18f45k50 --disable-warning 85 --std-sdcc99 --obanksel=3 --use-non-free
# Where to store the target/intermediate/temporary/object files
OBJDIR = ../obj
#-------------------------------------------------------------------------------
#
.PHONY: toad4
toad4: $(OBJDIR)/$(TARGET).hex
toad4: HI_SPEED_IRQ_ASM :=hi_speed_irq-hw4.asm
toad4: HWVERSION := HW4
toad4: BOOTLOADER := ../diolan-plus2-toad4/fw/bootloader.hex
.PHONY: toad5
toad5: HI_SPEED_IRQ_ASM :=hi_speed_irq.asm
toad5: HWVERSION := HW5
toad5: BOOTLOADER := ../diolan-plus2-toad5/fw/bootloader.hex
toad5: $(OBJDIR)/$(TARGET).hex
#
#-------------------------------------------------------------------------------
.PHONY: load
load:
$(UPLOADER) $(OBJDIR)/$(TARGET)-encoded.hex
#-------------------------------------------------------------------------------
.PHONY: comparebootloaders
comparebootloaders:
$(HEXMATE) -o$../bootloader-backedp.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,/Volumes/Partition2/Users/nyholku/diolan-plus2/fw-backup-25.7.2017/bootloader.hex r000802-FFFFFF,/Volumes/Partition2/Users/nyholku/diolan-plus2/fw-backup-25.7.2017/bootloader.hex
$(HEXMATE) -o$../bootloader-toad4.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,../diolan-plus2-toad4/fw/bootloader.hex r000802-FFFFFF,../diolan-plus2-toad4/fw/bootloader.hex
$(HEXMATE) -o$../bootloader-toad5.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,../diolan-plus2-toad5/fw/bootloader.hex r000802-FFFFFF,../diolan-plus2-toad5/fw/bootloader.hex
#
#
#-------------------------------------------------------------------------------
#
# This ensures that the object directory exists and re-creates it if necessary
#
# This requires make 3.81 or later, delete this section and all expressions that
# refer to .f if you have an older make
#
.SECONDEXPANSION:
# Uses a .f file as a flag file in each directory
%/.f:
mkdir -p $(dir $@)
touch $@
# dont' let make remove the flag files automatically
.PRECIOUS: %/.f
#
#-------------------------------------------------------------------------------
#
# Actual rules
#
# Compile the C-files
$(OBJDIR)/%.o: %.c $$(@D)/.f
@echo $(PATH)
$(SDCC) -c $(SDCCFLAGS) $< -o $@
KEY=${TOAD4PLUS_DIALON_KEY2}
# Link the compiled files and libraries
$(OBJDIR)/$(TARGET).hex: $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) $(OBJDIR)/hi_speed_irq.o
$(SDCC) $(SDCCFLAGS) -o $(OBJDIR)/$(TARGET).hex $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) $(LIBS) $(OBJDIR)/hi_speed_irq.o
# normalize the code filling un-used code memory with 0xFF so that encoding always works on known data
$(HEXMATE) -o$(OBJDIR)/$(TARGET)-normalized.hex -fill=0xFF@0x0800:0x7FFF r0800-7FFF,$(OBJDIR)/$(TARGET).hex
# sanitise the bootloader by keeping only the first 2kB (there is an extra jump code at 0x800 which overlaps with firmware code)
$(HEXMATE) -o$(OBJDIR)/bootloader-normalized.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,$(BOOTLOADER) r000802-FFFFFF,$(BOOTLOADER)
# combine the bootloader and firmware to one hex file that can be programmed with pickit ready to run
$(HEXMATE) -o$(OBJDIR)/$(TARGET)-pickit.hex -fill=0xFFFF@0xF00001:0xF000FF -fill=0xA5@0xF00000:0xF00000 -fill=0x00@0x300000:0x30000D $(OBJDIR)/$(TARGET)-normalized.hex ../obj/bootloader-normalized.hex
# encode the bootloader for bootloading purposes, suppress output so as NOT to reveal the secret key
$(ENCODER) -ix $(OBJDIR)/$(TARGET)-normalized.hex -ox $(OBJDIR)/$(TARGET)-encoded.hex -e ${TOAD4PLUS_DIALON_KEY2}
# upload the encoded hex file using the bootload process
$(UPLOADER) $(OBJDIR)/$(TARGET)-encoded.hex
# Compile the high speed interrupt asm file
$(OBJDIR)/hi_speed_irq.o: ${HI_SPEED_IRQ_ASM}
gpasm -D TOAD_HW_VERSION=${HWVERSION} -o $(OBJDIR)/hi_speed_irq.o -c ${HI_SPEED_IRQ_ASM}
#
#-------------------------------------------------------------------------------
#
# Automatic generation of dependencies
#
# This magic code fragment from GNU make manual uses the SDCC compiler -M option
# to create a Makefile fragment for each C-source file describing the dependencies.
#
# Traditionally these fragments have the type '.d' but SDCC seems to delete them
# when it compiles files, so I use '.dep' here.
#
# Also SDCC '-M' option produces wrong dependency for the file being compiled
# in the sense that it does not contain the path, only the filename. Hence
# the 'sed' command has been mangled to inject the missing path to the fragment.
#
# First include the dependencies
include $(addprefix $(OBJDIR)/, $(SRCS:.c=.dep))
# Then recreate them
$(OBJDIR)/%.dep: %.c $$(@D)/.f
set -e; rm -f $@; \
$(SDCC) -c -M $(SDCCFLAGS) $< > $@.$$$$; \
sed -e '1 s,^,$(OBJDIR)/,' -e 's,\($*\)\.o[ :]*,.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
#------------------------------------------------------------------------------
#
# pretty standard default target
#
all: toad5
#
#-------------------------------------------------------------------------------
#
# pretty standard clean that attempts to delete all that this Makefile may left behind
#
clean:
rm -f $(OBJDIR)/*.rel
rm -f $(OBJDIR)/*.lnk
rm -f $(OBJDIR)/*.S19
rm -f $(OBJDIR)/*.map
rm -f $(OBJDIR)/*.mem
rm -f $(OBJDIR)/*.asm
rm -f $(OBJDIR)/*.rst
rm -f $(OBJDIR)/*.sym
rm -f $(OBJDIR)/*.lst
rm -f $(OBJDIR)/*.o
rm -f $(OBJDIR)/*.dep
rm -f $(OBJDIR)/*.hex
#
# cleanall deletes all in the object directory, do not use this if target dir == source dir
cleanall:
rm $(OBJDIR)/*
#-------------------------------------------------------------------------------
特定于目标的变量继承流经先决条件依赖图。这就是您在这里所依赖的:当目标作为 toad4
的先决条件构建时,它会获得一组选项,而当它作为 toad5
的先决条件构建时,它会获得一组不同的选项。
但是,当您构建依赖文件时,配方不是 运行 作为 toad4
或 toad5
的先决条件:如手册中所述,依赖文件是作为解析 makefile 的一部分由 make 构建,因为您 include
d 那些依赖文件。因此,设置了 none 个特定于目标的变量。
退一步说,我不清楚你认为这将如何工作。您有两组不同的先决条件,但您试图将它们都保存在同一个文件中:这永远行不通。唯一正确的方法是,如果您每次调用 make 时都重建所有先决条件,那么它们对于这个特定 make 想要构建的任何目标都是准确的,但是当然 makefile 中的所有内容都会过时因此每次都会重建所有内容。
对于想要从同一个 makefile 构建两组不同目标的 makefile 的正确答案是构建两个 不同 组目标,而不是同一组目标有不同的旗帜。具体来说,您应该有两个不同的对象目录,并将一个构建生成的文件放在一个对象目录中(例如 obj-toad4
),将另一个构建生成的文件放在另一个对象目录中(例如 obj-toad5
).这样他们就不会混淆,并且 make 可以分辨出哪些是过时的,哪些不是。
此外,GNU make 手册中描述的处理自动先决条件的方法已过时。您应该考虑此处描述的方法:http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
我的问题如下:
我的 Makefile 中有两个目标,toad4 和 toad5。
根据构建的目标,需要设置一些不同的文件和编译器标志。
这适用于实际构建,如下所示:
SDCC = /Volumes/Partition2/Users/nyholku/sdcc340/bin/sdcc
SDCCFLAGS = "-Wl -f 0xffff" -DTOAD_HW_VERSION=${HWVERSION} --verbose --no-crt --ivt-loc=0x800 -V -L /Volumes/Partition2/Users/nyholku/sdcc340/non-free/lib/pic16 -Wa,-S,0 -Wl,-m,-s18f45k50.lkr -mpic16 -p18f45k50 --disable-warning 85 --std-sdcc99 --obanksel=3 --use-non-free
.PHONY: toad4
toad4: $(OBJDIR)/$(TARGET).hex
toad4: HI_SPEED_IRQ_ASM :=hi_speed_irq-hw4.asm
toad4: HWVERSION := HW4
toad4: BOOTLOADER := ../diolan-plus2-toad4/fw/bootloader.hex
.PHONY: toad5
toad5: HI_SPEED_IRQ_ASM :=hi_speed_irq.asm
toad5: HWVERSION := HW5
toad5: BOOTLOADER := ../diolan-plus2-toad5/fw/bootloader.hex
toad5: $(OBJDIR)/$(TARGET).hex
$(OBJDIR)/%.o: %.c $$(@D)/.f
@echo $(PATH)
$(SDCC) -c $(SDCCFLAGS) $< -o $@
但稍后在 Make 文件中我有规则来生成 C 代码依赖项:
# First include the dependencies
include $(addprefix $(OBJDIR)/, $(SRCS:.c=.dep))
# Then recreate them
$(OBJDIR)/%.dep: %.c $$(@D)/.f
set -e; rm -f $@; \
$(SDCC) -c -M $(SDCCFLAGS) $< > $@.$$$$; \
sed -e '1 s,^,$(OBJDIR)/,' -e 's,\($*\)\.o[ :]*,.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
这是根据 GNU Makefile 手册改编的,在我介绍双目标方案之前就已经工作了。
当我评论依赖生成时,make 工作,为 C 编译设置标志 HWVERSION(通过 SDCCFLAGS),就像它们应该的那样,具体取决于目标。
但是如果我保留该依赖项生成,那么显然该规则在 toad4 和 toad5 规则之前应用,因为 HWVERSION 为空并且生成依赖项的 C 编译失败。
那么为什么在 toad4/toad5 规则之前应用其他通用 C 编译规则并且在应用依赖项生成规则之前?
我也同意关于如何更好地组织它以实现从具有不同设置的大部分相同文件构建不同二进制文件的目标的建议。这应该是很普遍的需求。
我在 macOS 11.3.1 上使用 GNU Make 3.81,编译器是小型设备 C 编译器,即 SDCC
为了完整起见,完整的 Make 文件在这里
#-------------------------------------------------------------------------------
#
# Copyright (c) 2011, Kustaa Nyholm / SpareTimeLabs
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# Redistributions of source code must retain the above copyright notice, this list
# of conditions and the following disclaimer.
#
# Redistributions in binary form must reproduce the above copyright notice, this
# list of conditions and the following disclaimer in the documentation and/or other
# materials provided with the distribution.
#
# Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
# contributors may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
# OF SUCH DAMAGE.
#
# Everyone should have this
.SUFFIXES:
# The output file name
TARGET = toad4
# This is necessary so that pk2cmd (used by 'load' script) is found and for the
# pk2cmd to find its support files (it seems to search current dir which is wrong)
PATH := ${PATH}
UPLOADER := java -cp ~/EazyCNC-Project/classes:/Volumes/Partition2/Users/nyholku/EazyCNC-Project/lib/purejavahidapi-0.0.12.jar:/Volumes/Partition2/Users/nyholku/EazyCNC-Project/lib/jna-5.6.0.jar diolanupdater.UpdateFirmware
ENCODER := /Volumes/Partition2/Users/nyholku/diolan-plus2/encoder/build/encoder
HEXMATE := /Applications/microchip/xc8/v2.32/pic/bin/hexmate
# The source files that make up the project go here
SRCS = main.c toad4.c usb_hid.c usb_core.c usb_pic_defs.c usb_user_config.c command_queue.c crt0iz_toad4.c swuart.c
# The libraries that are used go here
LIBS = libc18f.lib libm18f.lib libsdcc.lib
# Where to find the compiler
SDCC = /Volumes/Partition2/Users/nyholku/sdcc340/bin/sdcc
# Compiler flags go here
# --use-crt=crt0.o TOAD_HW_VERSION
SDCCFLAGS = "-Wl -f 0xffff" -DTOAD_HW_VERSION=${HWVERSION} --verbose --no-crt --ivt-loc=0x800 -V -L /Volumes/Partition2/Users/nyholku/sdcc340/non-free/lib/pic16 -Wa,-S,0 -Wl,-m,-s18f45k50.lkr -mpic16 -p18f45k50 --disable-warning 85 --std-sdcc99 --obanksel=3 --use-non-free
# Where to store the target/intermediate/temporary/object files
OBJDIR = ../obj
#-------------------------------------------------------------------------------
#
.PHONY: toad4
toad4: $(OBJDIR)/$(TARGET).hex
toad4: HI_SPEED_IRQ_ASM :=hi_speed_irq-hw4.asm
toad4: HWVERSION := HW4
toad4: BOOTLOADER := ../diolan-plus2-toad4/fw/bootloader.hex
.PHONY: toad5
toad5: HI_SPEED_IRQ_ASM :=hi_speed_irq.asm
toad5: HWVERSION := HW5
toad5: BOOTLOADER := ../diolan-plus2-toad5/fw/bootloader.hex
toad5: $(OBJDIR)/$(TARGET).hex
#
#-------------------------------------------------------------------------------
.PHONY: load
load:
$(UPLOADER) $(OBJDIR)/$(TARGET)-encoded.hex
#-------------------------------------------------------------------------------
.PHONY: comparebootloaders
comparebootloaders:
$(HEXMATE) -o$../bootloader-backedp.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,/Volumes/Partition2/Users/nyholku/diolan-plus2/fw-backup-25.7.2017/bootloader.hex r000802-FFFFFF,/Volumes/Partition2/Users/nyholku/diolan-plus2/fw-backup-25.7.2017/bootloader.hex
$(HEXMATE) -o$../bootloader-toad4.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,../diolan-plus2-toad4/fw/bootloader.hex r000802-FFFFFF,../diolan-plus2-toad4/fw/bootloader.hex
$(HEXMATE) -o$../bootloader-toad5.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,../diolan-plus2-toad5/fw/bootloader.hex r000802-FFFFFF,../diolan-plus2-toad5/fw/bootloader.hex
#
#
#-------------------------------------------------------------------------------
#
# This ensures that the object directory exists and re-creates it if necessary
#
# This requires make 3.81 or later, delete this section and all expressions that
# refer to .f if you have an older make
#
.SECONDEXPANSION:
# Uses a .f file as a flag file in each directory
%/.f:
mkdir -p $(dir $@)
touch $@
# dont' let make remove the flag files automatically
.PRECIOUS: %/.f
#
#-------------------------------------------------------------------------------
#
# Actual rules
#
# Compile the C-files
$(OBJDIR)/%.o: %.c $$(@D)/.f
@echo $(PATH)
$(SDCC) -c $(SDCCFLAGS) $< -o $@
KEY=${TOAD4PLUS_DIALON_KEY2}
# Link the compiled files and libraries
$(OBJDIR)/$(TARGET).hex: $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) $(OBJDIR)/hi_speed_irq.o
$(SDCC) $(SDCCFLAGS) -o $(OBJDIR)/$(TARGET).hex $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) $(LIBS) $(OBJDIR)/hi_speed_irq.o
# normalize the code filling un-used code memory with 0xFF so that encoding always works on known data
$(HEXMATE) -o$(OBJDIR)/$(TARGET)-normalized.hex -fill=0xFF@0x0800:0x7FFF r0800-7FFF,$(OBJDIR)/$(TARGET).hex
# sanitise the bootloader by keeping only the first 2kB (there is an extra jump code at 0x800 which overlaps with firmware code)
$(HEXMATE) -o$(OBJDIR)/bootloader-normalized.hex -fill=0xFF@0x0000:0x07FF r0000-07FF,$(BOOTLOADER) r000802-FFFFFF,$(BOOTLOADER)
# combine the bootloader and firmware to one hex file that can be programmed with pickit ready to run
$(HEXMATE) -o$(OBJDIR)/$(TARGET)-pickit.hex -fill=0xFFFF@0xF00001:0xF000FF -fill=0xA5@0xF00000:0xF00000 -fill=0x00@0x300000:0x30000D $(OBJDIR)/$(TARGET)-normalized.hex ../obj/bootloader-normalized.hex
# encode the bootloader for bootloading purposes, suppress output so as NOT to reveal the secret key
$(ENCODER) -ix $(OBJDIR)/$(TARGET)-normalized.hex -ox $(OBJDIR)/$(TARGET)-encoded.hex -e ${TOAD4PLUS_DIALON_KEY2}
# upload the encoded hex file using the bootload process
$(UPLOADER) $(OBJDIR)/$(TARGET)-encoded.hex
# Compile the high speed interrupt asm file
$(OBJDIR)/hi_speed_irq.o: ${HI_SPEED_IRQ_ASM}
gpasm -D TOAD_HW_VERSION=${HWVERSION} -o $(OBJDIR)/hi_speed_irq.o -c ${HI_SPEED_IRQ_ASM}
#
#-------------------------------------------------------------------------------
#
# Automatic generation of dependencies
#
# This magic code fragment from GNU make manual uses the SDCC compiler -M option
# to create a Makefile fragment for each C-source file describing the dependencies.
#
# Traditionally these fragments have the type '.d' but SDCC seems to delete them
# when it compiles files, so I use '.dep' here.
#
# Also SDCC '-M' option produces wrong dependency for the file being compiled
# in the sense that it does not contain the path, only the filename. Hence
# the 'sed' command has been mangled to inject the missing path to the fragment.
#
# First include the dependencies
include $(addprefix $(OBJDIR)/, $(SRCS:.c=.dep))
# Then recreate them
$(OBJDIR)/%.dep: %.c $$(@D)/.f
set -e; rm -f $@; \
$(SDCC) -c -M $(SDCCFLAGS) $< > $@.$$$$; \
sed -e '1 s,^,$(OBJDIR)/,' -e 's,\($*\)\.o[ :]*,.o $@ : ,g' < $@.$$$$ > $@; \
rm -f $@.$$$$
#------------------------------------------------------------------------------
#
# pretty standard default target
#
all: toad5
#
#-------------------------------------------------------------------------------
#
# pretty standard clean that attempts to delete all that this Makefile may left behind
#
clean:
rm -f $(OBJDIR)/*.rel
rm -f $(OBJDIR)/*.lnk
rm -f $(OBJDIR)/*.S19
rm -f $(OBJDIR)/*.map
rm -f $(OBJDIR)/*.mem
rm -f $(OBJDIR)/*.asm
rm -f $(OBJDIR)/*.rst
rm -f $(OBJDIR)/*.sym
rm -f $(OBJDIR)/*.lst
rm -f $(OBJDIR)/*.o
rm -f $(OBJDIR)/*.dep
rm -f $(OBJDIR)/*.hex
#
# cleanall deletes all in the object directory, do not use this if target dir == source dir
cleanall:
rm $(OBJDIR)/*
#-------------------------------------------------------------------------------
特定于目标的变量继承流经先决条件依赖图。这就是您在这里所依赖的:当目标作为 toad4
的先决条件构建时,它会获得一组选项,而当它作为 toad5
的先决条件构建时,它会获得一组不同的选项。
但是,当您构建依赖文件时,配方不是 运行 作为 toad4
或 toad5
的先决条件:如手册中所述,依赖文件是作为解析 makefile 的一部分由 make 构建,因为您 include
d 那些依赖文件。因此,设置了 none 个特定于目标的变量。
退一步说,我不清楚你认为这将如何工作。您有两组不同的先决条件,但您试图将它们都保存在同一个文件中:这永远行不通。唯一正确的方法是,如果您每次调用 make 时都重建所有先决条件,那么它们对于这个特定 make 想要构建的任何目标都是准确的,但是当然 makefile 中的所有内容都会过时因此每次都会重建所有内容。
对于想要从同一个 makefile 构建两组不同目标的 makefile 的正确答案是构建两个 不同 组目标,而不是同一组目标有不同的旗帜。具体来说,您应该有两个不同的对象目录,并将一个构建生成的文件放在一个对象目录中(例如 obj-toad4
),将另一个构建生成的文件放在另一个对象目录中(例如 obj-toad5
).这样他们就不会混淆,并且 make 可以分辨出哪些是过时的,哪些不是。
此外,GNU make 手册中描述的处理自动先决条件的方法已过时。您应该考虑此处描述的方法:http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/