switch build system to CMake

This factors the burden of compiler specification in the fxSDK while
providing substantially more support through CMake modules.
This commit is contained in:
Lephe 2021-01-25 15:31:20 +01:00
parent 15ec46d11c
commit 0525b51ba5
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
8 changed files with 162 additions and 476 deletions

131
CMakeLists.txt Normal file
View File

@ -0,0 +1,131 @@
# Build system for the gint unikernel
# TODO: Options for NO_SYSCALLS, STATIC_GRAY, USER_VRAM, ATEXIT_MAX
cmake_minimum_required(VERSION 3.18)
project(Gint VERSION 2.3.0 LANGUAGES C ASM)
include(GitVersionNumber)
include(Fxconv)
# Generate <gint/config.h> with commit hash and version name in
git_version_number(SHORT_HASH "GINT_GIT_HASH" TAG_RELATIVE "GINT_GIT_VERSION")
configure_file(include/gint/config.h.in include/gint/config.h)
set(SOURCES_COMMON
src/cpg/cpg.c
src/intc/intc.c
src/kernel/cpu.s
src/kernel/exch.c
src/kernel/exch.s
src/kernel/hardware.c
src/kernel/inth.S
src/kernel/kernel.c
src/kernel/osmenu.c
src/kernel/start.c
src/kernel/syscalls.S
src/kernel/tlbh.S
src/keysc/getkey.c
src/keysc/iokbd.c
src/keysc/keycodes.c
src/keysc/keysc.c
src/mmu/mmu.c
src/render/dhline.c
src/render/dimage.c
src/render/dline.c
src/render/dprint.c
src/render/drect_border.c
src/render/dtext.c
src/render/dvline.c
src/render/topti.c
src/rtc/inth.s
src/rtc/rtc.c
src/spu/spu.c
src/std/tinymt32/rand.c
src/std/tinymt32/tinymt32.c
src/std/memcmp.s
src/std/memcpy.s
src/std/memmove.s
src/std/memset.s
src/std/stdio.c
src/std/string.c
src/tmu/inth-etmu.s
src/tmu/inth-tmu.s
src/tmu/sleep.c
src/tmu/tmu.c
)
set(SOURCES_FX
src/gray/engine.c
src/gray/gclear.c
src/gray/gint_gline.c
src/gray/gpixel.c
src/gray/grect.c
src/gray/gsubimage.c
src/gray/gtext.c
src/render-fx/bopti-asm-gray-scsp.s
src/render-fx/bopti-asm-gray.s
src/render-fx/bopti-asm-mono-scsp.s
src/render-fx/bopti-asm.s
src/render-fx/bopti.c
src/render-fx/dclear.c
src/render-fx/dpixel.c
src/render-fx/drect.c
src/render-fx/dsubimage.c
src/render-fx/dupdate.c
src/render-fx/gint_dline.c
src/render-fx/masks.c
src/render-fx/topti-asm.s
src/render-fx/topti.c
src/t6k11/t6k11.c
)
set(SOURCES_CG
src/dma/dma.c
src/dma/inth.s
src/dma/memcpy.c
src/dma/memset.c
src/r61524/r61524.c
src/render-cg/bopti-asm.s
src/render-cg/bopti.c
src/render-cg/dclear.c
src/render-cg/dpixel.c
src/render-cg/drect.c
src/render-cg/dsubimage.c
src/render-cg/dupdate.c
src/render-cg/dvram.c
src/render-cg/gint_dline.c
src/render-cg/topti-asm.s
src/render-cg/topti.c
)
set(ASSETS_FX src/font5x7.png)
set(ASSETS_CG src/font8x9.png)
set_source_files_properties(${ASSETS_FX} ${ASSETS_CG} PROPERTIES
LANGUAGE FXCONV
OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/fxconv-metadata.txt")
include_directories("${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/include")
add_compile_options(-Wall -Wextra -std=c11 -Os -fstrict-volatile-bitfields)
if("${FXSDK_PLATFORM_LONG}" STREQUAL fx9860G)
add_compile_definitions(FX9860G)
add_library(gint-fx STATIC ${SOURCES_COMMON} ${SOURCES_FX} ${ASSETS_FX})
set(NAME "gint-fx")
set(LINKER_SCRIPT "fx9860g.ld")
endif()
if("${FXSDK_PLATFORM_LONG}" STREQUAL fxCG50)
add_compile_definitions(FXCG50)
add_library(gint-cg STATIC ${SOURCES_COMMON} ${SOURCES_CG} ${ASSETS_CG})
set(NAME "gint-cg")
set(LINKER_SCRIPT "fxcg50.ld")
endif()
set_target_properties("${NAME}" PROPERTIES OUTPUT_NAME "${NAME}")
install(TARGETS "${NAME}" DESTINATION "${FXSDK_COMPILER_INSTALL}")
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_SCRIPT}"
DESTINATION "${FXSDK_COMPILER_INSTALL}")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include"
DESTINATION "${FXSDK_COMPILER_INSTALL}"
FILES_MATCHING PATTERN "*.h")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/gint/config.h"
DESTINATION "${FXSDK_COMPILER_INSTALL}/include/gint")

View File

@ -1,59 +0,0 @@
#! /usr/bin/make -f
builds := $(wildcard build*)
ifeq "$(builds)" ""
nobuild:
@ echo "error: you don't seem to have any build directory (build*)" >&2
@ echo "" >&2
@ echo "You can configure one like this:" >&2
@ echo " mkdir build && cd build && ../configure [options...]" >&2
@ echo "" >&2
@ false
endif
#
# all targets
#
all-targets := $(foreach b,$(builds),all-$b)
all: $(all-targets)
all-build%: build%
@ echo -e "$B::$W Making into $<$N"
@ $(MAKE) --no-print-directory -C $<
#
# install targets
#
install-targets := $(foreach b,$(builds),install-$b)
install: $(install-targets)
install-build%: build%
@ echo -e "$B::$W Installing from $<$N"
@ $(MAKE) --no-print-directory -C $< install
#
# uninstall targets
#
uninstall-targets := $(foreach b,$(builds),uninstall-$b)
uninstall: $(uninstall-targets)
uninstall-build%: build%
@ echo -e "$B::$W Uninstalling from $<$N"
@ $(MAKE) --no-print-directory -C $< uninstall
#
# Coloring tools
#
B = \e[34;1m
W = \e[39;1m
N = \e[0m
.PHONY: nobuild all all-build% install install-build%

1
TODO
View File

@ -8,7 +8,6 @@ Extensions on existing code:
* core: use cmp/str for memchr()
* r61524: brightness control and clean the file
* core: review forgotten globals and MPU addresses not in <gint/mpu/*.h>
* build: make the build system simpler (two targets are enough by default)
* core: run destructors when a task-switch results in leaving the app
* core rtc: use qdiv10 to massively improve division performance
* topti: let the font specify letter and word spacing

207
configure vendored
View File

@ -1,207 +0,0 @@
#! /bin/bash
#
# Basic configuration
#
# Target platform
target=
toolchain=
# Build options
prefix=
cflags=
# Behavior
no_syscalls=
static_gray=
user_vram=
# Size limits
atexit_max=
# Output files
output="Makefile.cfg"
#
# Help screen
#
help()
{
cat << EOF
Configuration script for the gint library.
Usage: $0 [options...]
You should build out-of-tree by creating a build directory and configuring from
there.
Target selection:
--target=fx9860g|fxcg50
fx9860g covers all fx-9860G II-like monochromes models that support add-ins
or can be flashed with an OS that does. This includes SH3 and SH4 machines.
Default toolchain is 'sh-elf'.
fxcg50 covers just the fx-CG 50; there is some unofficial compatibility with
fx-CG 10/20. All of these are SH4-only.
Default toolchain is 'sh-elf'.
Build options:
--toolchain=TRIPLET Build with a different toolchain
--prefix=PREFIX Install prefix (PREFIX/lib and PREFIX/include are used)
--cflags=FLAGS Additional compiler flags at end of command
Library options (disabled by default):
--no-syscalls Cut off all syscalls (this will break things)
Only use this option if you have a good idea of which.
--static-gray Allocate gray VRAMs in static RAM instead of the heap
May help when --no-syscalls is on.
--user-vram Allocate VRAM in user stack; takes 350k/512k [fxcg50]
Size limits:
--atexit-max=NUM Number of exit handlers in atexit()'s array [16]
Deprecated options (to be removed):
-events-queue-size=<n>
Size of event queue (this mechanism is likely to
disappear in future versions) [64]
EOF
exit 0
}
if [[ "$@" == "--help" ]]; then
help
exit 1
fi
if [[ -f make/Makefile ]]; then
echo "error: you should configure from a build directory, like this:" >&2
echo " mkdir build && cd build && ../configure [options..]" >&2
exit 1
fi
#
# Parsing arguments
#
fail=false
for arg; do case "$arg" in
-h | -? | --help)
help;;
--target=*)
case ${arg#*=} in
"fx9860g")
target=fx9860g
toolchain=${toolchain:-sh-elf};;
"fxcg50")
target=fxcg50
toolchain=${toolchain:-sh-elf};;
*)
echo "error: invalid target '$target'"
fail=true
esac;;
--toolchain=*)
toolchain=${arg#*=};;
--prefix=*)
prefix=${arg#*=};;
--cflags=*)
cflags=${arg#*=};;
--no-syscalls)
no_syscalls=true;;
--static-gray)
static_gray=true;;
--user-vram)
user_vram=true;;
--atexit-max=*)
n=${arg#*=}
if [[ $n =~ ([0-9])+ ]]; then
atexit_max=$n
else
echo -e "error: -atexit-max expects an integer value"
fail=true
fi;;
--atexit-max)
echo "error: '$arg' expects a value (see '$0 --help')";
fail=true;;
-events-queue-size=*)
echo "warning: support for '-events-queue-size' has been removed";;
*)
echo "error: unrecognized argument '$arg'";
fail=true;;
esac; done
#
# Checking mandatory arguments
#
if [[ -z "$target" ]]; then
echo "error: no target specified! (see '$0 --help')"
fail=true;
fi
if $fail; then
echo "note: output file $output has not been changed."
exit 1
fi
# If no prefix is specified, install to the GCC's build folder
if [[ -z "$prefix" ]]; then
echo "No prefix specified, let's ask the compiler:"
echo " $toolchain-gcc --print-search-dirs | grep install | sed 's/install: //'"
inst=$($toolchain-gcc --print-search-dirs | grep install | sed 's/install: //')
if [[ $? != 0 ]]; then
echo "Call returned $?, giving up."
fi
echo "Got '$inst'".
if [[ ! -d $inst ]]; then
echo "Directory does not exist (or is not a directory), giving up."
exit 1
fi
echo ""
prefix=$inst
fi
#
# Output config
#
output_config()
{
mod=${target/98/fx}
echo "CONFIG.TARGET = ${mod:2:2}"
echo "CONFIG.TARGET.LONG = $target"
[[ $prefix ]] && echo "PREFIX = $prefix"
[[ $toolchain ]] && echo "CONFIG.TOOLCHAIN = $toolchain"
[[ $cflags ]] && echo "CONFIG.CFLAGS = $cflags"
echo -n "CONFIG.MACROS ="
echo -n " -D$(echo $target | tr 'a-z' 'A-Z')"
[[ "$no_syscalls" ]] && echo -n " -DGINT_NO_SYSCALLS"
[[ "$static_gray" ]] && echo -n " -DGINT_STATIC_GRAY"
[[ "$user_vram" ]] && echo -n " -DGINT_USER_VRAM"
[[ "$atexit_max" ]] && echo -n " -DATEXIT_MAX=$atexit_max"
echo ""
}
output_config > $output
src="Makefile"
dst="../make/Makefile"
[[ -L $src && $(readlink $src) == $dst ]] && rm $src
ln -s $dst $src
echo "Configuration saved in $output, ready to make!"

View File

@ -3,16 +3,23 @@
-include giteapc-config.make
configure:
@ mkdir -p build-fx && cd build-fx && ../configure --target=fx9860g
@ mkdir -p build-cg && cd build-cg && ../configure --target=fxcg50
@ fxsdk build-fx -c
@ fxsdk build-cg -c
build:
@ make all
@ fxsdk build-fx
@ fxsdk build-cg
install:
@ make install
@ fxsdk build-fx install
@ fxsdk build-cg install
uninstall:
@ make uninstall
@ if [[ -e build-fx/install_manifest.txt ]]; then \
xargs rm -f < build-fx/install_manifest.txt; \
fi
@ if [[ -e build-cg/install_manifest.txt ]]; then \
xargs rm -f < build-cg/install_manifest.txt; \
fi
.PHONY: configure build install uninstall

View File

@ -10,10 +10,10 @@
/* GINT_VERSION: Latest tag and number of additional commits
"2.1.0" = Release 2.1.0
"2.1.1-5" = 5 commits after release 2.1.1 */
#define GINT_VERSION @GINT_VERSION@
#define GINT_VERSION "@GINT_GIT_VERSION@"
/* GINT_HASH: Commit hash with 7 digits
0x03f7c0a0 = Commit 3f7c0a0 */
#define GINT_HASH @GINT_HASH@
#define GINT_HASH 0x@GINT_GIT_HASH@
#endif /* GINT_CONFIG */

View File

@ -1,202 +0,0 @@
#! /usr/bin/make -f
#
# gint project Makefile
#
#---
#
# Build configuration
#
# Require configuration file (if you want to clean up and lost the file, you
# can either reconfigure or just delete the build directory)
CONFIG := Makefile.cfg
ifeq "$(wildcard $(CONFIG))" ""
$(error "config file $(CONFIG) does not exist (reconfigure or wipe directory)")
endif
include $(CONFIG)
# Machine flags, defaults are provided for common toolchains
ifeq "$(CONFIG.TOOLCHAIN)" "sh3eb-elf"
machine ?= -m3 -mb
endif
ifeq "$(CONFIG.TOOLCHAIN)" "sh4eb-elf"
machine ?= -m4-nofpu -mb
endif
# Compiler flags, assembler flags, dependency generation, archiving
inc := -I ../include -I include
cflags := $(machine) -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \
-fstrict-volatile-bitfields $(inc) $(CONFIG.MACROS) \
$(CONFIG.CFLAGS)
sflags := $(inc) $(CONFIG.MACROS)
dflags = -MMD -MT $@ -MF $(@:.o=.d) -MP
arflags :=
# Git file with current hash
ifeq "$(shell git branch --show-current)" ""
gitfile := ../.git/HEAD
else
gitfile := ../.git/refs/heads/$(shell git branch --show-current)
endif
#
# File listings
#
# Target file (CONFIG.TARGET is either "fx" or "cg")
target := libgint-$(CONFIG.TARGET).a
# Automatic names for object and dependency files
src2obj = $(1:../src/%=src/%).o
src2dep = $(1:../src/%=src/%).d
# Source files
# TODO: Enable the DMA on fx-9860G
prune-fx := -name render-cg -prune -o -name dma -prune -o -name r61524 -prune
prune-cg := -name render-fx -prune -o -name gray -prune -o -name t6k11 -prune
src := $(shell find ../src $(prune-$(CONFIG.TARGET)) \
-o -name '*.[csS]' -print)
src_obj := $(foreach s,$(src),$(call src2obj,$s))
# Files with special handling
spe-fx := ../src/font5x7.png
spe-cg := ../src/font8x9.png
spe_obj := $(foreach s,$(spe-$(CONFIG.TARGET)),$(call src2obj,$s))
# All object files
obj := $(src_obj) $(spe_obj)
#
# Toolchain
#
gcc = $(CONFIG.TOOLCHAIN)-gcc
as = $(CONFIG.TOOLCHAIN)-as
ld = $(CONFIG.TOOLCHAIN)-ld
ar = $(CONFIG.TOOLCHAIN)-ar
objcopy = $(CONFIG.TOOLCHAIN)-objcopy
#
# Version management
#
# Version symbol is obtained by using the last commit hash on 7 nibbles
version_hash = 0x0$(shell git rev-parse --short HEAD)
# Version number: closest tag, with additional commits
version_number = $(shell git describe --tag --always | cut -d- -f1-2)
#
# Build rules
#
all: $(target)
$(target): include/gint/config.h $(obj)
@ rm -f $@
$(call cmd_l,ar,$@) $(ar) rcs $(arflags) $@ $^
# Assembler sources
src/%.s.o: ../src/%.s src/%.s.d
@ mkdir -p $(dir $@)
$(call cmd_b,as,$*.s) $(gcc) -c $< -o $@ $(sflags)
src/%.S.o: ../src/%.S src/%.S.d
@ mkdir -p $(dir $@)
$(call cmd_b,as,$*.S) $(gcc) -c $< -o $@ $(sflags)
# C sources
src/%.c.o: ../src/%.c src/%.c.d
@ mkdir -p $(dir $@)
$(call cmd_b,gcc,$*.c) $(gcc) -c $< -o $@ $(dflags) $(cflags)
# Special files
include/gint/config.h: ../include/gint/config.h.in $(gitfile)
@ mkdir -p $(dir $@)
$(call cmd_m,sed,$@) cp $< $@
@ sed -i'' 's/@GINT_VERSION@/"$(version_number)"/' $@
@ sed -i'' 's/@GINT_HASH@/$(version_hash)/' $@
$(call src2obj,../src/font5x7.png): ../src/font5x7.png
@ mkdir -p $(dir $@)
$(call cmd_m,fxconv,font5x7.png) fxconv -f $< -o $@ \
--fx --toolchain=$(CONFIG.TOOLCHAIN) name:gint_font5x7 \
charset:ascii grid.size:5x7 grid.padding:1 grid.border:0
$(call src2obj,../src/font8x9.png): ../src/font8x9.png
@ mkdir -p $(dir $@)
$(call cmd_m,fxconv,font8x9.png) fxconv -f $< -o $@ \
--cg --toolchain=$(CONFIG.TOOLCHAIN) name:gint_font8x9 \
charset:print grid.size:8x11 grid.padding:1 grid.border:0 \
proportional:true height:9
#
# Cleaning
#
clean:
@ rm -rf src include
distclean: clean
@ rm -rf Makefile $(CONFIG) $(target)
#
# Installing
#
m644 := -m 644
# Disable -m on Mac OS
ifeq "$(shell uname)" "Darwin"
m644 :=
endif
install: $(target)
install -d $(PREFIX)
install $(target) $(m644) $(PREFIX)
install ../$(CONFIG.TARGET.LONG).ld $(m644) $(PREFIX)
install -d $(PREFIX)/include/gint
cp -r ../include/gint/* $(PREFIX)/include/gint/
cp -r include/gint/* $(PREFIX)/include/gint/
uninstall:
rm -f $(PREFIX)/$(target)
rm -f $(PREFIX)/$(CONFIG.TARGET.LONG).ld
rm -rf $(PREFIX)/include/gint
#
# Utilities
#
# Directories: make conveniently leaves a '/' at the end of $(dir ...)
%/:
@ mkdir -p $@
# Don't try to unlink directories once they're built (that wouldn't work =p)
.PRECIOUS: %/
# Dependency information
-include $(shell [ -d src ] && find src -name *.d)
src/%.d: ;
.PRECIOUS: src/%.d
.PHONY: all clean distclean
# Do not output full commands by default
VERBOSE ?=
# Simple command output method
# $1 Program name
# $2 Argument string to display
# $3 Command color
define cmd
@ echo -e "\e[""$3"";1m>\e[0;1m $1\e[0m $2"
$(if $(VERBOSE),,@)
endef
# Some pre-colored command kinds: misc, build, link, clean, install
cmd_m = $(call cmd,$1,$2,30)
cmd_b = $(call cmd,$1,$2,32)
cmd_l = $(call cmd,$1,$2,36)
cmd_c = $(call cmd,$1,$2,31)
cmd_i = $(call cmd,$1,$2,33)

17
src/fxconv-metadata.txt Normal file
View File

@ -0,0 +1,17 @@
font5x7.png:
name: gint_font5x7
type: font
charset: ascii
grid.size: 5x7
grid.padding: 1
grid.border: 0
font8x9.png:
name: gint_font8x9
type: font
charset: print
grid.size: 8x11
grid.padding: 1
grid.border: 0
proportional: true
height: 9