Question

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 $@) $<

That's the makefile. Here's the situation, imagine this directory structure:

output
|
|-- obj

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

Say I run make in the root folder (where output and source are). The target output is output/kernel.elf.

Essentially, I want all the files in the folder 'source' to be compiled into object files and placed into the folder output/obj.

I managed to get the variables about right; CXXSRC is simply the list of all source files to be compiled; CXXOBJ is the list of outputs.

However, make: * No rule to make target output/obj/file.cpp.o', needed byoutput/kernel.elf'. Stop.

After some trial and error, I managed to narrow down the issue: If I modify the target to this:

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

It works fine (ie. it errors on the other files in my tree, because not all files are in subdirectory)

Obviously this would defeat the purpose of the % wildcard operator, so how do I fix this problem?

Thanks. First SO post, take it easy on me (:

Was it helpful?

Solution

The short answer is, you can't. In a pattern rule the pattern (%) must be identical (string-wise) between the target and the prerequisite. It can't mean "something sort of, but not exactly, the same".

I think it's a bit unpleasant to compile source files from multiple different directories and put the output into a single directory. Every single time I've seen that done it's become a big problem (because people sometimes use the same source file name and then you have a mess).

If you really want to do it there's no choice but to declare multiple rules with the different source directories. There are ways to do this in the makefile without writing them all by hand, but they're somewhat more advanced.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top