From 9c59763ad77f095691a67103a1a7af9e64af140d Mon Sep 17 00:00:00 2001 From: Yatis Date: Wed, 7 Oct 2020 11:37:54 +0200 Subject: [PATCH] update Makefile --- .gitignore | 1 + configure | 160 ++++++++++++++++----------- make/Makefile.default | 245 ++++++++++++++++++++++++++++++++---------- 3 files changed, 287 insertions(+), 119 deletions(-) diff --git a/.gitignore b/.gitignore index 378eac2..4cf1d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build +*.txt diff --git a/configure b/configure index 0bd4a17..05d7ac5 100755 --- a/configure +++ b/configure @@ -1,4 +1,9 @@ #! /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 confile='fxlibc.cfg' @@ -13,38 +18,41 @@ makefile='Makefile.default' # configuration declare -A config -config[__SUPPORT_VHEX_KERNEL]=false config[__DEBUG]=false config[__ENABLE_VALGRIND]=false -config[__SUPPORT_CASIO_ABI_FX9860]=false -config[__SUPPORT_CASIO_ABI_FXCG50]=false +config[__SUPPORT_VHEX_KERNEL]=false +config[__SUPPORT_CASIO_FX9860]=false +config[__SUPPORT_CASIO_FXCG50]=false -# +#--- # Help screen -# +#--- help() { cat << EOF -Configuration script for the fx calculator libc. +Configuration script for the fx calculator standard C library. Usage: $0 [OPTION]... You should build out-of-tree by creating a build directory and configuring from there. Debug the fxlibc - --debug enable valgrind flags (-g3) - --unit-test check C-functoon validity with Criterion + --debug Enable valgrind flags (-g3) + --unit-test Check C-functoon validity with Criterion Build options: - --toolchain=TRIPLET Build with a different toolchain - [sh-elf-gcc] (or [gcc] when the '--unit_test' flag is set) - --cflags=FLAGS Additional compiler flags at end of command + --toolchain=TRIPLET Build with a different toolchain + [sh-elf-gcc] (or [gcc] when the '--unit_test' flag is set) + --cflags=FLAGS Additional compiler flags at end of command + --prefix=PREFIX Install prefix (PREFIX/lib and PREFIX/include are used) ABI support: - --vhex-support Enable the Vhex kernel support - --casio-support=fx9860|fxcg50 - enable the support of the Casio' ABI (used by malloc, free, ...) - + --support-vhex + Enable the Vhex kernel support + --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 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. 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: - --dyn-lib generate dynamic librairies (Vhex kernel dependant) + --dyn-lib Generate dynamic librairies (Vhex kernel dependant) -Little note for the generation of dynamic libraries. -The superH toolchain currently used (GCC) does not support the '--shared' flags -when the archive is build. So we need to create manually an archive that can be -used like a shared librairy. +Little note for the generation of dynamic libraries. The superH toolchain currently +used (GCC) does not support the '--shared' flags when the archive is build. So we +need to create manually an archive that can be used like a shared library. 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. 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 - shared librairies and will call internal VHEX loader primitives with the - librairies name, function address and size, etc....Then the loader will - load the shared function and override the "user function (stub)" to force - it to jump into the "real" function (trampoline) -4) all generated stubs will be compiled and linked throught a static lib that - SHOULD be used in the user program which use the "dynamic librairy" - +3) we create "stubs": functions that will have the same name than the wanted shared + libraries and will call internal VHEX loader primitives with the libraries + name, function address and size, etc....Then the loader will load the shared + function and override the "user function (stub)" to force it to jump into + the "real" function (trampoline). +4) all generated stubs will be compiled and linked through a static lib that SHOULD + be used in the user program which uses the "dynamic library" EOF exit 0 } @@ -85,8 +91,8 @@ EOF # from there. # if [ -f 'make/Makefile.default' ]; then - echo "error: you should configure from a build directory, like this:" >&2 - echo " mkdir build && cd build && ../configure [options..]" >&2 + echo 'error: you should configure from a build directory, like this:' >&2 + echo ' mkdir build && cd build && ../configure [options..]' >&2 exit 1 fi @@ -95,15 +101,16 @@ fi # Parsing arguments # for arg; do case "$arg" in - --help | -h) + --help | -h) help;; + # debug options --debug) config[__DEBUG]=true;; --unit-test) makefile='Malefile.unitest';; - + # build options --toolchain=*) toolchain=${arg#*=};; --prefix=*) @@ -111,68 +118,93 @@ for arg; do case "$arg" in --cflags=*) cflags=${arg#*=};; - --vhex-support) + # ABI support + --support-vhex) config[__SUPPORT_VHEX_KERNEL]=true;; - --casio-abi=*) - case ${arg#*=} in - "fx9860g") - config[__SUPPORT_CASIO_ABI_FX9860]=true;; - "fcg50") - config[__SUPPORT_CASIO_ABI_FXCG50]=true;; - *) - echo -e "\033[1;33merror\033[0m unreconized target '$arg'" - exit 1 - esac;; + --support-casio-abi-fx9860) + config[__SUPPORT_CASIO_ABI_FX9860]=true;; + --support-casio-abi-fxcg50) + config[__SUPPORT_CASIO_ABI_FXCG50]=true;; + # format options --dyn-lib) 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 esac; done -# +#--- # Check error -# -if [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ]; then - echo -e "\033[1;33merror\033[0m too many target" +#--- +# Check ABI support error +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 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 # @note: # * We have 3 makefile: normal, dynlib, unit_test -# +#--- dst='Makefile' src="../make/$makefile" 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 fi -[ -L $src ] && [ "$(readlink $src)" == $dst ] && rm $dst +[ $dst ] && [ "$(readlink $dst)" == $src ] && rm $dst ln -s $src $dst -# +#--- # Generate the configuration file -# -function generate_config() +#--- +generate_config() { - echo "CONFIG.TOOLCHAIN = $toolchain" - [ "$prefix" ] && echo "PREFIX = $prefix" - [ "$cflags" ] && echo "CONFIG.CFLAGS = $cflags" + echo "CONFIG.CFLAGS := " + echo "CONFIG.TARGET := " + echo "CONFIG.TOOLCHAIN := $toolchain" + [ "$prefix" ] && echo "CONFIG.PREFIX := $prefix" + [ "$cflags" ] && echo "CONFIG.CFLAGS += $cflags" - [ ${config[__DEBUG]} = true ] && echo -n '-g3' - [ ${config[__SUPPORT_VHEX_KERNEL]} = true ] && echo -n ' -D __SUPPORT_VHEX_KERNEL' - [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && echo -n ' -D ___SUPPORT_CASIO_ABI_FX9860' - [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ] && echo -n ' -D ___SUPPORT_CASIO_ABI_FXCG50' - echo '' + #[ ${config[__DEBUG]} = true ] && echo "CONFIG.CFLAGS += -g3" + [ ${config[__SUPPORT_VHEX_KERNEL]} = true ] && echo "CONFIG.TARGET += fxlibc-vhex" + [ ${config[__SUPPORT_CASIO_ABI_FX9860]} = true ] && echo "CONFIG.TARGET += fxlibc-fx9860" + [ ${config[__SUPPORT_CASIO_ABI_FXCG50]} = true ] && echo "CONFIG.TARGET += fxlibc-fxcg50" } generate_config > $confile - echo "Configuration saved in $confile, ready to make!" exit 0 diff --git a/make/Makefile.default b/make/Makefile.default index 62702b0..ac21371 100644 --- a/make/Makefile.default +++ b/make/Makefile.default @@ -23,12 +23,15 @@ # |-- fxlibc_stubs.a (workaround for the shared librairie, see documentation note) # |-- fxlibc.so (shared librairy) # `-- fxlibc.a (static librairy) +# +# TODO: +# * generate all libraries for all ABI by default ? +# * handle versionning #--- #--- # 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 := fxlibc.cfg @@ -37,11 +40,10 @@ $(error "config file $(CONFIG) does not exist (reconfigure or wipe directory)") endif include $(CONFIG) - # Compiler flags, assembler flags, dependency generation, archiving -header := -I ../include +header := ../include cflags := $(machine) -ffreestanding -nostdlib -Wall -Wextra -std=c11 -Os \ - -fstrict-volatile-bitfields $(header) $(CONFIG.CFLAGS) + -fstrict-volatile-bitfields -I$(header) $(CONFIG.CFLAGS) # color definition red := \033[1;31m @@ -57,7 +59,8 @@ define n endef # Define all directory used to stored informations -dir_objects := objects +dir_object := object +dir_output := output dir_bin := bin # Output configurations @@ -65,19 +68,14 @@ name := fxlibc target := $(dir_bin)/$(name).a # automated variable -src := -directory := $(shell find ../src/ -not -path "*/\.*" -type d) -$(foreach path,$(directory),$(eval \ - src += $(wildcard $(path)/*.c) $n\ - src += $(wildcard $(path)/*.S) $n\ - src += $(wildcard $(path)/*.s) $n\ -)) -obj := $(patsubst .._src_%,$(dir_objects)/%.o,$(subst /,_,$(basename $(src)))) +directory := $(shell find ../src -not -path "*/\.*" -type d) +src := $(foreach path,$(directory), \ + $(wildcard $(path)/*.c) \ + $(wildcard $(path)/*.S) \ + $(wildcard $(path)/*.s)) + + -# 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 + + #--- # Version management #--- # TODO + + #--- # 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 -$(target): $(obj) | $(dir_bin) - $(ar) crs $@ $^ - -# Directory management -$(dir_bin) $(dir_objects): - @ printf "Create $(blue)$@$(nocolor) directory\n" +# Create directory helper +# @note: Just use "$*" and "$@" to refer to the directory being created. +%/: + @ printf "Create $(blue)$*$(nocolor) directory\n" @ mkdir -p $@ +.PRECIOUS: %/ -.PHONY: all #--- # Automated rules #--- -define rule-src -$(patsubst .._src_%,$(dir_objects)/%.o,$(subst /,_,$(basename $1))): $1 | $(dir_objects) - @ printf "compiling $(white)$$<$(nocolor)..." +# common part used to compile source file +# @params: +# *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 @ printf "$(green)[ok]$(nocolor)\n" endef -$(foreach source,$(src),$(eval \ - $(call rule-src,$(source))) \ +# common part used by all library geneation +# @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: - @ 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)' +all: $(generated-libs) -disasm: - @ $(objdump) -D $(target) | less - -elf_sec: - @ $(objdump) -h $(target) | less - -.PHONY: help __debug disasm elf_sec +DEBUG=$(call generate-target,fxlibc,static,$(dir_objects),$(src)) +export DEBUG +debug: + @ echo "$$DEBUG" + @ echo "target-lib: $(target-libs)" + @ echo "generated lib: $(generated-libs)" + @ echo "target format: $(target-formats)" #--- @@ -159,10 +206,98 @@ elf_sec: #--- clean: rm -rf $(dir_objects) - fclean: clean rm -rf $(dir_bin) - re: fclean clean - .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