LINUX.ORG.RU

Избегание дублирования кода в Makefile

 


0

2

Делаю эксперименты с RISC-V, написал мини-ОС на C++, которая работает в эмуляторе TinyEMU в Haiku, выглядит так. Для сборки и запуска написал Makefile:

CC = clang
CXX = clang++
AS = clang
LD = ld.lld -nostdlib

TARGETFLAGS = -target riscv64-linux -march=rv64imafdc -mcmodel=medium
CXXFLAGS += -fno-exceptions -fno-rtti -Iheaders -Ilibc/headers -I/boot/system/develop/tools/x86/lib/gcc/i586-pc-haiku/8.3.0/include/c++ -I/boot/system/develop/tools/x86/lib/gcc/i586-pc-haiku/8.3.0/include/c++/i586-pc-haiku
ASFLAGS += $(TARGETFLAGS)


Startup.bin: Startup
	llvm-objcopy -O binary Startup Startup.bin

Startup: Startup.ld objs/Startup.o objs/Vecs.o objs/Graphics.o objs/Font.o objs/Virtio.o objs/Threads.o objs/Timers.o libc/objs/setjmp.o libc/objs/string.o libc/objs/memcpy.o libc/objs/memset.o libc/objs/malloc.o Startup.ld
	$(LD) -T Startup.ld --export-dynamic objs/Startup.o objs/Vecs.o objs/Graphics.o objs/Font.o objs/Virtio.o objs/Threads.o objs/Timers.o libc/objs/setjmp.o libc/objs/string.o libc/objs/memcpy.o libc/objs/memset.o libc/objs/malloc.o -o Startup

objs/%.o: src/%.cpp
	$(CXX) $(TARGETFLAGS) $(CXXFLAGS) -MF"deps/$*.d" -MD -c $< -o $@
objs/%.o: src/%.S
	$(AS) $(TARGETFLAGS) $(ASFLAGS) -MF"deps/$*.d" -MD -c $< -o $@
libc/objs/%.o: libc/src/%.cpp
	$(CXX) $(TARGETFLAGS) $(CXXFLAGS) -MF"libc/deps/$*.d" -MD -c $< -o $@
libc/objs/%.o: libc/src/%.S
	$(AS) $(TARGETFLAGS) $(ASFLAGS) -MF"libc/deps/$*.d" -MD -c $< -o $@

run: Startup.bin
	temu -rw tinyemu.cfg

-include deps/*.d libc/deps/*.d

clean:
	rm -f objs/* deps/* libc/objs/* libc/deps/* Startup Startup.bin

В нём много дублирования кода. Есть способы сокращения дублирования? Autotools не предлагать.

★★★★★

Последнее исправление: X512 (всего исправлений: 2)

Ну во-первых асм можно через CC/CXX прогонять, во-вторых пользовать автоматы и ограничиться настройкой только переменных, а «-МF*» внести в переменные, тот же ЛД можно не трогать, а настроить LDFLAGS

AKonia ★★
()
Ответ на: комментарий от AKonia

во-вторых пользовать автоматы

Что за автоматы? Оно позволяет класть объектные файлы в отдельную директорию? По началу я не делал правил для *.S, *.cpp, но тогда всё скидывается в одну директорию и бардак получается.

X512 ★★★★★
() автор топика

Я что-то не пойму, где много дублирования? src/* и libc/src* — и всё?

Можно, например, перестать разбрасывать объектники по всему дереву, а наоборот — складывать их в иерархию внутри одной директории сборки. Тогда правила для сборки типов файлов можно будет писать только один раз.

$(BUILD)/obj/%.cpp.o: %.cpp
	@mkdir -p $(@D)
	$(CXX) $(TARGETFLAGS) $(CXXFLAGS) -MF"$(BUILD)/deps/$*.d" -MD -c $< -o $@


STARTUP_SRC += $(wildcard src/*.cpp)
STARTUP_SRC += $(wildcard libc/src/*.cpp)

STARTUP_OBJ = $(patsubst %, $(BUILD)/obj/%.o, $(STARTUP_SRC))

$(BUILD)/Startup: $(STARTUP_OBJ) Startup.ld
	@mkdir -p $(@D)
	$(LD) -T Startup.ld --export-dynamic $(filter %.o, $^) -o $@

clean:
	rm -rf $(BUILD)
ilammy ★★★
()
Последнее исправление: ilammy (всего исправлений: 2)
Ответ на: комментарий от X512

В мэйке, есть встроенные правила для сборки и например add.o sub.o: math.h сам найдёт add.c и sub.c файлы и сам скомпилирует соответствующие объекты

AKonia ★★
()
Последнее исправление: AKonia (всего исправлений: 2)
Ответ на: комментарий от AKonia

сам найдёт add.c и sub.c файлы и сам скомпилирует соответствующие файлы

И положит рядом с исходником, что нежелательно т.к. создаёт помойку и затрудняет навигацию по исходникам.

X512 ★★★★★
() автор топика
Ответ на: комментарий от ilammy

Тогда правила для сборки типов файлов можно будет писать только один раз.

А если в разных поддиректориях есть исходники с одинаковыми именами?

X512 ★★★★★
() автор топика

Autotools не предлагать.

а зря :) всё равно предложу

Harald ★★★★★
()
Ответ на: комментарий от X512

Не помню, вроде тоже как-то можно подправить, нужно руководство смотреть, как вариант просто напилить локальный сценарий и его запускать из другого мэйкфайла, который расположить в папке build, вообще сам для подобного беру premake, ставлю location и objdir, попробуйте, он достойные мэйкфайлы вырабатывает.

AKonia ★★
()
Ответ на: комментарий от X512

А если в разных поддиректориях есть исходники с одинаковыми именами?

Потому и весь путь с поддиректорией включается, чтобы было

  • src/foo.cpp => obj/src/foo.cpp.o
  • src/lib/foo.cpp => obj/src/lib/foo.cpp.o

и не было конфликтов имён.

ilammy ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.