CXXSRC = $(shell find source -iname "*.cpp")
CXXSRCFN = $(notdir $(CXXSRC))
CXXOBJ = $(CXXSRCFN:%.s=output/obj/%.cpp.o)
OUTPUT = output/kernel.elf.PHONY: builduserspace clean allall: $(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 $@) $<
Это make-файл. Вот ситуация, представьте эту структуру каталогов:
output
|
|-- obj
source
|
|-- file1.cpp
|-- file2.cpp
|-- subdirectory
|
|-- file3.cpp
Скажем, я запускаю make в корневой папке (где находятся выход и источник). Целевым выходом является output / kernel.elf.
По сути, я хочу, чтобы все файлы в папке ‘source’ были скомпилированы в объектные файлы и помещены в папку output / obj.
Мне удалось получить переменные о правильном; CXXSRC — это просто список всех исходных файлов для компиляции; CXXOBJ — это список выходов.
Тем не менее, сделать: * Нет правила, чтобы сделать цель output/obj/file.cpp.o', needed by
выход / kernel.elf. Стоп.
После некоторых проб и ошибок мне удалось сузить вопрос: если я изменю цель так:
output/obj/%.cpp.o: source/subdirectory/%.cpp
Это работает нормально (то есть. Это ошибки на других файлах в моем дереве, потому что не все файлы находятся в подкаталоге)
Очевидно, что это отрицательно скажется на цели оператора% wildcard, так как мне решить эту проблему?
Благодарю.
Первый ТАК пост, полегче на меня (:
Короткий ответ: ты не можешь. В шаблонном правиле шаблон (%
) должно быть идентичным (по строкам) между целью и предварительным условием. Это не может означать «что-то вроде, но не совсем то же самое».
Я думаю, что немного неприятно собирать исходные файлы из нескольких разных каталогов и помещать вывод в один каталог. Каждый раз, когда я видел, что это сделано, это становилось большой проблемой (потому что люди иногда используют одно и то же имя исходного файла, и у вас возникает беспорядок).
Если вы действительно хотите это сделать, у вас нет выбора, кроме как объявить несколько правил с разными исходными каталогами. Есть способы сделать это в make-файле, не записывая их все вручную, но они несколько более продвинуты.
Других решений пока нет …