neorv32/sw/common/common.mk
stnolting 3e4899210f
Some checks failed
Documentation / SW Framework (push) Has been cancelled
Documentation / Datasheet (push) Has been cancelled
Processor / processor simulation (push) Has been cancelled
Documentation / Deploy to Releases and Pages (push) Has been cancelled
[sw/common] generalize system tools
2025-04-13 21:02:24 +02:00

474 lines
18 KiB
Makefile

# ================================================================================ #
# NEORV32 Application Software Makefile #
# -------------------------------------------------------------------------------- #
# Do not edit this file! Use the re-defines in the project-local makefile instead. #
# -------------------------------------------------------------------------------- #
# The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 #
# Copyright (c) NEORV32 contributors. #
# Copyright (c) 2020 - 2025 Stephan Nolting. All rights reserved. #
# Licensed under the BSD-3-Clause license, see LICENSE for details. #
# SPDX-License-Identifier: BSD-3-Clause #
# ================================================================================ #
# -----------------------------------------------------------------------------
# Default configuration (DO NOT EDIT THIS FILE! REDEFINE / OVERRIDE THE DEFAULT
# CONFIGURATION WHEN INCLUDING THIS MAKEFILE IN THE PROJECT-SPECIFIC MAKEFILE)
# -----------------------------------------------------------------------------
# User's application sources (*.c, *.cpp, *.s, *.S); add additional files here
APP_SRC ?= $(wildcard ./*.c) $(wildcard ./*.s) $(wildcard ./*.cpp) $(wildcard ./*.S)
# User's application object files (*.o, *.cpp, *.s, *.S); add additional files here
APP_OBJ ?=
# User's application include folders (don't forget the '-I' before each entry)
APP_INC ?= -I .
# User's application include folders - for assembly files only (don't forget the '-I' before each entry)
ASM_INC ?= -I .
# Build folder for output
BUILD_DIR ?= build
# Optimization
EFFORT ?= -Os
# Compiler toolchain prefix
RISCV_PREFIX ?= riscv-none-elf-
# CPU architecture and ABI
MARCH ?= rv32i_zicsr_zifencei
MABI ?= ilp32
# User flags for additional configuration (will be added to compiler flags)
USER_FLAGS ?=
# Relative or absolute path to the NEORV32 home folder
NEORV32_HOME ?= ../../..
# GDB arguments
GDB_ARGS ?= -ex "target extended-remote localhost:3333"
# GHDL simulation run arguments
GHDL_RUN_FLAGS ?=
# -----------------------------------------------------------------------------
# NEORV32 framework
# -----------------------------------------------------------------------------
# Path to NEORV32 linker script and startup file
NEORV32_COM_PATH = $(NEORV32_HOME)/sw/common
# Path to main NEORV32 library include files
NEORV32_INC_PATH = $(NEORV32_HOME)/sw/lib/include
# Path to main NEORV32 library source files
NEORV32_SRC_PATH = $(NEORV32_HOME)/sw/lib/source
# Path to NEORV32 executable generator
NEORV32_EXG_PATH = $(NEORV32_HOME)/sw/image_gen
# Path to NEORV32 rtl folder
NEORV32_RTL_PATH = $(NEORV32_HOME)/rtl
# Path to NEORV32 sim folder
NEORV32_SIM_PATH = $(NEORV32_HOME)/sim
# Core libraries (peripheral and CPU drivers)
CORE_SRC = $(wildcard $(NEORV32_SRC_PATH)/*.c)
# Application start-up code
CORE_SRC += $(NEORV32_COM_PATH)/crt0.S
# Linker script
LD_SCRIPT ?= $(NEORV32_COM_PATH)/neorv32.ld
# Main output files
APP_EXE = neorv32_exe.bin
APP_ELF = main.elf
APP_HEX = neorv32_raw_exe.hex
APP_BIN = neorv32_raw_exe.bin
APP_COE = neorv32_raw_exe.coe
APP_MEM = neorv32_raw_exe.mem
APP_MIF = neorv32_raw_exe.mif
APP_ASM = main.asm
APP_VHD = neorv32_application_image.vhd
BOOT_VHD = neorv32_bootloader_image.vhd
# Binary main file
BIN_MAIN = $(BUILD_DIR)/main.bin
# Define all sources
SRC = $(APP_SRC)
SRC += $(CORE_SRC)
# Define search path for prerequisites
VPATH = $(sort $(dir $(SRC)))
# Define all object files
OBJ := $(patsubst %,$(BUILD_DIR)/%.o,$(notdir $(SRC)))
OBJ += $(APP_OBJ)
# -----------------------------------------------------------------------------
# Tools and flags
# -----------------------------------------------------------------------------
# Compiler tools
CC = $(RISCV_PREFIX)gcc
OBJDUMP = $(RISCV_PREFIX)objdump
OBJCOPY = $(RISCV_PREFIX)objcopy
READELF = $(RISCV_PREFIX)readelf
SIZE = $(RISCV_PREFIX)size
GDB = $(RISCV_PREFIX)gdb
# Host's native compiler
CC_HOST = gcc -Wall -O -g
# System tools
ECHO = @echo
SET = set
CP = cp
RM = rm
MKDIR = mkdir
SH = sh
WC = wc
# NEORV32 executable image generator
IMAGE_GEN = $(NEORV32_EXG_PATH)/image_gen
ifeq ($(OS),Windows_NT)
IMAGE_GEN := $(IMAGE_GEN).exe
endif
# Compiler & linker flags
CC_FLAGS = -march=$(MARCH) -mabi=$(MABI) $(EFFORT) -Wall -ffunction-sections -fdata-sections -nostartfiles -mno-fdiv
CC_FLAGS += -mstrict-align -mbranch-cost=10 -Wl,--gc-sections -ffp-contract=off -g
CC_FLAGS += $(USER_FLAGS)
LD_LIBS = -lm -lc -lgcc
LD_LIBS += $(USER_LIBS)
# Allow users to use tool-specific flags
# Uses naming from https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
NEO_CFLAGS = $(CC_FLAGS) $(CFLAGS)
NEO_CXXFLAGS = $(CC_FLAGS) $(CXXFLAGS)
NEO_LDFLAGS = $(CC_FLAGS) $(LDFLAGS)
NEO_ASFLAGS = $(CC_FLAGS) $(ASFLAGS)
# -----------------------------------------------------------------------------
# Application output definitions
# -----------------------------------------------------------------------------
.PHONY: check info help elf_info clean clean_all
.DEFAULT_GOAL := help
elf: $(APP_ELF)
asm: $(APP_ASM)
exe: $(APP_EXE)
hex: $(APP_HEX)
bin: $(APP_BIN)
coe: $(APP_COE)
mem: $(APP_MEM)
mif: $(APP_MIF)
image: $(APP_VHD)
install: image install-$(APP_VHD)
all: $(APP_ELF) $(APP_ASM) $(APP_EXE) $(APP_HEX) $(APP_BIN) $(APP_COE) $(APP_MEM) $(APP_MIF) $(APP_VHD) install hex bin
# -----------------------------------------------------------------------------
# Verbosity
# -----------------------------------------------------------------------------
ifeq ("$(origin V)", "command line")
BUILD_VERBOSE=$(V)
endif
ifndef BUILD_VERBOSE
BUILD_VERBOSE = 0
endif
ifeq ($(BUILD_VERBOSE),0)
Q = @
else
Q =
endif
# -----------------------------------------------------------------------------
# Git tag and commit hash
# -----------------------------------------------------------------------------
NEORV32_GIT_TAG = "unknown"
# check if git is available at all
ifneq (, $(shell git 2>/dev/null))
$(eval NEORV32_GIT_TAG = $(shell git describe --tags))
endif
# add short commit hash as C define
NEO_CFLAGS += -DNEORV32_GIT_TAG="\"$(NEORV32_GIT_TAG)\""
# -----------------------------------------------------------------------------
# Image generator targets
# -----------------------------------------------------------------------------
# Compile image generator
$(IMAGE_GEN): $(NEORV32_EXG_PATH)/image_gen.c
$(ECHO) Compiling image generator...
$(Q)$(CC_HOST) $< -o $(IMAGE_GEN)
# -----------------------------------------------------------------------------
# General targets: Assemble, compile, link, dump
# -----------------------------------------------------------------------------
# Create the build directories if they don't exist
$(BUILD_DIR):
$(Q)$(MKDIR) -p $(BUILD_DIR)
# Compile app *.s sources (assembly)
$(BUILD_DIR)/%.s.o: %.s | $(BUILD_DIR)
$(Q)$(CC) -c $(NEO_ASFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.s.d -MT $(BUILD_DIR)/$*.s.o -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
# Compile app *.S sources (assembly + C pre-processor)
$(BUILD_DIR)/%.S.o: %.S | $(BUILD_DIR)
$(Q)$(CC) -c $(NEO_ASFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.S.d -MT $(BUILD_DIR)/$*.S.o -I $(NEORV32_INC_PATH) $(ASM_INC) $< -o $@
# Compile app *.c sources
$(BUILD_DIR)/%.c.o: %.c | $(BUILD_DIR)
$(Q)$(CC) -c $(NEO_CFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.c.d -MT $(BUILD_DIR)/$*.c.o -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
# Compile app *.cpp sources
$(BUILD_DIR)/%.cpp.o: %.cpp | $(BUILD_DIR)
$(Q)$(CC) -c $(NEO_CXXFLAGS) -MMD -MP -MF $(BUILD_DIR)/$*.cpp.d -MT $(BUILD_DIR)/$*.cpp.o -I $(NEORV32_INC_PATH) $(APP_INC) $< -o $@
# Link object files and show memory utilization
-include $(OBJ:.o=.d)
$(APP_ELF): $(OBJ)
$(Q)$(CC) $(NEO_LDFLAGS) -T $(LD_SCRIPT) $^ $(LD_LIBS) -o $@
$(ECHO) "Memory utilization:"
$(Q)$(SIZE) $(APP_ELF)
# Assembly listing file (for debugging)
$(APP_ASM): $(APP_ELF)
$(Q)$(OBJDUMP) -d -S -z $< > $@
# Generate final executable from .text + .rodata + .data (in THIS order!)
$(BIN_MAIN): $(APP_ELF) | $(BUILD_DIR)
$(Q)$(OBJCOPY) -I elf32-little $< -j .text -j .rodata -j .data -O binary $@
# -----------------------------------------------------------------------------
# Application targets: Generate executable formats
# -----------------------------------------------------------------------------
# Generate NEORV32 executable image for upload via bootloader
$(APP_EXE): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_EXE)"
$(Q)$(IMAGE_GEN) -app_bin $< $@ $(shell basename $(CURDIR))
$(ECHO) "Executable size in bytes:"
$(Q)$(WC) -c < $(APP_EXE)
# Generate NEORV32 executable VHDL boot image
$(APP_VHD): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_VHD)"
$(Q)$(IMAGE_GEN) -app_vhd $< $@ $(shell basename $(CURDIR))
# Generate NEORV32 RAW executable image in plain hex format
$(APP_HEX): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_HEX)"
$(Q)$(IMAGE_GEN) -raw_hex $< $@ $(shell basename $(CURDIR))
# Generate NEORV32 RAW executable image in binary format
$(APP_BIN): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_BIN)"
$(Q)$(IMAGE_GEN) -raw_bin $< $@ $(shell basename $(CURDIR))
# Generate NEORV32 RAW executable image in COE format
$(APP_COE): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_COE)"
$(Q)$(IMAGE_GEN) -raw_coe $< $@ $(shell basename $(CURDIR))
# Generate NEORV32 RAW executable image in MIF format
$(APP_MIF): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_MIF)"
$(Q)$(IMAGE_GEN) -raw_mif $< $@ $(shell basename $(CURDIR))
# Generate NEORV32 RAW executable image in MEM format
$(APP_MEM): $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(APP_MEM)"
$(Q)$(IMAGE_GEN) -raw_mem $< $@ $(shell basename $(CURDIR))
# -----------------------------------------------------------------------------
# BOOTROM / bootloader image targets
# -----------------------------------------------------------------------------
# Create local VHDL BOOTROM image
bl_image: $(BIN_MAIN) $(IMAGE_GEN)
$(Q)$(SET) -e
$(ECHO) "Generating $(BOOT_VHD)"
$(Q)$(IMAGE_GEN) -bld_vhd $< $(BOOT_VHD) $(shell basename $(CURDIR))
# Install BOOTROM image to VHDL source directory
bootloader: bl_image
$(Q)$(SET) -e
$(ECHO) "Installing bootloader image to $(NEORV32_RTL_PATH)/core/$(BOOT_VHD)"
$(Q)$(CP) $(BOOT_VHD) $(NEORV32_RTL_PATH)/core/.
# -----------------------------------------------------------------------------
# In-console simulation using default testbench and GHDL
# -----------------------------------------------------------------------------
sim: $(APP_VHD)
$(ECHO) "Simulating processor using default testbench..."
$(Q)$(SH) $(NEORV32_SIM_PATH)/ghdl.sh $(GHDL_RUN_FLAGS)
# Install VHDL memory initialization file
install-$(APP_VHD): $(APP_VHD)
$(Q)$(SET) -e
$(ECHO) "Installing application image to $(NEORV32_RTL_PATH)/core/$(APP_VHD)"
$(Q)$(CP) $(APP_VHD) $(NEORV32_RTL_PATH)/core/.
# -----------------------------------------------------------------------------
# Regenerate HDL file list file(s)
# -----------------------------------------------------------------------------
hdl_lists:
$(Q)$(SH) $(NEORV32_RTL_PATH)/generate_file_lists.sh
# -----------------------------------------------------------------------------
# Show final ELF details (just for debugging)
# -----------------------------------------------------------------------------
elf_info: $(APP_ELF)
$(Q)$(OBJDUMP) -x $(APP_ELF)
elf_sections: $(APP_ELF)
$(Q)$(READELF) -S $(APP_ELF)
# -----------------------------------------------------------------------------
# Run GDB
# -----------------------------------------------------------------------------
gdb: $(APP_ELF)
$(Q)$(GDB) $(APP_ELF) $(GDB_ARGS)
# -----------------------------------------------------------------------------
# Clean up
# -----------------------------------------------------------------------------
# remove all build artifacts
clean:
$(Q)$(RM) -rf $(BUILD_DIR)
$(Q)$(RM) -f $(APP_EXE) $(APP_ELF) $(APP_HEX) $(APP_BIN) $(APP_COE) $(APP_MEM) $(APP_MIF) $(APP_ASM) $(APP_VHD) $(BOOT_VHD)
$(Q)$(RM) -f .gdb_history
# also remove image generator
clean_all: clean
$(Q)$(RM) -f $(IMAGE_GEN)
$(Q)$(RM) -rf $(NEORV32_SIM_PATH)/build
# -----------------------------------------------------------------------------
# Check toolchain
# -----------------------------------------------------------------------------
check: $(IMAGE_GEN)
$(ECHO) "---------------- $(CC) ----------------"
$(Q)$(CC) -v
$(ECHO) "---------------- $(OBJDUMP) ----------------"
$(Q)$(OBJDUMP) -V
$(ECHO) "---------------- $(OBJCOPY) ----------------"
$(Q)$(OBJCOPY) -V
$(ECHO) "---------------- $(READELF) ----------------"
$(Q)$(READELF) -v
$(ECHO) "---------------- $(SIZE) ----------------"
$(Q)$(SIZE) -V
$(ECHO) "---------------- NEORV32 image_gen ----------------"
$(Q)$(IMAGE_GEN) -help
$(ECHO) "---------------- Native GCC ----------------"
$(Q)$(CC_HOST) -v
$(ECHO) ""
$(ECHO) "Toolchain check OK"
# -----------------------------------------------------------------------------
# Show configuration
# -----------------------------------------------------------------------------
info:
$(ECHO) "******************************************************"
$(ECHO) "Project / Makefile Configuration"
$(ECHO) "******************************************************"
$(ECHO) "Git tag: $(NEORV32_GIT_TAG)"
$(ECHO) "Project folder: $(shell basename $(CURDIR))"
$(ECHO) "Source files: $(APP_SRC)"
$(ECHO) "Include folder(s): $(APP_INC)"
$(ECHO) "ASM include folder(s): $(ASM_INC)"
$(ECHO) "NEORV32 home folder (NEORV32_HOME): $(NEORV32_HOME)"
$(ECHO) "IMAGE_GEN: $(IMAGE_GEN)"
$(ECHO) "Core source files:"
$(ECHO) "$(CORE_SRC)"
$(ECHO) "Core include folder:"
$(ECHO) "$(NEORV32_INC_PATH)"
$(ECHO) "Search path (VPATH)"
$(ECHO) "$(VPATH)"
$(ECHO) "Project object files:"
$(ECHO) "$(OBJ)"
$(ECHO) "LIBGCC:"
$(Q)$(CC) -print-libgcc-file-name
$(ECHO) "SEARCH-DIRS:"
$(Q)$(CC) -print-search-dirs
$(ECHO) "USER_LIBS: $(USER_LIBS)"
$(ECHO) "LD_LIBS: $(LD_LIBS)"
$(ECHO) "MARCH: $(MARCH)"
$(ECHO) "MABI: $(MABI)"
$(ECHO) "CC: $(CC)"
$(ECHO) "OBJDUMP: $(OBJDUMP)"
$(ECHO) "OBJCOPY: $(OBJCOPY)"
$(ECHO) "SIZE: $(SIZE)"
$(ECHO) "DEBUGGER: $(GDB)"
$(ECHO) "GDB_ARGS: $(GDB_ARGS)"
$(ECHO) "GHDL_RUN_FLAGS: $(GHDL_RUN_FLAGS)"
$(ECHO) "USER_FLAGS: $(USER_FLAGS)"
$(ECHO) "CC_FLAGS: $(CC_FLAGS)"
# -----------------------------------------------------------------------------
# Help
# -----------------------------------------------------------------------------
help:
$(ECHO) "NEORV32 Software Makefile"
$(ECHO) "Find more information at https://github.com/stnolting/neorv32"
$(ECHO) "Use make V=1 or set BUILD_VERBOSE to increase build verbosity"
$(ECHO) ""
$(ECHO) "Targets:"
$(ECHO) ""
$(ECHO) " help show this text"
$(ECHO) " check check toolchain"
$(ECHO) " info show makefile/toolchain configuration"
$(ECHO) " gdb start GNU debugging session"
$(ECHO) " asm compile and generate <$(APP_ASM)> assembly listing file for manual debugging"
$(ECHO) " elf compile and generate <$(APP_ELF)> ELF file"
$(ECHO) " exe compile and generate <$(APP_EXE)> executable image file for bootloader upload (includes a HEADER!)"
$(ECHO) " bin compile and generate <$(APP_BIN)> executable memory image"
$(ECHO) " hex compile and generate <$(APP_HEX)> executable memory image"
$(ECHO) " coe compile and generate <$(APP_COE)> executable memory image"
$(ECHO) " mem compile and generate <$(APP_MEM)> executable memory image"
$(ECHO) " mif compile and generate <$(APP_MIF)> executable memory image"
$(ECHO) " image compile and generate VHDL IMEM application boot image <$(APP_VHD)> in local folder"
$(ECHO) " install compile, generate and install VHDL IMEM application boot image <$(APP_VHD)>"
$(ECHO) " sim in-console simulation using default testbench (sim folder) and GHDL"
$(ECHO) " hdl_lists regenerate HDL file-lists (*.f) in NEORV32_HOME/rtl"
$(ECHO) " all exe + install + hex + bin + asm"
$(ECHO) " elf_info show ELF layout info"
$(ECHO) " elf_sections show ELF sections"
$(ECHO) " clean clean up project home folder"
$(ECHO) " clean_all clean up project home folder and image generator"
$(ECHO) " bl_image compile and generate VHDL BOOTROM bootloader boot image <$(BOOT_VHD)> in local folder"
$(ECHO) " bootloader compile, generate and install VHDL BOOTROM bootloader boot image <$(BOOT_VHD)>"
$(ECHO) ""
$(ECHO) "Variables:"
$(ECHO) ""
$(ECHO) " BUILD_VERBOSE Set to increase build verbosity: \"$(BUILD_VERBOSE)\""
$(ECHO) " USER_FLAGS Custom toolchain flags [append only]: \"$(USER_FLAGS)\""
$(ECHO) " USER_LIBS Custom libraries [append only]: \"$(USER_LIBS)\""
$(ECHO) " EFFORT Optimization level: \"$(EFFORT)\""
$(ECHO) " MARCH Machine architecture: \"$(MARCH)\""
$(ECHO) " MABI Machine binary interface: \"$(MABI)\""
$(ECHO) " APP_INC C include folder(s) [append only]: \"$(APP_INC)\""
$(ECHO) " APP_SRC C source folder(s) [append only]: \"$(APP_SRC)\""
$(ECHO) " APP_OBJ Object file(s) [append only]: \"$(APP_OBJ)\""
$(ECHO) " ASM_INC ASM include folder(s) [append only]: \"$(ASM_INC)\""
$(ECHO) " RISCV_PREFIX Toolchain prefix: \"$(RISCV_PREFIX)\""
$(ECHO) " NEORV32_HOME NEORV32 home folder: \"$(NEORV32_HOME)\""
$(ECHO) " GDB_ARGS GDB (connection) arguments: \"$(GDB_ARGS)\""
$(ECHO) " GHDL_RUN_FLAGS GHDL simulation run arguments: \"$(GHDL_RUN_FLAGS)\""
$(ECHO) ""