Makefile 函数“通配符”不';看不见$@

Makefile 函数“通配符”不';看不见$@,makefile,Makefile,我有以下Makefile: .PHONY:一切正常运行 INC_DIR=包括 SRC_DIR=SRC KERNEL\u NAME=mykernel AS=AS 天冬氨酸=--32 CXX=g++ CXXPARAMS=-m32-ffreestanding-fno异常-fno rtti-I$(INC_DIR) #CXXPARAMS=-m32-fno使用cxa atexit-NOTDLIB-fno内置-fno rtti-fno异常-fno前导下划线-I$(INC_DIR) LDPARAMS=-melf

我有以下
Makefile

.PHONY:一切正常运行
INC_DIR=包括
SRC_DIR=SRC
KERNEL\u NAME=mykernel
AS=AS
天冬氨酸=--32
CXX=g++
CXXPARAMS=-m32-ffreestanding-fno异常-fno rtti-I$(INC_DIR)
#CXXPARAMS=-m32-fno使用cxa atexit-NOTDLIB-fno内置-fno rtti-fno异常-fno前导下划线-I$(INC_DIR)
LDPARAMS=-melf_i386
BUILD\u DIR=BUILD
ISO_DIR=$(BUILD_DIR)/ISO
ISO_BOOT=$(ISO_DIR)/BOOT
GRUB_CONFIG=$(ISO_引导)/GRUB/GRUB.cfg
SRC=$(通配符$(SRC_DIR)/*.cpp)
SRC+=$(通配符$(SRC_DIR)/***.cpp)
SRC+=$(通配符$(SRC_DIR)/*.s)
OBJS=$(SRC:=.o)
OBJS:=$(addprefix$(BUILD_DIR)/,$(OBJS))
.SECONDARY:$(OBJS)
全部:$(内核名称).iso
运行:$(内核名称).iso
qemu-system-i386-cdrom$<
$(KERNEL\u NAME).iso:$(GRUB\u CONFIG)$(iso\u BOOT)/$(KERNEL\u NAME).bin
grub MKSERCUE-o$@$(ISO_目录)
$(ISO_BOOT)/$(KERNEL_NAME).bin:$(SRC_DIR)/linker.ld$(OBJS)
ld$(LDPARAMS)-T$^-o$@-nostdlib
$(GRUB_配置):
mkdir-p$(dir$@)
echo“设置超时=0”>$(GRUB_配置)
echo'设置默认值=0'>>$(GRUB\U配置)
回声'>>$(GRUB\U配置)
echo'menuentry'$(内核名称)操作系统“{'>>$(GRUB\U配置)
echo'multiboot2/boot/$(内核名称).bin'>>$(GRUB\U配置)
echo'boot'>>$(GRUB_配置)
echo'}'>>$(GRUB_配置)
$(构建目录)/%.cpp.o:%.cpp
echo$(dir$@)
echo$(通配符(dir$@))
#ifeq($(通配符(dir$@)),)
#回声“mkdir-p$(dir$@)”;
#$(CXX)$(CXX参数)$<-c-o$@
#恩迪夫
$(构建目录)/%.s.o:%.s
@如果[!-d$(dir$@)];然后\
回声“mkdir-p$(dir$@)”\
mkdir-p$(dir$@)\
fi
$(AS)$(ASPARAMS)$<-o$@
清洁:
rm-rf$(内核名称).iso$(构建目录)
为什么我通过运行
make
,以空
echo
获取输出?目录
build/src
存在

echo build/src/
build/src/
echo 

echo build/src/
build/src/
echo 

echo build/src/
build/src/
echo 

echo build/src/
build/src/
echo 

echo build/src/
build/src/
echo 

echo build/src/
build/src/
echo 

echo build/src/gui/
build/src/gui/
echo 

echo build/src/gui/
build/src/gui/
echo 

ld -melf_i386 -T src/linker.ld build/src/Keyboard.cpp.o build/src/VGArray.cpp.o build/src/mykernel.cpp.o build/src/TextCursor.cpp.o build/src/VideoContext.cpp.o build/src/GDTable.cpp.o build/src/gui/DrawContext.cpp.o build/src/gui/Window.cpp.o build/src/loader.s.o -o build/iso/boot/mykernel.bin -nostdlib
ld: cannot find build/src/Keyboard.cpp.o: No such file or directory
ld: cannot find build/src/VGArray.cpp.o: No such file or directory
ld: cannot find build/src/mykernel.cpp.o: No such file or directory
ld: cannot find build/src/TextCursor.cpp.o: No such file or directory
ld: cannot find build/src/VideoContext.cpp.o: No such file or directory
ld: cannot find build/src/GDTable.cpp.o: No such file or directory
ld: cannot find build/src/gui/DrawContext.cpp.o: No such file or directory
ld: cannot find build/src/gui/Window.cpp.o: No such file or directory
Makefile:33: recipe for target 'build/iso/boot/mykernel.bin' failed
make: *** [build/iso/boot/mykernel.bin] Error 1

我试着做一个简单的例子,但当
build
目录存在时,它就可以正常工作

.PHONY: all clean

CXX = g++
OPTS =  -Wall -Wextra
BUILD_DIR = build
APP = $(BUILD_DIR)/main
SRC_DIR = src
SRC = $(wildcard $(SRC_DIR)/*.cpp)

all: $(APP)

$(APP): $(APP).o
    
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
    echo $(dir $@)
    echo $(wildcard $(dir $@))

clean:
    rm -rf $(BUILD_DIR) main *.o 
echo$(通配符(dir$@))
替换为
echo$(通配符$(dir$@))
,事情应该按照您的预期进行

注意:
SRC+=$(通配符$(SRC_DIR)/***.cpp)
不会在子目录中递归。如果您认为会,请尝试:

SRC = $(shell find $(SRC_DIR) -type f -name '*.cpp')
SRC += $(wildcard $(SRC_DIR)/*.s)

错误消息实际上是,在您尝试构建build/iso/boot/mykernel.bin时,这些.cpp.o文件不存在。这通常缺少一个缺少的依赖项。$(ISO_BOOT)/$(KERNEL_NAME).bin目标中的$(OBJS)是什么?另外,请提供一个简单的例子,最好是一个更具体的问题,与“为什么我得到输出”相对应。@AllanWind,我尝试了一个简单的例子,但效果很好。太好了!它起作用了。谢谢你的来信。