使用通配符模式无法找到目标

时间:2013-12-19 18:08:07

标签: c++ makefile wildcard target

CXXSRC            = $(shell find source -iname "*.cpp")
CXXSRCFN          = $(notdir $(CXXSRC))
CXXOBJ            = $(CXXSRCFN:%.s=output/obj/%.cpp.o)

OUTPUT            = output/kernel.elf


.PHONY: builduserspace clean all



all: $(OUTPUT)
    @$(QEMU) -vga std -serial file:"output/serialout.log" -m 20 -hda output/disk.img -rtc base=localtime


$(OUTPUT): $(CXXOBJ)
    # Linking object files...
    @$(LD) $(LDFLAGS) -o output/temp.elf output/obj/Start.s.o $(shell find output/obj -name "*.o" ! -name "Start.s.o") -Lgcc

    # Performing objcopy...
    @$(OBJCOPY) -O elf32-i386 output/temp.elf output/kernel.elf


%.cpp.o: %.cpp
    @echo $(notdir $<)
    @$(CXX) $(CXXFLAGS) -o $(notdir $@) $<

那是makefile。这是情况,想象一下这个目录结构:

output
|
|-- obj

source
|
|-- file1.cpp
|-- file2.cpp
|-- subdirectory
    |
    |-- file3.cpp

假设我在根文件夹中运行make(输出和源代码在那里)。目标输出是output / kernel.elf。

基本上,我希望将文件夹'source'中的所有文件编译成目标文件并放入文件夹output / obj中。

我设法得到关于正确的变量; CXXSRC只是要编译的所有源文件的列表; CXXOBJ是输出列表。

但是,make: * 没有规则可以使目标output/obj/file.cpp.o', needed by输出/ kernel.elf'。停止。

经过一些反复试验,我设法缩小了问题的范围:如果我将目标修改为:

output/obj/%.cpp.o: source/subdirectory/%.cpp

它运行正常(即它在我树中的其他文件上出错,因为并非所有文件都在子目录中)

显然这会破坏%通配符运算符的用途,那么如何解决这个问题?

感谢。 第一篇SO帖子,对我很轻松(:

1 个答案:

答案 0 :(得分:1)

简短的回答是,你做不到。在模式规则中,模式(%)必须在目标和先决条件之间相同(按字​​符串)。它并不意味着“某种东西,但不完全相同”。

我认为从多个不同的目录编译源文件并将输出放到一个目录中有点不愉快。每次我看到它完成它都会成为一个大问题(因为人们有时会使用相同的源文件名,然后你就会一团糟)。

如果你真的想这样做,除了用不同的源目录声明多个规则之外别无选择。

可以在makefile中执行此操作,而无需手动编写所有内容