C Make忽略隐式规则依赖关系
在这个部分生成文件中,当我在没有参数的情况下执行make并禁用.PHONY时,它返回: make:对于“调试”不做任何操作 启用.PHONY(或make-r)后,它将转到“build”,而不生成任何对象文件,因此GCC无法打开任何对象文件,因为目标目录中还没有对象文件 arm none eabi gcc:错误: obj/debug/ThirdParty/stm32f1x\u HAL\u Driver/Src/stm32f1x\u HAL\u adc.o:否 这样的文件或目录 此makefile将obj分离到文件夹obj/debug或obj/release中 文件结构:C Make忽略隐式规则依赖关系,c,makefile,gnu-make,C,Makefile,Gnu Make,在这个部分生成文件中,当我在没有参数的情况下执行make并禁用.PHONY时,它返回: make:对于“调试”不做任何操作 启用.PHONY(或make-r)后,它将转到“build”,而不生成任何对象文件,因此GCC无法打开任何对象文件,因为目标目录中还没有对象文件 arm none eabi gcc:错误: obj/debug/ThirdParty/stm32f1x\u HAL\u Driver/Src/stm32f1x\u HAL\u adc.o:否 这样的文件或目录 此makefile将
bin
inc
Src
ThirdParty // thirdparty source files
obj // mkdir -p should create this directories tree
debug
Src
ThirdParty
release
...
Makefile
.PHONY: build debug release clean $(COBJ) $(SOBJ)
# Main target
debug: CC_FLAGS += $(DEBUG)
debug: ELF = debug.elf
debug: OBJPATH = obj/debug
debug: COBJ = $(patsubst ./%,$(OBJPATH)/%,$(C:.c=.o)) # C contains c code
debug: SOBJ = $(patsubst ./%,$(OBJPATH)/%,$(S:.s=.o)) # S contains asm code
debug: build
release: CC_FLAGS += $(RELEASE)
release: OBJPATH = obj/release
release: COBJ = $(patsubst ./%,$(OBJPATH)/%,$(C:.c=.o))
release: SOBJ = $(patsubst ./%,$(OBJPATH)/%,$(S:.s=.o))
release: ELF = release.elf
release: build
build: $(COBJ) $(SOBJ)
$(CC) $(COBJ) $(SOBJ) $(LIBS) $(LD_FLAGS) -o bin/$(ELF)
%.o: %.c
echo $@
@mkdir -p $(OBJPATH)/$(dir $@)
$(CC) $(CC_FLAGS) -c $< -o $(OBJPATH)/$@
%.o: %.s
@mkdi -p $(OBJPATH)/$(dir $@)
$(CC) $(CC_FLAGS) -c $< -o $(OBJPATH)/$@
.PHONY:build-debug-release-clean$(COBJ)$(SOBJ)
#主要目标
调试:CC_标志+=$(调试)
调试:ELF=debug.ELF
调试:OBJPATH=obj/debug
调试:COBJ=$(patsubst./%,$(OBJPATH)/%,$(C:.C=.o))#C包含C代码
调试:SOBJ=$(patsubst./%,$(OBJPATH)/%,$(S:.S=.o))#S包含asm代码
调试:构建
发布:CC_标志+=$(发布)
发布:OBJPATH=obj/release
发布:COBJ=$(patsubst./%,$(OBJPATH)/%,$(C:.C=.o))
发布:SOBJ=$(patsubst./%,$(OBJPATH)/%,$(S:.S=.o))
release:ELF=release.ELF
发布:构建
构建:$(COBJ)$(SOBJ)
$(CC)$(COBJ)$(SOBJ)$(LIBS)$(LD_标志)-o bin/$(ELF)
%.o:%.c
回音$@
@mkdir-p$(OBJPATH)/$(dir$@)
$(CC)$(CC_标志)-c$<-o$(OBJPATH)/$@
%.o:%.s
@mkdi-p$(OBJPATH)/$(dir$@)
$(CC)$(CC_标志)-c$<-o$(OBJPATH)/$@
$(COBJ)的一个样本:
obj/debug/ThirdParty/FreeRTOS/queue.o
Linux x86-64
GNU Make 4.2.1
Arm none eabi gcc-我认为这无关紧要关于特定于目标的变量,您缺少了一个关键注意事项: 与自动变量一样,这些值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中) 因此,在makefile中:
debug: COBJ = $(patsubst ./%,$(OBJPATH)/%,$(C:.c=.o)) # C contains c code
debug: SOBJ = $(patsubst ./%,$(OBJPATH)/%,$(S:.s=.o)) # S contains asm code
build: $(COBJ) $(SOBJ)
...
此时$(COBJ)
和$(SOBJ)
指的是COBJ
和SOBJ
变量的全局设置值(因为如上所述,目标特定值仅在配方中可用,而不在先决条件列表中)。这些变量没有全局值,因此它们扩展为空字符串,而您的makefile实际上只有:
build:
...
没有先决条件,这就是为什么你会看到自己的行为
您可以通过多种方式来管理它。一种是使用递归生成:删除release:build
和debug:build
行,并添加以下内容:
debug release:
@$(MAKE) COBJ='$(COBJ)' SOBJ='$(SOBJ)' build
另一种方法是使用(您不能按照我最初建议的方式执行,但可以使用构造的变量名执行:
OBJPREFIX := obj
COBJ = $(patsubst ./%,$(OBJPREFIX)/$@/%,$(C:.c=.o))
SOBJ = $(patsubst ./%,$(OBJPREFIX)/$@/%,$(S:.s=.o))
# Main target
debug: CC_FLAGS += $(DEBUG)
debug: ELF = debug.elf
release: CC_FLAGS += $(RELEASE)
release: ELF = release.elf
.SECONDEXPANSION:
release debug: $$(COBJ) $$(SOBJ)
$(CC) $(COBJ) $(SOBJ) $(LIBS) $(LD_FLAGS) -o bin/$(ELF)
这将使用输出对象名称中的目标名称
另一种方法是使用生成的makefile
你可以考虑在这里阅读一系列文章:(先从最老的一个开始)。
你忽略了关于目标特定变量的一个批注: 与自动变量一样,这些值仅在目标配方的上下文中可用(以及在其他特定于目标的分配中) 因此,在makefile中:debug: COBJ = $(patsubst ./%,$(OBJPATH)/%,$(C:.c=.o)) # C contains c code
debug: SOBJ = $(patsubst ./%,$(OBJPATH)/%,$(S:.s=.o)) # S contains asm code
build: $(COBJ) $(SOBJ)
...
此时$(COBJ)
和$(SOBJ)
指的是COBJ
和SOBJ
变量的全局设置值(因为如上所述,目标特定值仅在配方中可用,而不在先决条件列表中)。这些变量没有全局值,因此它们扩展为空字符串,而您的makefile实际上只有:
build:
...
没有先决条件,这就是为什么你会看到自己的行为
有多种方法可以管理此问题。一种是使用递归生成:删除release:build
和debug:build
行,然后添加以下内容:
debug release:
@$(MAKE) COBJ='$(COBJ)' SOBJ='$(SOBJ)' build
另一种方法是使用(您不能按照我最初建议的方式执行,但可以使用构造的变量名执行:
OBJPREFIX := obj
COBJ = $(patsubst ./%,$(OBJPREFIX)/$@/%,$(C:.c=.o))
SOBJ = $(patsubst ./%,$(OBJPREFIX)/$@/%,$(S:.s=.o))
# Main target
debug: CC_FLAGS += $(DEBUG)
debug: ELF = debug.elf
release: CC_FLAGS += $(RELEASE)
release: ELF = release.elf
.SECONDEXPANSION:
release debug: $$(COBJ) $$(SOBJ)
$(CC) $(COBJ) $(SOBJ) $(LIBS) $(LD_FLAGS) -o bin/$(ELF)
这将使用输出对象名称中的目标名称
另一种方法是使用生成的makefile
你可以考虑在这里阅读一系列文章:(首先从最老的一个开始)。<> > <强>疯狂科学家提到了目标特定变量的有限范围,我从MaFixFor文件中选择了一个选择器,并用目标=“目标”的参数运行如下:
make TARGET = debug
make TARGET = release
不是优雅而是实用
Makefile:
O = $(C:%.c=%.o)
O += $(S:%.s=%.o)
ifeq ($(TARGET), release)
ELF = bin/release.elf
CC_FLAGS += -O3
OBJPATH = obj/release
else
ELF = bin/debug.elf
CC_FLAGS += -g3
OBJPATH = obj/debug
endif
OBJ = $(addprefix $(OBJPATH)/, $(O))
all: makepath build
build: $(OBJ)
@echo ---- LINKING ----
$(CC) $(OBJ) $(LIBS) $(LD_FLAGS) -o $(ELF)
makepath:
@mkdir -p $(dir $(OBJ))
$(OBJPATH)/%.o:%.c
@echo ---- C ----
$(CC) $(CC_FLAGS) -c $< -o $@
$(OBJPATH)/%.o:%.s
@echo ---- S ----
$(CC) $(CC_FLAGS) -c $< -o $@
clean:
find -name *.o -delete
find -name *.elf -delete
O=$(C:%.C=%.O)
O+=$(S:%.S=%.O)
ifeq($(目标),发布)
ELF=bin/release.ELF
CC_标志+=-O3
OBJPATH=obj/释放
其他的
ELF=bin/debug.ELF
CC_标志+=-g3
OBJPATH=obj/debug
恩迪夫
OBJ=$(addprefix$(OBJPATH)/,$(O))
全部:makepath构建
构建:$(OBJ)
@回音链接----
$(CC)$(OBJ)$(LIBS)$(LD_标志)-o$(ELF)
生成路径:
@mkdir-p$(dir$(OBJ))
$(对象路径)/%.o:%.c
@回声——C----
$(CC)$(CC_标志)-c$<-o$@
$(对象路径)/%.o:%.s
@回声----
$(CC)$(CC_标志)-c$<-o$@
清洁:
查找-名称*.o-删除
查找-名称*.elf-删除
正如MadScientist提到的,我从makefile中拿出一个选择器,并使用target='target'参数运行make,如下所示:
make TARGET = debug
make TARGET = release
不是优雅而是实用
Makefile:
O = $(C:%.c=%.o)
O += $(S:%.s=%.o)
ifeq ($(TARGET), release)
ELF = bin/release.elf
CC_FLAGS += -O3
OBJPATH = obj/release
else
ELF = bin/debug.elf
CC_FLAGS += -g3
OBJPATH = obj/debug
endif
OBJ = $(addprefix $(OBJPATH)/, $(O))
all: makepath build
build: $(OBJ)
@echo ---- LINKING ----
$(CC) $(OBJ) $(LIBS) $(LD_FLAGS) -o $(ELF)
makepath:
@mkdir -p $(dir $(OBJ))
$(OBJPATH)/%.o:%.c
@echo ---- C ----
$(CC) $(CC_FLAGS) -c $< -o $@
$(OBJPATH)/%.o:%.s
@echo ---- S ----
$(CC) $(CC_FLAGS) -c $< -o $@
clean:
find -name *.o -delete
find -name *.elf -delete
O=$(C:%.C=%.O)
O+=$(S:%.S=%.O)
ifeq($(目标),发布)
ELF=bin/release.ELF
CC_标志+=-O3
OBJPATH=obj/释放
其他的
ELF=bin/debug.ELF
CC_标志+=-g3
OBJPATH=obj/debug
恩迪夫
OBJ=$(addprefix$(OBJPATH)/,$(O))
全部:makepath构建
构建:$(OBJ)
@回音链接----
$(CC)$(OBJ)$(LIBS)$(LD_标志)-o$(ELF)
生成路径:
@mkdir-p$(dir$(OBJ))
$(对象路径)/%.o:%.c
@回声——C----
$(CC)$(CC_标志)-c$<-o$@
$(对象路径)/%.o:%.s
@回声----
$(CC)$(CC_标志)-c$<-o$@
清洁:
查找-名称*.o-删除
查找-名称*.elf-删除
Arm none eabi gcc-我想这不需要