update Makefile

This commit is contained in:
Yatis 2020-10-07 11:37:54 +02:00
parent 8fac0c2272
commit 9c59763ad7
3 changed files with 287 additions and 119 deletions

1
.gitignore vendored
View file

@ -1 +1,2 @@
build build
*.txt

160
configure vendored
View file

@ -1,4 +1,9 @@
#! /bin/bash #! /bin/bash
#
# -= TODO =-
# * check if the wanted lib exist (check lib verion too)!
# * option to list all installed libraries with their versions
# * each ABI options define one specific libs (fxlibc-common, fxlibc-vhex, fxlibc-fx9860g, fxlibc-fxcg50)
# output file # output file
confile='fxlibc.cfg' confile='fxlibc.cfg'
@ -13,38 +18,41 @@ makefile='Makefile.default'
# configuration # configuration
declare -A config declare -A config
config[__SUPPORT_VHEX_KERNEL]=false
config[__DEBUG]=false config[__DEBUG]=false
config[__ENABLE_VALGRIND]=false config[__ENABLE_VALGRIND]=false
config[__SUPPORT_CASIO_ABI_FX9860]=false config[__SUPPORT_VHEX_KERNEL]=false
config[__SUPPORT_CASIO_ABI_FXCG50]=false config[__SUPPORT_CASIO_FX9860]=false
config[__SUPPORT_CASIO_FXCG50]=false
# #---
# Help screen # Help screen
# #---
help() help()
{ {
cat << EOF cat << EOF
Configuration script for the fx calculator libc. Configuration script for the fx calculator standard C library.
Usage: $0 [OPTION]... Usage: $0 [OPTION]...
You should build out-of-tree by creating a build directory and configuring from You should build out-of-tree by creating a build directory and configuring from
there. there.
Debug the fxlibc Debug the fxlibc
--debug enable valgrind flags (-g3) --debug Enable valgrind flags (-g3)
--unit-test check C-functoon validity with Criterion --unit-test Check C-functoon validity with Criterion
Build options: Build options:
--toolchain=TRIPLET Build with a different toolchain --toolchain=TRIPLET Build with a different toolchain
[sh-elf-gcc] (or [gcc] when the '--unit_test' flag is set) [sh-elf-gcc] (or [gcc] when the '--unit_test' flag is set)
--cflags=FLAGS Additional compiler flags at end of command --cflags=FLAGS Additional compiler flags at end of command
--prefix=PREFIX Install prefix (PREFIX/lib and PREFIX/include are used)
ABI support: ABI support:
--vhex-support Enable the Vhex kernel support --support-vhex
--casio-support=fx9860|fxcg50 Enable the Vhex kernel support
enable the support of the Casio' ABI (used by malloc, free, ...) --support-casio-fx9860,
--support-casio-fxcg50
Enable the support of the Casio' ABI (used by malloc, free, ...)
fx9860 covers all fx-9860G II-like monochromes models that support add-ins fx9860 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. or can be flashed with an OS that does. This includes SH3 and SH4 machines.
@ -52,27 +60,25 @@ ABI support:
fx-CG 10/20. All of these are SH4-only. fx-CG 10/20. All of these are SH4-only.
The 'ABI support' is used to allow some part of the code, in particular the 'unistd' The 'ABI support' is used to allow some part of the code, in particular the 'unistd'
part, I/O management and additionnal feature (process, fs, ...). part, I/O management and additionals feature. (like process, fs, ...).
Format: Format:
--dyn-lib generate dynamic librairies (Vhex kernel dependant) --dyn-lib Generate dynamic librairies (Vhex kernel dependant)
Little note for the generation of dynamic libraries. Little note for the generation of dynamic libraries. The superH toolchain currently
The superH toolchain currently used (GCC) does not support the '--shared' flags used (GCC) does not support the '--shared' flags when the archive is build. So we
when the archive is build. So we need to create manually an archive that can be need to create manually an archive that can be used like a shared library.
used like a shared librairy.
To do this we need to do several steps: To do this we need to do several steps:
1) build the sources with the PIE mode as if it were a executable without entry point. 1) build the sources with the PIE mode as if it were a executable without entry point.
2) manually extract symbols defined as 'global' from the generated ELF. 2) manually extract symbols defined as 'global' from the generated ELF.
3) we create "stubs": functions that will have the same name than the wanted 3) we create "stubs": functions that will have the same name than the wanted shared
shared librairies and will call internal VHEX loader primitives with the libraries and will call internal VHEX loader primitives with the libraries
librairies name, function address and size, etc....Then the loader will name, function address and size, etc....Then the loader will load the shared
load the shared function and override the "user function (stub)" to force function and override the "user function (stub)" to force it to jump into
it to jump into the "real" function (trampoline) the "real" function (trampoline).
4) all generated stubs will be compiled and linked throught a static lib that 4) all generated stubs will be compiled and linked through a static lib that SHOULD
SHOULD be used in the user program which use the "dynamic librairy" be used in the user program which uses the "dynamic library"
EOF EOF
exit 0 exit 0
} }
@ -85,8 +91,8 @@ EOF
# from there. # from there.
# #
if [ -f 'make/Makefile.default' ]; then if [ -f 'make/Makefile.default' ]; then
echo "error: you should configure from a build directory, like this:" >&2 echo 'error: you should configure from a build directory, like this:' >&2
echo " mkdir build && cd build && ../configure [options..]" >&2 echo ' mkdir build && cd build && ../configure [options..]' >&2
exit 1 exit 1
fi fi
@ -95,15 +101,16 @@ fi
# Parsing arguments # Parsing arguments
# #
for arg; do case "$arg" in for arg; do case "$arg" in
--help | -h) --help | -h)
help;; help;;
# debug options
--debug) --debug)
config[__DEBUG]=true;; config[__DEBUG]=true;;
--unit-test) --unit-test)
makefile='Malefile.unitest';; makefile='Malefile.unitest';;
# build options
--toolchain=*) --toolchain=*)
toolchain=${arg#*=};; toolchain=${arg#*=};;
--prefix=*) --prefix=*)
@ -111,68 +118,93 @@ for arg; do case "$arg" in
--cflags=*) --cflags=*)
cflags=${arg#*=};; cflags=${arg#*=};;
--vhex-support) # ABI support
--support-vhex)
config[__SUPPORT_VHEX_KERNEL]=true;; config[__SUPPORT_VHEX_KERNEL]=true;;
--casio-abi=*) --support-casio-abi-fx9860)
case ${arg#*=} in config[__SUPPORT_CASIO_ABI_FX9860]=true;;
"fx9860g") --support-casio-abi-fxcg50)
config[__SUPPORT_CASIO_ABI_FX9860]=true;; config[__SUPPORT_CASIO_ABI_FXCG50]=true;;
"fcg50")
config[__SUPPORT_CASIO_ABI_FXCG50]=true;;
*)
echo -e "\033[1;33merror\033[0m unreconized target '$arg'"
exit 1
esac;;
# format options
--dyn-lib) --dyn-lib)
makefile='Makefile.dynlib';; makefile='Makefile.dynlib';;
# error part
*) *)
echo -e "\033[1;33merror\033[0m unreconized argument '$arg'" echo "error: unreconized argument '$arg', giving up." >&2
exit 1 exit 1
esac; done esac; done
# #---
# Check error # Check error
# #---
if [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ]; then # Check ABI support error
echo -e "\033[1;33merror\033[0m too many target" if [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ] ||
[ ${config[__SUPPORT_VHEX_KERNEL]} = true ] && [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ] ||
[ ${config[__SUPPORT_VHEX_KERNEL]} = true ] && [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ]; then
echo "error: too many ABI target" >&2
exit 1 exit 1
fi fi
# If no prefix is specified, install to the GCC's build folder
if [[ -z "$prefix" ]]
then
# ask the toolchain where is his installation path
echo "No prefix specified, let's ask the compiler:"
echo " Call: \"$toolchain-gcc --print-search-dirs | grep install | sed 's/install: //'\""
if ! inst=$("$toolchain"-gcc --print-search-dirs | grep install | sed 's/install: //'); then
echo " Call: returned $?, giving up." >&2
exit 1
fi
echo " Got '$inst'".
# check if the directory exist
if [[ ! -d $inst ]]; then
echo "Directory does not exist (or is not a directory), giving up." >&2
exit 1
fi
prefix=$inst
fi
# #
# TODO: check if the wanted lib exist (check lib verion too)!
#
#---
# Dump appropriate Makefile # Dump appropriate Makefile
# @note: # @note:
# * We have 3 makefile: normal, dynlib, unit_test # * We have 3 makefile: normal, dynlib, unit_test
# #---
dst='Makefile' dst='Makefile'
src="../make/$makefile" src="../make/$makefile"
if ! test $src; then if ! test $src; then
echo -e "\033[1;33merror\033[0m target makefile ($src) does not exist !" echo "error: target makefile ($src) does not exist !" >&2
exit 1 exit 1
fi fi
[ -L $src ] && [ "$(readlink $src)" == $dst ] && rm $dst [ $dst ] && [ "$(readlink $dst)" == $src ] && rm $dst
ln -s $src $dst ln -s $src $dst
# #---
# Generate the configuration file # Generate the configuration file
# #---
function generate_config() generate_config()
{ {
echo "CONFIG.TOOLCHAIN = $toolchain" echo "CONFIG.CFLAGS := "
[ "$prefix" ] && echo "PREFIX = $prefix" echo "CONFIG.TARGET := "
[ "$cflags" ] && echo "CONFIG.CFLAGS = $cflags" echo "CONFIG.TOOLCHAIN := $toolchain"
[ "$prefix" ] && echo "CONFIG.PREFIX := $prefix"
[ "$cflags" ] && echo "CONFIG.CFLAGS += $cflags"
[ ${config[__DEBUG]} = true ] && echo -n '-g3' #[ ${config[__DEBUG]} = true ] && echo "CONFIG.CFLAGS += -g3"
[ ${config[__SUPPORT_VHEX_KERNEL]} = true ] && echo -n ' -D __SUPPORT_VHEX_KERNEL' [ ${config[__SUPPORT_VHEX_KERNEL]} = true ] && echo "CONFIG.TARGET += fxlibc-vhex"
[ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && echo -n ' -D ___SUPPORT_CASIO_ABI_FX9860' [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && echo "CONFIG.TARGET += fxlibc-fx9860"
[ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ] && echo -n ' -D ___SUPPORT_CASIO_ABI_FXCG50' [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ] && echo "CONFIG.TARGET += fxlibc-fxcg50"
echo ''
} }
generate_config > $confile generate_config > $confile
echo "Configuration saved in $confile, ready to make!" echo "Configuration saved in $confile, ready to make!"
exit 0 exit 0

View file

@ -23,12 +23,15 @@
# |-- fxlibc_stubs.a (workaround for the shared librairie, see documentation note) # |-- fxlibc_stubs.a (workaround for the shared librairie, see documentation note)
# |-- fxlibc.so (shared librairy) # |-- fxlibc.so (shared librairy)
# `-- fxlibc.a (static librairy) # `-- fxlibc.a (static librairy)
#
# TODO:
# * generate all libraries for all ABI by default ?
# * handle versionning
#--- #---
#--- #---
# Build configuration # Build configuration
#--- #---
# Require configuration file (if you want to clean up and lost the file, you # Require configuration file (if you want to clean up and lost the file, you
# can either reconfigure or just delete the build directory) # can either reconfigure or just delete the build directory)
CONFIG := fxlibc.cfg CONFIG := fxlibc.cfg
@ -37,11 +40,10 @@ $(error "config file $(CONFIG) does not exist (reconfigure or wipe directory)")
endif endif
include $(CONFIG) include $(CONFIG)
# Compiler flags, assembler flags, dependency generation, archiving # Compiler flags, assembler flags, dependency generation, archiving
header := -I ../include header := ../include
cflags := $(machine) -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \ cflags := $(machine) -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \
-fstrict-volatile-bitfields $(header) $(CONFIG.CFLAGS) -fstrict-volatile-bitfields -I$(header) $(CONFIG.CFLAGS)
# color definition # color definition
red := \033[1;31m red := \033[1;31m
@ -57,7 +59,8 @@ define n
endef endef
# Define all directory used to stored informations # Define all directory used to stored informations
dir_objects := objects dir_object := object
dir_output := output
dir_bin := bin dir_bin := bin
# Output configurations # Output configurations
@ -65,19 +68,14 @@ name := fxlibc
target := $(dir_bin)/$(name).a target := $(dir_bin)/$(name).a
# automated variable # automated variable
src := directory := $(shell find ../src -not -path "*/\.*" -type d)
directory := $(shell find ../src/ -not -path "*/\.*" -type d) src := $(foreach path,$(directory), \
$(foreach path,$(directory),$(eval \ $(wildcard $(path)/*.c) \
src += $(wildcard $(path)/*.c) $n\ $(wildcard $(path)/*.S) \
src += $(wildcard $(path)/*.S) $n\ $(wildcard $(path)/*.s))
src += $(wildcard $(path)/*.s) $n\
))
obj := $(patsubst .._src_%,$(dir_objects)/%.o,$(subst /,_,$(basename $(src))))
# check if any file have been found
ifeq ($(obj),)
$(error "source file does not exist (reconfigure or wipe directory)")
endif
#--- #---
@ -90,68 +88,117 @@ ar = $(CONFIG.TOOLCHAIN)-ar
objcopy = $(CONFIG.TOOLCHAIN)-objcopy objcopy = $(CONFIG.TOOLCHAIN)-objcopy
#--- #---
# Version management # Version management
#--- #---
# TODO # TODO
#--- #---
# Build rules # Build rules
#--- #---
all: $(target) # (Make selects the first rule when you type "make" and I don't want the first
# rule to be "%/" so here's a placeholder)
first: all
# linker part # Create directory helper
$(target): $(obj) | $(dir_bin) # @note: Just use "$*" and "$@" to refer to the directory being created.
$(ar) crs $@ $^ %/:
@ printf "Create $(blue)$*$(nocolor) directory\n"
# Directory management
$(dir_bin) $(dir_objects):
@ printf "Create $(blue)$@$(nocolor) directory\n"
@ mkdir -p $@ @ mkdir -p $@
.PRECIOUS: %/
.PHONY: all
#--- #---
# Automated rules # Automated rules
#--- #---
define rule-src # common part used to compile source file
$(patsubst .._src_%,$(dir_objects)/%.o,$(subst /,_,$(basename $1))): $1 | $(dir_objects) # @params:
@ printf "compiling $(white)$$<$(nocolor)..." # *1 - source file path
# *2 - build directory path (output)
# TODO:
# * handle custom cflags (format, abi management)
# * handle verbose option
define compile-src
$(patsubst .._src_%,$2/%.o,$(subst /,_,$(basename $1))): $1 | $2/
@ printf "compiling $(white)$$@$(nocolor)..."
@ $(gcc) $(cflags) -o $$@ -c $$< -lgcc @ $(gcc) $(cflags) -o $$@ -c $$< -lgcc
@ printf "$(green)[ok]$(nocolor)\n" @ printf "$(green)[ok]$(nocolor)\n"
endef endef
$(foreach source,$(src),$(eval \ # common part used by all library geneation
$(call rule-src,$(source))) \ # @params:
# * 1 - library name
# * 2 - format (dynamic/static)
# * 3 - source file list
define generate-target
# generate the library name based on the wanted formats
lib-output-dir := $(dir_output)/$2/
lib-build-dir := $(dir_object)/$2/$1/
ifeq ($2,dynamic)
lib-name := $$(lib-output-dir)/lib$1.so
lib-cflags := -pic $(cflags)
else
lib-name := $$(lib-output-dir)/lib$1.a
lib-cflags := $(cflags)
endif
# indicate the new lib that will be ouputed
generated-libs += $$(lib-name)
# generate all file object name
$$(foreach source,$3,$$(eval \
$$(call compile-src,$$(source),$$(lib-build-dir)) \
))
# link the library
# @note: based on the wanted format
ifeq ($2,shared)
$$(lib-name): $$(patsubst .._src_%,$$(lib-build-dir)/%.o,$$(subst /,_,$$(basename $3))) | $$(lib-output-dir)
$(gcc) -shared -o $$@ $$^ -nostdlib -lgcc
else
$$(lib-name): $$(patsubst .._src_%,$$(lib-build-dir)/%.o,$$(subst /,_,$$(basename $3))) | $$(lib-output-dir)
$(ar) crs $$@ $$^
endif
endef
# create all "target" variable used to determine which format
# and which libraries will be generated.
# @note:
# * we force default variable if nothing is set
target-formats := $(if $(CONFIG.FORMAT),$(CONFIG.FORMAT),static)
target-libs := $(if $(CONFIG.TARGET),$(CONFIG.TARGET),fxlibc)
# create a variable that will be updated during the generation of
# the dynamic make code generation (generated by the "foreach")
generated-libs :=
# Generate all targets
$(foreach format,$(target-formats), \
$(foreach lib,$(target-libs),$(eval \
$(call generate-target,$(lib),$(format),$(src)) \
)) \
) )
#--- #---
# Debugging rules # Build rule
#--- #---
help: all: $(generated-libs)
@ echo 'make [options]...'
@ echo ''
@ echo 'Options:'
@ echo ' * disasm use objdump to display the content of the archive'
@ echo ' * debug display source files name and objects name'
@ echo ' * elf_sec display ELF section of the archive'
__debug:
@ echo 'src: $(src)'
@ echo ''
@ echo 'obj: $(obj)'
@ echo ''
@ echo 'directory: $(dir_bin) $(dir_output) $(dir_objects)'
disasm: DEBUG=$(call generate-target,fxlibc,static,$(dir_objects),$(src))
@ $(objdump) -D $(target) | less export DEBUG
debug:
elf_sec: @ echo "$$DEBUG"
@ $(objdump) -h $(target) | less @ echo "target-lib: $(target-libs)"
@ echo "generated lib: $(generated-libs)"
.PHONY: help __debug disasm elf_sec @ echo "target format: $(target-formats)"
#--- #---
@ -159,10 +206,98 @@ elf_sec:
#--- #---
clean: clean:
rm -rf $(dir_objects) rm -rf $(dir_objects)
fclean: clean fclean: clean
rm -rf $(dir_bin) rm -rf $(dir_bin)
re: fclean clean re: fclean clean
.PHONY: clean fclean re .PHONY: clean fclean re
#---
# Build rules
#---
#all: $(target)
#
## linker part
#$(target): $(obj) | $(dir_bin)
# $(ar) crs $@ $^
#
## installation part
#install: $(target)
# install -d $(CONFIG.PREFIX)
# install $(target) -m 644 $(CONFIG.PREFIX)
# cp -r $(header) $(CONFIG.PREFIX)/include/fxlibc
#uninstall:
# rm -f $(CONFIG.PREFIX)/$(target)
# rm -rf $(CONFIG.PREFIX)/include/fxlibc
#
## Directory management
#$(dir_bin) $(dir_objects):
# @ printf "Create $(blue)$@$(nocolor) directory\n"
# @ mkdir -p $@
#
#.PHONY: all install uninstall
#
#
#
##define rule-src
##$(patsubst .._src_%,$(dir_objects)/%.o,$(subst /,_,$(basename $1))): $1 | $(dir_objects)
## @ printf "compiling $(white)$$<$(nocolor)..."
## @ $(gcc) $(cflags) -o $$@ -c $$< -lgcc
## @ printf "$(green)[ok]$(nocolor)\n"
##endef
##
##$(foreach source,$(src),$(eval \
## $(call rule-src,$(source))) \
##)
#
#
##---
## Debugging rules
##---
#help:
# @ echo 'make [options]...'
# @ echo ''
# @ echo 'Options:'
# @ echo ' * install install the library and headers to the PREFIX'
# @ echo ' * uninstall uninstall the library and headers of the PREFIX'
# @ echo ' * disasm use objdump to display the content of the archive'
# @ echo ' * debug display source files name and objects name'
# @ echo ' * elf_sec display ELF section of the archive'
#__debug:
# @ echo 'src: $(src)'
# @ echo ''
# @ echo 'obj: $(obj)'
# @ echo ''
# @ echo 'directory: $(dir_bin) $(dir_output) $(dir_objects)'
#
#disasm:
# @ $(objdump) -D $(target) | less
#
#elf_sec:
# @ $(objdump) -h $(target) | less
#
#.PHONY: help __debug disasm elf_sec
#
#
##---
## clean rules
##---
#clean:
# rm -rf $(dir_objects)
#
#fclean: clean
# rm -rf $(dir_bin)
#
#re: fclean clean
#
#.PHONY: clean fclean re