Search
Volání kompilátoru je vhodné minimálně dokumentovat a lépe zautomatizovat. Jednou z možností je vytvořit skript pro shell (na GNU/Linuxu obvykle BASH nebo DASH). Při překladu větších projektů je ale nepraktické překládat všechny kompilační jednotky opakovaně, když dojde k malé změně jen v některém ze zdrojových souborů. proto bylo vytvořeno množství programů speciálně navržených pro účel překladu a sestavení programu (Make, Ant, qmake, Cmake, meson, atd.).
Make je nástroj pro automatickou kompilaci zdrojových kódů, potřebná konfigurace je uložena v souboru Makefile.
Makefile šablona pro překlad zdrojového kódu v assembleru:
ARCH=riscv64-unknown-elf SOURCES = change_me.S TARGET_EXE = change_me CC=$(ARCH)-gcc CXX=$(ARCH)-g++ AS=$(ARCH)-as LD=$(ARCH)-ld OBJCOPY=$(ARCH)-objcopy ARCHFLAGS += -mabi=ilp32 ARCHFLAGS += -march=rv32i ARCHFLAGS += -fno-lto CFLAGS += -ggdb -Os -Wall CXXFLAGS+= -ggdb -Os -Wall AFLAGS += -ggdb LDFLAGS += -ggdb LDFLAGS += -nostartfiles LDFLAGS += -nostdlib LDFLAGS += -static #LDFLAGS += -specs=/opt/musl/riscv64-linux-gnu/lib/musl-gcc.specs CFLAGS += $(ARCHFLAGS) CXXFLAGS+= $(ARCHFLAGS) AFLAGS += $(ARCHFLAGS) LDFLAGS += $(ARCHFLAGS) OBJECTS += $(filter %.o,$(SOURCES:%.S=%.o)) OBJECTS += $(filter %.o,$(SOURCES:%.c=%.o)) OBJECTS += $(filter %.o,$(SOURCES:%.cpp=%.o)) all : default .PHONY : default clean dep all %.o:%.S $(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@ %.o:%.c $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ %.o:%.cpp $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $< %.s:%.c $(CC) $(CFLAGS) $(CPPFLAGS) -S $< -o $@ default : $(TARGET_EXE) $(TARGET_EXE) : $(OBJECTS) $(CC) $(LDFLAGS) $^ -o $@ dep: depend depend: $(SOURCES) $(glob *.h) echo '# autogenerated dependencies' > depend ifneq ($(filter %.S,$(SOURCES)),) $(CC) -D__ASSEMBLY__ $(AFLAGS) -w -E -M $(filter %.S,$(SOURCES)) \ >> depend endif ifneq ($(filter %.c,$(SOURCES)),) $(CC) $(CFLAGS) $(CPPFLAGS) -w -E -M $(filter %.c,$(SOURCES)) \ >> depend endif ifneq ($(filter %.cpp,$(SOURCES)),) $(CXX) $(CXXFLAGS) $(CPPFLAGS) -w -E -M $(filter %.cpp,$(SOURCES)) \ >> depend endif clean: rm -f *.o *.a $(OBJECTS) $(TARGET_EXE) depend #riscv64-unknown-elf --source change_me -include depend
Sestavovací soubor Makefile se sestává z definic (přiřazení hodnot proměnným) a pravidel. Pravidla začínají řádkou, která určuje závislost cílů na jejich závislostech uvedených za dvojtečkou. Pravidla mohou přímo uvádět jména souborů nebo mohou být obecná, kdy zástupným znakem pro doplňovanou část jména je znak procento “%”. Kompletnější šablonu pro překlad na cílovou architekturu RISC-V i s nalezením závislostí na hlavičkových souborech naleznete na počítačích v laboratoři v adresáři /opt/apo/qtrvsim_template.
/opt/apo/qtrvsim_template
Kompilace probíhá příkazem make (příkaz make je nutné zadávat v adresáři, ve kterém je upravený Makefile a zdrojový kód programu). Make vygeneruje několik souborů, z nichž pro import do simulačního prostředí QtRvSim použijeme soubor bez koncovky. Překlad nejdříve převádí kompilační jednotky (jednotka je zjednodušeně jeden zdrojový soubor včetně vložených hlavičkových souborů) do objektového tvaru (.o) v relokovatelné podobě. Objektové soubory jsou linkerem složeny, vzájemné reference/odkazy vyřešeny a provedeno umístění na finální adresy. Pro uložení vlastních instrukcí strojového kódu je potřeba přidat obálku s informacemi, kde je potřeba kód upravit při konečném umístění .o souborů. Data a instrukce v konečném spustitelném tvaru je také potřeba doplnit informací na které adresy má být daná část/sekce umístěna. K uložení těchto informací je v našem případě a obecně na většině standardům odpovídajících systémů použitý formát ELF (Executable and Linkable Format).
.o
Zjištění adres, na které byly jednotlivé funkce a datové položky linkerem umístěny lze zjistit
riscv64-unknown-elf-nm program
Rozmístění sekcí
riscv64-unknown-elf-objdump --headers program
Porovnání vstupu a výsledku překladu
riscv64-unknown-elf-objdump --source program