Wed, 02 Jul 2025 23:21:17 +0200
resolve TODOs regarding input.h
a) mouse position must be integer, because it can be negative (though rarely)
b) we should not trade "access complexity" for space in the scancodes array
#!/bin/sh # some utility functions isplatform() { for p in $PLATFORM do if [ "$p" = "$1" ]; then return 0 fi done return 1 } notisplatform() { for p in $PLATFORM do if [ "$p" = "$1" ]; then return 1 fi done return 0 } istoolchain() { for t in $TOOLCHAIN do if [ "$t" = "$1" ]; then return 0 fi done return 1 } notistoolchain() { for t in $TOOLCHAIN do if [ "$t" = "$1" ]; then return 1 fi done return 0 } # clean abort abort_configure() { rm -Rf "$TEMP_DIR" exit 1 } # Test for availability of pkg-config PKG_CONFIG=`command -v pkg-config` : ${PKG_CONFIG:="false"} # Simple uname based platform detection # $PLATFORM is used for platform dependent dependency selection OS=`uname -s` OS_VERSION=`uname -r` printf "detect platform... " if [ "$OS" = "SunOS" ]; then PLATFORM="solaris sunos unix svr4" elif [ "$OS" = "Linux" ]; then PLATFORM="linux unix" elif [ "$OS" = "FreeBSD" ]; then PLATFORM="freebsd bsd unix" elif [ "$OS" = "OpenBSD" ]; then PLATFORM="openbsd bsd unix" elif [ "$OS" = "NetBSD" ]; then PLATFORM="netbsd bsd unix" elif [ "$OS" = "Darwin" ]; then PLATFORM="macos osx bsd unix" elif echo "$OS" | grep -i "MINGW" > /dev/null; then PLATFORM="windows mingw" fi : ${PLATFORM:="unix"} PLATFORM_NAME=`echo "$PLATFORM" | cut -f1 -d' ' -` echo "$PLATFORM_NAME" # help text printhelp() { echo "Usage: $0 [OPTIONS]..." cat << __EOF__ Installation directories: --prefix=PREFIX path prefix for architecture-independent files [$prefix] --exec-prefix=EPREFIX path prefix for architecture-dependent files [PREFIX] --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR system configuration files [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR run-time variable data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --mandir=DIR man documentation [DATAROOTDIR/man] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] Build Types: --debug add extra compile flags for debug builds --release add extra compile flags for release builds Optional Features: --enable-asan Enable address sanitization. __EOF__ } # create temporary directory TEMP_DIR=".tmp-`uname -n`" rm -Rf "$TEMP_DIR" if mkdir -p "$TEMP_DIR"; then : else echo "Cannot create tmp dir $TEMP_DIR" echo "Abort" exit 1 fi touch "$TEMP_DIR/options" touch "$TEMP_DIR/features" # define standard variables # also define standard prefix (this is where we will search for config.site) prefix=/usr exec_prefix= bindir= sbindir= libdir= libexecdir= datarootdir= datadir= sysconfdir= sharedstatedir= localstatedir= runstatedir= includedir= infodir= localedir= mandir= # custom variables if true \ ; then SRCDIR=`pwd` fi # features # # parse arguments # BUILD_TYPE="default" for ARG in "$@" do case "$ARG" in "--prefix="*) prefix=${ARG#--prefix=} ;; "--exec-prefix="*) exec_prefix=${ARG#--exec-prefix=} ;; "--bindir="*) bindir=${ARG#----bindir=} ;; "--sbindir="*) sbindir=${ARG#--sbindir=} ;; "--libdir="*) libdir=${ARG#--libdir=} ;; "--libexecdir="*) libexecdir=${ARG#--libexecdir=} ;; "--datarootdir="*) datarootdir=${ARG#--datarootdir=} ;; "--datadir="*) datadir=${ARG#--datadir=} ;; "--sysconfdir="*) sysconfdir=${ARG#--sysconfdir=} ;; "--sharedstatedir="*) sharedstatedir=${ARG#--sharedstatedir=} ;; "--localstatedir="*) localstatedir=${ARG#--localstatedir=} ;; "--includedir="*) includedir=${ARG#--includedir=} ;; "--infodir="*) infodir=${ARG#--infodir=} ;; "--mandir"*) mandir=${ARG#--mandir} ;; "--localedir"*) localedir=${ARG#--localedir} ;; "--help"*) printhelp; abort_configure ;; "--debug") BUILD_TYPE="debug" ;; "--release") BUILD_TYPE="release" ;; "--enable-asan") FEATURE_ASAN=on ;; "--disable-asan") unset FEATURE_ASAN ;; "-"*) echo "unknown option: $ARG"; abort_configure ;; esac done # set defaults for dir variables : ${exec_prefix:="$prefix"} : ${bindir:='${exec_prefix}/bin'} : ${sbindir:='${exec_prefix}/sbin'} : ${libdir:='${exec_prefix}/lib'} : ${libexecdir:='${exec_prefix}/libexec'} : ${datarootdir:='${prefix}/share'} : ${datadir:='${datarootdir}'} : ${sysconfdir:='${prefix}/etc'} : ${sharedstatedir:='${prefix}/com'} : ${localstatedir:='${prefix}/var'} : ${runstatedir:='${localstatedir}/run'} : ${includedir:='${prefix}/include'} : ${infodir:='${datarootdir}/info'} : ${mandir:='${datarootdir}/man'} : ${localedir:='${datarootdir}/locale'} # remember the above values and compare them later orig_bindir="$bindir" orig_sbindir="$sbindir" orig_libdir="$libdir" orig_libexecdir="$libexecdir" orig_datarootdir="$datarootdir" orig_datadir="$datadir" orig_sysconfdir="$sysconfdir" orig_sharedstatedir="$sharedstatedir" orig_localstatedir="$localstatedir" orig_runstatedir="$runstatedir" orig_includedir="$includedir" orig_infodir="$infodir" orig_mandir="$mandir" orig_localedir="$localedir" # check if a config.site exists and load it if [ -n "$CONFIG_SITE" ]; then # CONFIG_SITE may contain space separated file names for cs in $CONFIG_SITE; do printf "loading defaults from $cs... " . "$cs" echo ok done elif [ -f "$prefix/share/config.site" ]; then printf "loading site defaults... " . "$prefix/share/config.site" echo ok elif [ -f "$prefix/etc/config.site" ]; then printf "loading site defaults... " . "$prefix/etc/config.site" echo ok fi # generate vars.mk cat > "$TEMP_DIR/vars.mk" << __EOF__ prefix=$prefix exec_prefix=$exec_prefix bindir=$bindir sbindir=$sbindir libdir=$libdir libexecdir=$libexecdir datarootdir=$datarootdir datadir=$datadir sysconfdir=$sysconfdir sharedstatedir=$sharedstatedir localstatedir=$localstatedir runstatedir=$runstatedir includedir=$includedir infodir=$infodir mandir=$mandir localedir=$localedir __EOF__ # toolchain detection utilities . make/toolchain.sh # # DEPENDENCIES # # check languages lang_c= lang_cpp= if detect_c_compiler ; then lang_c=1 fi # create buffer for make variables required by dependencies echo > "$TEMP_DIR/make.mk" test_pkg_config() { if "$PKG_CONFIG" --exists "$1" ; then : else return 1 ; fi if [ -z "$2" ] || "$PKG_CONFIG" --atleast-version="$2" "$1" ; then : else return 1 ; fi if [ -z "$3" ] || "$PKG_CONFIG" --exact-version="$3" "$1" ; then : else return 1 ; fi if [ -z "$4" ] || "$PKG_CONFIG" --max-version="$4" "$1" ; then : else return 1 ; fi return 0 } print_check_msg() { if [ -z "$1" ]; then shift printf "$@" fi } dependency_error_sdl2_ttf() { print_check_msg "$dep_checked_sdl2_ttf" "checking for sdl2_ttf... " # dependency sdl2_ttf while true do if [ -z "$PKG_CONFIG" ]; then break fi if test_pkg_config "SDL2_ttf" "" "" "" ; then TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags SDL2_ttf`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs SDL2_ttf`" else break fi print_check_msg "$dep_checked_sdl2_ttf" "yes\n" dep_checked_sdl2_ttf=1 return 1 done print_check_msg "$dep_checked_sdl2_ttf" "no\n" dep_checked_sdl2_ttf=1 return 0 } dependency_error_asan() { print_check_msg "$dep_checked_asan" "checking for asan... " # dependency asan toolchain="gnuc" while true do if notistoolchain "gnuc"; then break fi TEMP_CFLAGS="$TEMP_CFLAGS -fsanitize=address" TEMP_LDFLAGS="$TEMP_LDFLAGS -fsanitize=address" print_check_msg "$dep_checked_asan" "yes\n" dep_checked_asan=1 return 1 done print_check_msg "$dep_checked_asan" "no\n" dep_checked_asan=1 return 0 } dependency_error_sdl2() { print_check_msg "$dep_checked_sdl2" "checking for sdl2... " # dependency sdl2 while true do if [ -z "$PKG_CONFIG" ]; then break fi if test_pkg_config "sdl2" "" "" "" ; then TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags sdl2`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs sdl2`" else break fi print_check_msg "$dep_checked_sdl2" "yes\n" dep_checked_sdl2=1 return 1 done print_check_msg "$dep_checked_sdl2" "no\n" dep_checked_sdl2=1 return 0 } dependency_error_sdl2_image() { print_check_msg "$dep_checked_sdl2_image" "checking for sdl2_image... " # dependency sdl2_image while true do if [ -z "$PKG_CONFIG" ]; then break fi if test_pkg_config "SDL2_image" "" "" "" ; then TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags SDL2_image`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs SDL2_image`" else break fi print_check_msg "$dep_checked_sdl2_image" "yes\n" dep_checked_sdl2_image=1 return 1 done print_check_msg "$dep_checked_sdl2_image" "no\n" dep_checked_sdl2_image=1 return 0 } dependency_error_glew() { print_check_msg "$dep_checked_glew" "checking for glew... " # dependency glew while true do if [ -z "$PKG_CONFIG" ]; then break fi if test_pkg_config "glew" "" "" "" ; then TEMP_CFLAGS="$TEMP_CFLAGS `"$PKG_CONFIG" --cflags glew`" TEMP_LDFLAGS="$TEMP_LDFLAGS `"$PKG_CONFIG" --libs glew`" else break fi print_check_msg "$dep_checked_glew" "yes\n" dep_checked_glew=1 return 1 done print_check_msg "$dep_checked_glew" "no\n" dep_checked_glew=1 return 0 } dependency_error_ucx() { print_check_msg "$dep_checked_ucx" "checking for ucx... " # dependency ucx while true do if check_lib ucx cx/common.h > /dev/null ; then : else break fi TEMP_LDFLAGS="$TEMP_LDFLAGS -lucx" print_check_msg "$dep_checked_ucx" "yes\n" dep_checked_ucx=1 return 1 done print_check_msg "$dep_checked_ucx" "no\n" dep_checked_ucx=1 return 0 } # start collecting dependency information echo > "$TEMP_DIR/flags.mk" DEPENDENCIES_FAILED= ERROR=0 # unnamed dependencies TEMP_CFLAGS="$CFLAGS" TEMP_CXXFLAGS="$CXXFLAGS" TEMP_LDFLAGS="$LDFLAGS" while true do while true do if [ -z "$lang_c" ] ; then ERROR=1 break fi TEMP_LDFLAGS="$TEMP_LDFLAGS -lm" cat >> "$TEMP_DIR/make.mk" << __EOF__ srcdir=$SRCDIR __EOF__ break done break done # build type if [ "$BUILD_TYPE" = "debug" ]; then TEMP_CFLAGS="\${DEBUG_CFLAGS}$TEMP_CFLAGS" TEMP_CXXFLAGS="\${DEBUG_CXXFLAGS}$TEMP_CXXFLAGS" fi if [ "$BUILD_TYPE" = "release" ]; then TEMP_CFLAGS="\${RELEASE_CFLAGS}$TEMP_CFLAGS" TEMP_CXXFLAGS="\${RELEASE_CXXFLAGS}$TEMP_CXXFLAGS" fi # add general dependency flags to flags.mk echo "# general flags" >> "$TEMP_DIR/flags.mk" if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_LDFLAGS}" ]; then echo "LDFLAGS += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" fi # # OPTION VALUES # # # TARGETS # echo >> "$TEMP_DIR/flags.mk" echo "configuring global target" echo "# flags for unnamed target" >> "$TEMP_DIR/flags.mk" TEMP_CFLAGS= TEMP_CXXFLAGS= TEMP_LDFLAGS= if dependency_error_ucx; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED ucx " ERROR=1 fi if dependency_error_sdl2; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED sdl2 " ERROR=1 fi if dependency_error_sdl2_ttf; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED sdl2_ttf " ERROR=1 fi if dependency_error_sdl2_image; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED sdl2_image " ERROR=1 fi if dependency_error_glew; then DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED glew " ERROR=1 fi # Features if [ -n "$FEATURE_ASAN" ]; then # check dependency if dependency_error_asan ; then # "auto" features can fail and are just disabled in this case if [ "$FEATURE_ASAN" = "auto" ]; then DISABLE_FEATURE_ASAN=1 else DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED asan " ERROR=1 fi fi if [ -n "$DISABLE_FEATURE_ASAN" ]; then unset FEATURE_ASAN fi fi if [ -n "$FEATURE_ASAN" ]; then : else : fi if [ -n "${TEMP_CFLAGS}" ] && [ -n "$lang_c" ]; then echo "CFLAGS += $TEMP_CFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_CXXFLAGS}" ] && [ -n "$lang_cpp" ]; then echo "CXXFLAGS += $TEMP_CXXFLAGS" >> "$TEMP_DIR/flags.mk" fi if [ -n "${TEMP_LDFLAGS}" ]; then echo "LDFLAGS += $TEMP_LDFLAGS" >> "$TEMP_DIR/flags.mk" fi # final result if [ $ERROR -ne 0 ]; then echo echo "Error: Unresolved dependencies" echo "$DEPENDENCIES_FAILED" abort_configure fi echo "configure finished" echo echo "Toolchain" echo " name: $TOOLCHAIN_NAME" if [ -n "$TOOLCHAIN_CC" ]; then echo " cc: $TOOLCHAIN_CC" fi if [ -n "$TOOLCHAIN_CXX" ]; then echo " cxx: $TOOLCHAIN_CXX" fi if [ -n "$TOOLCHAIN_WSIZE" ]; then echo " word size: $TOOLCHAIN_WSIZE bit" fi if [ -n "$TOOLCHAIN_CSTD" ]; then echo " default C std: $TOOLCHAIN_CSTD" fi echo echo "Build Config:" echo " prefix: $prefix" echo " exec_prefix: $exec_prefix" if [ "$orig_bindir" != "$bindir" ]; then echo " bindir: $bindir" fi if [ "$orig_sbindir" != "$sbindir" ]; then echo " sbindir: $sbindir" fi if [ "$orig_libdir" != "$libdir" ]; then echo " libdir: $libdir" fi if [ "$orig_libexecdir" != "$libexecdir" ]; then echo " libexecdir: $libexecdir" fi if [ "$orig_datarootdir" != "$datarootdir" ]; then echo " datarootdir: $datarootdir" fi if [ "$orig_datadir" != "$datadir" ]; then echo " datadir: $datadir" fi if [ "$orig_sysconfdir" != "$sysconfdir" ]; then echo " sysconfdir: $sysconfdir" fi if [ "$orig_sharedstatedir" != "$sharedstatedir" ]; then echo " sharedstatedir: $sharedstatedir" fi if [ "$orig_localstatedir" != "$localstatedir" ]; then echo " localstatedir: $localstatedir" fi if [ "$orig_runstatedir" != "$runstatedir" ]; then echo " runstatedir: $runstatedir" fi if [ "$orig_includedir" != "$includedir" ]; then echo " includedir: $includedir" fi if [ "$orig_infodir" != "$infodir" ]; then echo " infodir: $infodir" fi if [ "$orig_mandir" != "$mandir" ]; then echo " mandir: $mandir" fi if [ "$orig_localedir" != "$localedir" ]; then echo " localedir: $localedir" fi echo echo "Features:" if [ -n "$FEATURE_ASAN" ]; then echo " asan: on" else echo " asan: off" fi echo # generate the config.mk file pwd=`pwd` cat > "$TEMP_DIR/config.mk" << __EOF__ # # config.mk generated by: # pwd: $pwd # $0 $@ # __EOF__ write_toolchain_defaults "$TEMP_DIR/toolchain.mk" cat "$TEMP_DIR/config.mk" "$TEMP_DIR/vars.mk" "$TEMP_DIR/toolchain.mk" "$TEMP_DIR/flags.mk" "$TEMP_DIR/make.mk" > config.mk rm -Rf "$TEMP_DIR"