Skip to content

Commit

Permalink
Refactor makefiles; use print funcs from common.mk
Browse files Browse the repository at this point in the history
  • Loading branch information
saursin committed Dec 27, 2023
1 parent f3e2571 commit 75ebe3d
Show file tree
Hide file tree
Showing 12 changed files with 360 additions and 398 deletions.
145 changes: 60 additions & 85 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#====================================================================#
# ____ _________ _______ __ __ #
# / __ \/ _/ ___// ____/ | / / ____ _/ /_____ ____ ___ #
# / /_/ // / \__ \/ / | | / / / __ `/ __/ __ \/ __ `__ \ #
# / _, _// / ___/ / /___ | |/ / / /_/ / /_/ /_/ / / / / / / #
# /_/ |_/___//____/\____/ |___/ \__,_/\__/\____/_/ /_/ /_/ #
# #
#h#. ____ _________ _______ __ __
#h#. / __ \/ _/ ___// ____/ | / / ____ _/ /_____ ____ ___
#h#. / /_/ // / \__ \/ / | | / / / __ `/ __/ __ \/ __ `__ \
#h#. / _, _// / ___/ / /___ | |/ / / /_/ / /_/ /_/ / / / / / /
#h#. /_/ |_/___//____/\____/ |___/ \__,_/\__/\____/_/ /_/ /_/
#h#
#====================================================================#
# README:
# This is the root makefile for the RISC-V Atom project. It
Expand All @@ -13,19 +13,24 @@
# on how to usage instructions and available targets
#
#====================================================================#
# About this makefile:
# This is a self-documenting Makefile. It parses the target
# descriptions from the makefile autoimetically to display when
# `$ make help` is called. To enable this, One-line target
# description should be prefixed with double hash(#), and should
# placed be in same line as target recepie. lines prefixed with
# #h and #f will be placed at the header abnd footer of help page
# respectively.
#====================================================================#
include common.mk
#h# ***** RISC-V Atom Root Makefile *****

#v# Specify soctarget
soctarget?= atombones

#v# Build for simulation
sim?=1

#v# Enable debug build of atomsim
debug?=1


# Flags to the makefiles
MKFLAGS := -s

# soctarget variable (should be overridden using CLI)
soctarget ?= atombones
_mk_check_env:=1
include common.mk
#######################################################################

# Directories
sim_dir := sim
Expand All @@ -35,141 +40,111 @@ bootloader_dir := sw/bootloader
lib_dir := sw/lib
doxy_dir := sim/docs

# Flags to the makefiles
MKFLAGS := -s

# Check if RVATOM env variable is set
ifeq ($(RVATOM),)
$(error RVATOM environment variable not set; did you forget to source the sourceme script?)
endif

#======================================================================
# Recepies
#======================================================================

default: sim lib boot ## Build sim, elfdump, and libs
default: sim lib boot #t# Build atomsim, libcatom and bootloader
@printf "\n$(CLR_GR)==============================\n"
@printf " Build Succesful!\n"
@printf "==============================$(CLR_NC)\n"
@printf " - atomsim [$(soctarget)]\n"
@printf " - software libraries\n"
@printf " - bootloader [$(soctarget)]\n"

all : doxy-pdf default ## Build default with docs
@printf " - doxygen-docs in latex, html & pdf\n"


#======== Help ========
.PHONY : help
help : Makefile ## Show help message
@printf "****** RISC-V Atom Makefile ******\n"
@printf "Usage:\n"
@printf " $$ make soctarget=[SOCTARGET] [TARGET]\n"
@printf "\n"

@printf "SOCTARGETs:\n"
@printf "\t$(CLR_CY)%-20s$(CLR_NC) %s\n" "atombones" "A barebone Atom based SoC with simulated memories"
@printf "\t$(CLR_CY)%-20s$(CLR_NC) %s\n" "hydrogensoc" "A minimal Atom based SoC"

@printf "\n"
@printf "TARGETs:\n"
@grep -E -h '\s##\s' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\t$(CLR_CY)%-20s$(CLR_NC) %s\n", $$1, $$2}'
@printf "\n"
@sed -n 's/^#f //p' Makefile
@printf " soctarget: $(soctarget), sim: $(sim), debug: $(debug)\n"

all : doxy-pdf default #t# Build default with docs

# ======== AtomSim ========
.PHONY : sim
sim: boot ## Build atomsim for given target [default: atombones]
@printf "$(CLR_GR)>> Building Atomsim [soctarget:$(soctarget)] $(CLR_NC)\n"
make $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) DEBUG=1
sim: boot #t# Build atomsim for given soctarget
$(call print_msg_root,Building AtomSim)
make $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) DEBUG=$(debug)


.PHONY: clean-sim
clean-sim: ## Clean atomsim build files
@printf "$(CLR_GR)>> Cleaning atomsim build files $(CLR_NC)\n"
clean-sim: #t# Clean atomsim build files
$(call print_msg_root,Cleaning AtomSim build files)
make $(MKFLAGS) -C $(sim_dir) soctarget=$(soctarget) clean


.PHONY: test
test: sim lib ## Test the build using banner example
cd sw/examples && make ex=banner sim=1 clean compile run
test: sim lib #t# Test the build using banner example
$(call print_msg_root,Running example on Atomsim)
make $(MKFLAGS) -C $(RVATOM)/sw/examples soctarget=$(soctarget) ex=banner sim=1 clean compile run


# ======== Bootloader ========
.PHONY : boot
boot: lib ## Build bootloader for given target [default: atombones]
@printf "$(CLR_GR)>> Building bootloader [soctarget:$(soctarget)] $(CLR_NC)\n"
make $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) sim=1
boot: lib #t# Build bootloader for given target
$(call print_msg_root,Building bootloader)
make $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) sim=$(sim)


.PHONY: clean-boot
clean-boot: ## Clean bootloader build files
@printf "$(CLR_GR)>> Cleaning bootloader build files $(CLR_NC)\n"
clean-boot: #t# Clean bootloader build files
$(call print_msg_root,Cleaning bootloader build files)
make $(MKFLAGS) -C $(bootloader_dir) soctarget=$(soctarget) clean


# ======== SCAR ========
.PHONY: scar
scar: sim ## Verify target using scar
@printf "$(CLR_GR)>> Running SCAR $(CLR_NC)\n"
scar: sim #t# Verify target using scar
$(call print_msg_root,Running SCAR)
make $(MKFLAGS) -C $(scar_dir)


.PHONY: clean-scar
clean-scar: ## Clean scar directory
@printf "$(CLR_GR)>> Cleaning scar working directory$(CLR_NC)\n"
clean-scar: #t# Clean scar directory
$(call print_msg_root,Cleaning SCAR working directory)
make $(MKFLAGS) -C $(scar_dir) clean


# ======== ElfDump ========
.PHONY: elfdump
elfdump: ## Build elfdump utility
@printf "$(CLR_GR)>> Building elfdump $(CLR_NC)\n"
elfdump: #t# Build elfdump utility
$(call print_msg_root,Building ELFDump)
make $(MKFLAGS) -C $(elfdump_dir)


.PHONY: clean-elfdump
clean-elfdump: ## Clean elfdump directory
@printf "$(CLR_GR)>> Cleaning elfdump directory [tools/elfdump/bin/*]$(CLR_NC)\n"
clean-elfdump: #t# Clean elfdump directory
$(call print_msg_root,Cleaning ELFDump build files)
make $(MKFLAGS) -C $(elfdump_dir) clean

# ======== SW libs ========
.PHONY: lib
lib: ## compile software libraries
@printf "$(CLR_GR)>> Compiling software libraries $(CLR_NC)\n"
make $(MKFLAGS) -C $(lib_dir) soctarget=$(soctarget)
lib: #t# compile software libraries
$(call print_msg_root,Building libcatom)
make $(MKFLAGS) -C $(lib_dir) soctarget=$(soctarget) sim=$(sim)


.PHONY: clean-lib
clean-lib: ## Clean software libs
@printf "$(CLR_GR)>> Cleaning build files for lib $(CLR_NC)\n"
clean-lib: #t# Clean software libs
$(call print_msg_root,Cleaning libcatom build files)
make $(MKFLAGS) -C $(lib_dir) clean


# ======== Documentation ========
.PHONY: doxy
doxy: ## Generate atomsim C++ source documentation
@printf "$(CLR_GR)>> Generating Doxygen C++ documentation [latex & html]$(CLR_NC)\n"
doxy: #t# Generate atomsim C++ source documentation
$(call print_msg_root,Generating docs for AtomSim,LATEX & HTML)
make $(MKFLAGS) -C $(doxy_dir)


.PHONY: doxy-pdf
doxy-pdf: doxy ## Generate atomsim C++ source documentation (pdf)
@printf "$(CLR_GR)>> Generating Doxygen C++ documentation [pdf]$(CLR_NC)\n"
doxy-pdf: doxy #t# Generate atomsim C++ source documentation (pdf)
$(call print_msg_root,Generating docs for AtomSim,PDF)
make $(MKFLAGS) -C $(doxy_dir) pdf


.PHONY: clean-doxy
clean-doxy: ## Clean build files for Atomsim docs
@printf "$(CLR_GR)>> Cleaning docs $(CLR_NC)\n"
clean-doxy: #t# Clean build files for Atomsim docs
$(call print_msg_root,Cleaning docs build files)
make $(MKFLAGS) -C $(doxy_dir) clean


# ======== clean ========
.PHONY: clean
clean: clean-sim clean-boot clean-lib ## Alias for clean-sim, clean-lib
clean: clean-sim clean-boot clean-lib #t# Alias for clean-sim, clean-lib


.PHONY: clean-all
clean-all: clean-sim clean-boot clean-scar clean-elfdump clean-lib clean-doxy ## Clean all build files
clean-all: clean-sim clean-boot clean-scar clean-elfdump clean-lib clean-doxy #t# Clean all build files
36 changes: 21 additions & 15 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -40,32 +40,38 @@ endif
##############################################################################
# common functions

# $1 level
# $2 msg
# Print a formatted message
define print_msg_root
@printf "$(CLR_GR)$(CLR_B)❖ %-30b$(CLR_NB)%s$(CLR_NC)\n" "$(1)" "$(2)"
endef
define print_msg
@printf "$(CLR_CY)$(CLR_B)► %-30b$(CLR_NB)%s$(CLR_NC)\n" "$(1)" "$(2)"
endef

# Print a formatted message with target information
define print_msgt_root
@printf "$(CLR_GR)$(CLR_B)❖ %-30b$(CLR_NB)%s$(CLR_NC)\n" "$(1)" "$(@F)"
endef
define print_msgt
@printf "$(CLR_CY)$(CLR_B)► %-30b$(CLR_NB)%s$(CLR_NC)\n" "$(1)" "$(@F)"
endef

define print_info
@printf "$(CLR_GR)>$(1)$(CLR_NC)\n"
@printf "$(CLR_CY)$(CLR_B)INFO:$(CLR_NB)$(CLR_NC)$(1)\n"
endef

define print_warn
@printf "$(CLR_YL)> WARNING:$(CLR_NC)$(1)\n"
@printf "$(CLR_YL)$(CLR_B)WARN:$(CLR_NB)$(CLR_NC)$(1)\n"
endef

define print_error
@printf "$(CLR_RD)> ERROR:$(CLR_NC)$(1)\n"
$(error "Exiting...")
@printf "$(CLR_RD)$(CLR_B)ERROR:$(CLR_NB)$(CLR_NC)$(1)\n"
@printf "Exiting..."; exit 1
endef

##############################################################################
# common targets

.PHONY: help
help: Makefile
# Print Header comments '#h#'
@sed -n 's/^#h# //p' $<

# Print Target descriptions '#t#'
@printf "\nTARGETs:\n"
@grep -E -h '\s#t#\s' $< | awk 'BEGIN {FS = ":.*?#t# "}; {printf "\t$(CLR_CY)%-20s$(CLR_NC) %s\n", $$1, $$2}'

# Print footer '#f#'
@sed -n 's/^#f# //p' $<
@python3 $(RVATOM)/scripts/genmkhelp.py $<
82 changes: 82 additions & 0 deletions scripts/genmkhelp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import sys
import re
from colorama import init, Fore, Style

if len(sys.argv) != 2:
print("ERROR: Invalid Args")
sys.exit(1)

lines = []
with open(sys.argv[1], 'r') as mkfile:
lines = mkfile.readlines()

header = []
variables = []
targets = []
footer = []

header_tag_re = re.compile(r'^.*#h#(.*)$')
variable_tag_re = re.compile(r'^.*#v#(.*)$')
variable_decl_re = re.compile(r'^\s*(.*)[?!:+]=(.*)$')
target_tag_re = re.compile(r'^^\s*(.*):.*#t#(.*)$')
footer_tag_re = re.compile(r'^.*#f#(.*)$')


var_tag = None
for l in lines:
match = None

# parse variable declaration, if last line had a var tag #v#
if var_tag is not None:
match = variable_decl_re.match(l)
if match:
variables += [[match.group(1).strip(), match.group(2).strip(), var_tag]]
var_tag = None
continue

# Header tag: #h#
match = header_tag_re.match(l)
if match:
header += [match.group(1).strip()]
continue

# Variable tag: #v#
match = variable_tag_re.match(l)
if match:
var_tag = match.group(1).strip()
continue

match = target_tag_re.match(l)
if match:
targets += [[match.group(1).strip(), match.group(2).strip()]]
continue

# Footer
match = footer_tag_re.match(l)
if match:
footer += [match.group(1).strip()]
continue

# ==================== Print Help ====================
# Header
if len(header) > 0:
print(f'{Fore.GREEN}'+'\n'.join(header)+f'{Fore.RESET}\n')

print('Usage: make', '[VARs]' if len(variables) > 0 else '', 'TARGETs' if len(targets) > 0 else '')

# variables
if len(variables) > 0:
print('\nVARs:')
for v in variables:
print(Fore.CYAN+'\t{:<15s}{}{:<15s}'.format(v[0], Fore.RESET, v[2]), end='')
print(f' (default: {v[1]})' if v[1] else '')

# targets
if len(targets) > 0:
print('\nTARGETs:')
for t in targets:
print(Fore.CYAN+'\t{:<15s}{}{:<15s}'.format(t[0], Fore.RESET, t[1]))

# footer
if len(footer)>0:
print(f'\n'+'\n'.join(footer))
Loading

0 comments on commit 75ebe3d

Please sign in to comment.