#!/usr/bin/env bash # # CONFIGURE, check requirements then set variables and create Makefiles # Copyright (C) 2017-2025 Xavier Delaruelle # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . ########################################################################## progpath=$0 progdir=${progpath%/*} # files to translate targetlist="${progdir}/Makefile.inc ${progdir}/site.exp" # argument list arglist="TCLSH PYTHON SPHINXBUILD PS BASENAME RMDIR_IGN_NON_EMPTY SED_ERE \ VERSION RELEASE baseprefix prefix bindir libdir libexecdir etcdir initdir \ datarootdir mandir docdir vimdatadir modulefilesdir setmanpath appendmanpath \ setbinpath appendbinpath setmodulespath docinstall vimaddons \ examplemodulefiles builddoc usemanpath libtclenvmodules SHLIB_SUFFIX \ multilibsupport libdir64 libdir32 versioning silentshdbgsupport \ setshellstartup quarantinesupport autohandling availindepth implicitdefault \ extendeddefault moduleshome initconfin pager pageropts verbosity color \ darkbgcolors lightbgcolors termbg lockedconfigs icase unloadmatchorder \ searchmatch modulepath loadedmodules quarantinevars wa277 advversspec ml \ windowssupport nearlyforbiddendays implicitrequirement tagabbrev \ tagcolorname mcookieversioncheck availoutput availterseoutput listoutput \ listterseoutput editor variantshortcut bashcompletiondir fishcompletiondir \ zshcompletiondir tcllinter tcllinteropts nagelfardatadir nagelfaraddons \ stickypurge uniquenameloaded abortonerror sourcecache logger loggeropts \ loggedevents conflictunload spideroutput spiderterseoutput spiderindepth \ emacsdatadir emacsaddons" libarglist=() # flags to know if argument has been specified on command-line defpageropts=1 defloggeropts=1 # set argument default values prefix=/usr/local/Modules setmanpath=y appendmanpath=n setbinpath=y appendbinpath=n setmodulespath=n docinstall=y vimaddons=y emacsaddons=y examplemodulefiles=y libtclenvmodules=y SHLIB_SUFFIX='.so' multilibsupport=n libdir64=undefined libdir32=undefined versioning=n silentshdbgsupport=n setshellstartup=n quarantinesupport=n autohandling=y conflictunload=n implicitrequirement=y availindepth=y spiderindepth=y implicitdefault=y extendeddefault=y advversspec=y ml=y wa277=n loadedmodules= quarantinevars= binsearchpath=/usr/bin:/bin:/usr/local/bin TCLSH=tclsh PYTHON=python SPHINXBUILD=sphinx-build builddoc=y usemanpath=y PS='ps' BASENAME='basename' RMDIR_IGN_NON_EMPTY='rmdir' SED_ERE='sed -E' VERSION= RELEASE= # shellcheck disable=SC2034 initconfin=etcdir loggedevents= logger='logger' loggeropts='-t modules' pager=less pageropts='-eFKRX' verbosity=normal color=y darkbgcolors='hi=1:db=2:tr=2:se=2:er=91:wa=93:me=95:in=94:mp=1;94:di=94:al=96:va=93:sy=95:de=4:cm=92:aL=100:L=90;47:H=2:F=41:nF=31;43:S=46:sS=44:kL=30;48;5;109:W=30;43' lightbgcolors='hi=1:db=2:tr=2:se=2:er=31:wa=33:me=35:in=34:mp=1;34:di=34:al=36:va=33:sy=35:de=4:cm=32:aL=107:L=47:H=2:F=101:nF=91;103:S=106:sS=104:kL=48;5;109:W=103' termbg=dark lockedconfigs= uniquenameloaded=n sourcecache=n unloadmatchorder=returnlast searchmatch=starts_with icase=search # these args are initialized here but as they depend on other argument value # they will get their default value later (after command-line parse) bindir= libdir= libexecdir= etcdir= initdir= datarootdir= mandir= docdir= vimdatadir= emacsdatadir= nagelfardatadir= modulefilesdir= moduleshome= modulepath= windowssupport=n nearlyforbiddendays=14 tagabbrev='auto-loaded=aL:loaded=L:hidden=H:hidden-loaded=H:forbidden=F:nearly-forbidden=nF:sticky=S:super-sticky=sS:keep-loaded=kL:warning=W' tagcolorname= stickypurge=error abortonerror='ml:reload:switch_unload' mcookieversioncheck=y availoutput='modulepath:alias:dirwsym:sym:tag:variantifspec:key' availterseoutput='modulepath:alias:dirwsym:sym:tag:variantifspec' listoutput='header:idx:variant:sym:tag:key' listterseoutput='header' spideroutput='modulepath:alias:dirwsym:sym:tag:variantifspec:via:key' spiderterseoutput=$availterseoutput editor='vi' variantshortcut= bashcompletiondir= fishcompletiondir= zshcompletiondir= tcllinter='nagelfar.tcl' tcllinteropts= nagelfaraddons=y # check if output/error channels are attached to terminal for i in 1 2; do if [ -t $i ]; then fdisterm[i]=1 else fdisterm[i]=0 fi done # apply SGR code to message if output channel is attached to terminal sgr() { local fd=$1 local code=$2 local msg=$3 if [ "${fdisterm[fd]}" -eq 1 ]; then local out="\033[${code}m${msg}\033[0m" else local out=$msg fi echo "$out" } # print message on stderr then exit echo_error() { local firstln=1 while [ $# -gt 0 ]; do if [ $firstln -eq 1 ]; then local msg msg="$(sgr 2 31 ERROR): $1" firstln=0 elif [ "$1" = 'tryhelp' ]; then msg="${msg}\n Try \`$progpath --help' for more information" else msg="${msg}\n $1" fi shift done echo -e "${msg}" >&2 exit 1 } # print message on stderr then exit echo_warning() { echo -e "$(sgr 1 33 WARNING): $1" } # print usage message echo_usage() { # shellcheck disable=SC2028 echo "Usage: $progpath [OPTION]... Check requirements then set variables and create Makefiles. Defaults for the options are specified in square brackets. Configuration: -h, --help display this help and exit Installation directories: --prefix=PREFIX install files in PREFIX [$prefix] By default, \`make install' will install all the files in \`$prefix/bin', \`$prefix/libexec', etc. You can specify an installation prefix other than \`$prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [PREFIX/bin] --libdir=DIR object code libraries [PREFIX/lib] --libexecdir=DIR program executables [PREFIX/libexec] --etcdir=DIR program configurations [PREFIX/etc] --initdir=DIR environment initialization scripts [PREFIX/init] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc] --vimdatadir=DIR Vim addons directory [DATAROOTDIR/vim/vimfiles] --emacsdatadir=DIR Emacs addons directory [DATAROOTDIR/emacs/lisp] --nagelfardatadir=DIR Nagelfar addons directory [DATAROOTDIR/nagelfar] --modulefilesdir=DIR system modulefiles [PREFIX/modulefiles] Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-set-manpath set mandir to MANPATH in init scripts [yes] --enable-append-manpath append rather prepend mandir to MANPATH [no] --enable-set-binpath set bindir to PATH in init scripts [yes] --enable-append-binpath append rather prepend bindir to PATH [no] --enable-modulespath, --enable-dotmodulespath configure modules path in modulespath file rather than initrc file (or respectively in .modulespath file rather modulerc file if \`--with-initconf-in' is set to 'initdir') [no] --enable-doc-install install documentation files in the documentation directory defined with \'docdir' (no impact on man pages installation) [yes] --enable-vim-addons install Vim addon files in the directory defined with \'vimdatadir' [yes] --enable-emacs-addons install Emacs addon files in the directory defined with \'emacsdatadir' [yes] --enable-nagelfar-addons install Nagelfar addon files in the directory defined with \'nagelfardatadir' [yes] --enable-example-modulefiles install in 'modulefilesdir' some modulefiles provided as examples [yes] --enable-libtclenvmodules build and install the Modules Tcl extension library and enable its load in modulecmd.tcl [yes] --enable-multilib-support support multilib systems by looking at an alternative location where to find the Modules Tcl extension lib depending on current machine architecture. [no] --enable-versioning append modules version to installation prefix and deploy a \`versions' modulepath, shared between all versioning enabled Modules installation, containing modulefiles that enable to switch from one Modules version to another [no] --enable-silent-shell-debug-support generate code in module function definition to add support for silencing shell debugging properties [no] --enable-set-shell-startup set when module function is defined the shell startup file to ensure that the module function is still defined in sub-shells [no] --enable-quarantine-support generate code in module function definition to add support for the environment variable quarantine mechanism [no] --enable-auto-handling set modulecmd.tcl to automatically apply automated modulefiles handling actions, like loading the pre-requisites of a modulefile when loading this modulefile [yes] --enable-conflict-unload set modulecmd.tcl to automatically unload modules that conflict with modules to load and the dependent of these conflicting modules [no] --enable-implicit-requirement implicitly define a requirement toward modules specified on ``module load`` or ``module unload`` commands in modulefile [yes] --enable-avail-indepth control whether \`avail' search results should recursively include or not modulefiles from directories matching search query [yes] --enable-spider-indepth control whether \`spider' search results should recursively include or not modulefiles from directories matching search query [yes] --enable-implicit-default implicitly set a default version for modules with none defined [yes] --enable-extended-default allow partial module version specification [yes] --enable-advanced-version-spec activate the advanced module version specificers to specify finer constraints on module version. [yes] --enable-unique-name-loaded only allow one module loaded per module name. [no] --enable-source-cache cache files evaluated through \`source' Tcl command. [no] --enable-ml define \`ml' command when Modules initializes [yes] --enable-color control colored output. \`yes' equals to the \`auto' color mode. \`no' equals to the \`never' color mode [yes] --enable-wa-277 activate workaround for Tcsh history issue [no] --enable-windows-support install all required files for Windows platform [no] --enable-new-features enable all new features that are disabled by default due to substantial behavior changes they imply on Modules 5 [no] --enable-mcookie-version-check enable check of the version specified right after Modules magic cookie in modulefiles, which defines the minimal version of the Modules tool to use to evaluate the modulefile [yes] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-bin-search-path=PATHLIST list of paths to look at when searching the location of tools required to build and configure Modules [$binsearchpath] --with-moduleshome location of the main Modules package file directory [$prefix] --with-initconf-in=VALUE location where to install Modules initialization configuration files. Either \`initdir' or \`etcdir' [etcdir] --with-tclsh=BIN name or full path of Tcl interpreter shell [tclsh] --with-logger=BIN name or full path of default logger program to use to log some evaluation information (can be super- seeded at run-time by environment variable) [$logger] --with-logger-opts=OPTLIST settings to apply to default logger program [$loggeropts] --with-logged-events=EVENTLIST events to log. accepted event names in EVENTLIST are \`auto_eval', \`requested_eval' and \`requested_cmd' (each event name in EVENTLIST should be separated by \`:') [$loggedevents] --with-pager=BIN name or full path of default pager program to use to paginate informational message output (can be super- seeded at run-time by environment variable) [$pager] --with-pager-opts=OPTLIST settings to apply to default pager program [$pageropts] --with-verbosity=VALUE specify default message verbosity. accepted values are \`silent', \`concise', \`normal', \`verbose', \`verbose2', \`trace', \`debug' and \`debug2' [$verbosity] --with-dark-background-colors=SGRLIST default color set to apply if terminal background color is defined to \`dark'. Each element in SGRLIST is an output item associated to a Select Graphic Rendition (SGR) code (elements in SGRLIST are separated by \`:') [$darkbgcolors] --with-light-background-colors=SGRLIST default color set to apply if terminal background color is defined to \`light'. Expect the same syntax than described for \`--with-dark-background-colors' [$lightbgcolors] --with-terminal-background=VALUE terminal background color which determines the color set to apply by default between the \`dark' background colors or the \`light' background colors [$termbg] --with-locked-configs=CONFIGLIST ignore environment variable superseding value for listed configuration options. accepted option names in CONFIGLIST are \`extra_siteconfig', \`implicit_default', \`logged_events' and \`logger' (each option name in CONFIGLIST should be separated by \` ') [$lockedconfigs] --with-unload-match-order=VALUE when unloading a module if multiple loaded modules match the request, unload module loaded first (\`returnfirst') or module loaded last (\`returnlast') [$unloadmatchorder] --with-search-match=VALUE when searching for a module, query string should match the beginning of module name (\`starts_with') or any part of module name (\`contains') [$searchmatch] --with-icase=VALUE apply a case insensitive match to module specification on search-like sub-commands (\`search'), on all sub-commands and modulefile Tcl commands (\`always') or disable case insensitive match (\`never') [$icase] --with-nearly-forbidden-days=VALUE define the number of days a module is considered nearly forbidden prior reaching its expiry date [$nearlyforbiddendays] --with-tag-abbrev=ABBRVLIST define the abbreviation to use when reporting each module tag. Each element in ABBRVLIST is a tag name associated to an abbreviation string (elements in ABBRVLIST are separated by \`:') [$tagabbrev] --with-tag-color-name=TAGLIST define the tags whose graphical rendering should be applied over their name instead of over the name of the module they are attached to. Each element in TAGLIST is a tag name or abbreviation (elements in TAGLIST are separated by \`:') [$tagcolorname] --with-sticky-purge=VALUE define the kind of error to render when unloading a sticky or super-sticky module during a purge. Raise an \`error' or report a \`warning' or be \`silent'. [$stickypurge] --with-abort-on-error=LIST list of sub-commands that should abort when a module evaluation fails instead of continuing their evaluation sequence. sub-commands accepted in LIST are: \`load', \`ml', \`mod-to-sh', \`purge', \`reload', \`switch', \`switch_unload', \`try-load' and \`unload' (elements in LIST are separated by \`:') [$abortonerror] --with-avail-output=LIST specify content to report on avail sub-command regular output. elements accepted in LIST are: \`modulepath', \`alias', \`dirwsym', \`indesym', \`sym', \`tag', \`key', \`hidden', \`variant', \`variantifspec' and \`via' (elements in LIST are separated by \`:') [$availoutput] --with-avail-terse-output=LIST specify content to report on avail sub-command terse output. elements accepted in LIST are: \`modulepath', \`alias', \`dirwsym', \`indesym', \`sym', \`tag', \`key', \`hidden', \`variant' and \`variantifspec' (elements in LIST are separated by \`:') [$availterseoutput] --with-list-output=LIST specify content to report on list sub-command regular output. elements accepted in LIST are: \`header', \`idx', \`variant', \`alias', \`indesym', \`sym', \`tag', \`hidden' and \`key' (elements in LIST are separated by \`:') [$listoutput] --with-list-terse-output=LIST specify content to report on list sub-command terse output. elements accepted in LIST are: \`header', \`idx', \`variant', \`alias', \`indesym', \`sym', \`tag', \`hidden' and \`key' (elements in LIST are separated by \`:') [$listterseoutput] --with-spider-output=LIST specify content to report on spider sub-command regular output. elements accepted in LIST are: \`modulepath', \`alias', \`dirwsym', \`indesym', \`sym', \`tag', \`key', \`hidden', \`variant', \`variantifspec' and \`via' (elements in LIST are separated by \`:') [$spideroutput] --with-spider-terse-output=LIST specify content to report on spider sub-command terse output. elements accepted in LIST are: \`modulepath', \`alias', \`dirwsym', \`indesym', \`sym', \`tag', \`key', \`hidden', \`variant' and \`variantifspec' (elements in LIST are separated by \`:') [$spiderterseoutput] --with-variant-shortcut=SHORTCUTLIST define shortcut characters to specify variant names. Each element in SHORTCUTLIST is a variant name associated to a shortcut character (elements in SHORTCUTLIST are separated by \`:') [$variantshortcut] --with-editor=BIN name or full path of default editor program to use to edit modulefiles [$editor] --with-modulepath=PATHLIST default modulepaths to set in default configuration file to be enabled (each path in PATHLIST should be separated by \`:') [PREFIX/modulefiles or BASEPREFIX/\$MODULE_VERSION/modulefiles if versioning installation mode enabled] --with-loadedmodules=MODLIST default modulefiles to set in default configuration file to be loaded (each modulefile name in MODLIST should be separated by \`:') [] --with-quarantine-vars='VARNAME[=VALUE] ...' environment variables to put in quarantine when running the module command to ensure it a sane execution environment (each variable should be separated by \` '). a value can eventually be set to a quarantine variable instead of emptying it. [] --with-tcl directory containing the Tcl configuration script tclConfig.sh. --with-tclinclude directory containing the Tcl header files. --with-python=BIN name or full path of Python interpreter command to use as shebang for helper scripts [$PYTHON] --with-bashcompletiondir=DIR Bash completions directory [] --with-fishcompletiondir=DIR Fish completions directory [] --with-zshcompletiondir=DIR Zsh completions directory [] --with-tcl-linter=BIN name of full path of program to use to lint Tcl modulefiles [$tcllinter] --with-tcl-linter-opts=OPTLIST settings to apply to tcl linter program [$tcllinteropts] Depending on the above configuration options the files are approximately placed in the following directory structure: PREFIX/ bin/ etc/ init/ lib/ libexec/ share/ doc/ emacs/ lisp/ man/ man1/ man5/ nagelfar/ vim/ vimfiles/ modulefiles/" } # check requirement availability check_requirement() { typeset req=$1 typeset optmesg=$2 typeset cmdenv=$3 if [ $# -gt 3 ]; then shift 3 else shift $# fi for cmd in $req "${@}"; do if [ -n "$cmd" ]; then echo -n "checking for ${cmd}... " if [ -n "$cmdenv" ]; then cmdsearch="$cmdenv command -v $cmd" else cmdsearch="command -v $cmd" fi reqpath=$(eval "$cmdsearch") if [ -n "$reqpath" ]; then echo "$reqpath" break else echo "not found" fi fi done if [ -z "$reqpath" ]; then if [ -z "$optmesg" ]; then echo_error "$req could not be found" # no message output if message set to '-' elif [ "$optmesg" != '-' ]; then echo_warning "$optmesg" fi fi } # parse optional argument to find if feature is enabled or disabled get_feature_value() { typeset val="${1#*=}" if [ "${1//--enable/}" != "$1" ]; then if [ "$val" = 'no' ]; then echo 'n' else echo 'y' fi else echo 'n' fi } # parse optional argument to extract package's option get_package_option() { typeset option="${1%=*}" echo "${option/#--without/--with}" } # parse optional argument to find package is set or disabled get_package_value() { typeset val_raw="${1#*=}" typeset dfl_without_val="$2" if [ "${1/#--with-/}" = "$1" ] || [ "$val_raw" = 'no' ]; then value="$dfl_without_val" else value="$val_raw" fi echo "$value" } check_and_get_package_value() { typeset arg_raw="$2" typeset allowed_values="$3" typeset dfl_without_val="$4" option=$(get_package_option "$arg_raw") value=$(get_package_value "$arg_raw" "$dfl_without_val") if [ "${allowed_values// $value /}" = "$allowed_values" ]; then echo_error "Bad value for option \`$option'"\ "Allowed values are:$allowed_values" fi typeset -g "$1"="$value" } check_and_get_package_value_list() { typeset arg_raw="$2" typeset allowed_values="$3" typeset dfl_without_val="$4" option=$(get_package_option "$arg_raw") value=$(get_package_value "$arg_raw" "$dfl_without_val") ORIG_IFS=$IFS IFS=: for val in $value; do if [ "${allowed_values// $val /}" = "$allowed_values" ]; then echo_error "Bad value '$val' set in option \`$option'"\ "Values allowed in list are:$allowed_values" fi done IFS=$ORIG_IFS typeset -g "$1"="$value" } # parse arguments for arg in "$@"; do # set argument value defined with "--arg val" form if [ -n "${nextargisval+x}" ]; then declare "$nextargisval"="$arg" unset nextargisval continue # set lib argument value defined with "--arg val" form elif [ -n "${nextargislibarg+x}" ]; then libarglist+=("$arg"); unset nextargislibarg continue # current arg should be skipped elif [ -n "${nextargisign+x}" ]; then unset nextargisign continue fi case "$arg" in --prefix=*) prefix="${arg#*=}" ;; --prefix) nextargisval=prefix ;; --bindir=*) bindir="${arg#*=}" ;; --bindir) nextargisval=bindir ;; --libdir=*) libdir="${arg#*=}" ;; --libdir) nextargisval=libdir ;; --libexecdir=*) libexecdir="${arg#*=}" ;; --libexecdir) nextargisval=libexecdir ;; --etcdir=*) etcdir="${arg#*=}" ;; --etcdir) nextargisval=etcdir ;; --initdir=*) initdir="${arg#*=}" ;; --initdir) nextargisval=initdir ;; --datarootdir=*) datarootdir="${arg#*=}" ;; --datarootdir) nextargisval=datarootdir ;; --mandir=*) mandir="${arg#*=}" ;; --mandir) nextargisval=mandir ;; --docdir=*) docdir="${arg#*=}" ;; --docdir) nextargisval=docdir ;; --vimdatadir=*) vimdatadir="${arg#*=}" ;; --vimdatadir) nextargisval=vimdatadir ;; --emacsdatadir=*) emacsdatadir="${arg#*=}" ;; --emacsdatadir) nextargisval=emacsdatadir ;; --nagelfardatadir=*) nagelfardatadir="${arg#*=}" ;; --nagelfardatadir) nextargisval=nagelfardatadir ;; --modulefilesdir=*) modulefilesdir="${arg#*=}" ;; --modulefilesdir) nextargisval=modulefilesdir ;; --enable-set-manpath*|--disable-set-manpath) # shellcheck disable=SC2034 setmanpath=$(get_feature_value "$arg") ;; --enable-append-manpath*|--disable-append-manpath) # shellcheck disable=SC2034 appendmanpath=$(get_feature_value "$arg") ;; --enable-set-binpath*|--disable-set-binpath) # shellcheck disable=SC2034 setbinpath=$(get_feature_value "$arg") ;; --enable-append-binpath*|--disable-append-binpath) # shellcheck disable=SC2034 appendbinpath=$(get_feature_value "$arg") ;; --enable-dotmodulespath*|--disable-dotmodulespath|--enable-modulespath*|--disable-modulespath) setmodulespath=$(get_feature_value "$arg") ;; --enable-doc-install*|--disable-doc-install) # shellcheck disable=SC2034 docinstall=$(get_feature_value "$arg") ;; --enable-vim-addons*|--disable-vim-addons) # shellcheck disable=SC2034 vimaddons=$(get_feature_value "$arg") ;; --enable-emacs-addons*|--disable-emacs-addons) # shellcheck disable=SC2034 emacsaddons=$(get_feature_value "$arg") ;; --enable-nagelfar-addons*|--disable-nagelfar-addons) # shellcheck disable=SC2034 nagelfaraddons=$(get_feature_value "$arg") ;; --enable-example-modulefiles*|--disable-example-modulefiles) # shellcheck disable=SC2034 examplemodulefiles=$(get_feature_value "$arg") ;; --enable-libtclenvmodules*|--disable-libtclenvmodules) libtclenvmodules=$(get_feature_value "$arg") ;; --enable-multilib-support*|--disable-multilib-support) multilibsupport=$(get_feature_value "$arg") ;; --enable-versioning*|--disable-versioning) versioning=$(get_feature_value "$arg") ;; --enable-silent-shell-debug-support*|--disable-silent-shell-debug-support) # shellcheck disable=SC2034 silentshdbgsupport=$(get_feature_value "$arg") ;; --enable-set-shell-startup*|--disable-set-shell-startup) # shellcheck disable=SC2034 setshellstartup=$(get_feature_value "$arg") ;; --enable-quarantine-support*|--disable-quarantine-support) # shellcheck disable=SC2034 quarantinesupport=$(get_feature_value "$arg") ;; --enable-auto-handling*|--disable-auto-handling) # shellcheck disable=SC2034 autohandling=$(get_feature_value "$arg") ;; --enable-conflict-unload*|--disable-conflict-unload) # shellcheck disable=SC2034 conflictunload=$(get_feature_value "$arg") ;; --enable-implicit-requirement*|--disable-implicit-requirement) # shellcheck disable=SC2034 implicitrequirement=$(get_feature_value "$arg") ;; --enable-avail-indepth*|--disable-avail-indepth) # shellcheck disable=SC2034 availindepth=$(get_feature_value "$arg") ;; --enable-spider-indepth*|--disable-spider-indepth) # shellcheck disable=SC2034 spiderindepth=$(get_feature_value "$arg") ;; --enable-implicit-default*|--disable-implicit-default) # shellcheck disable=SC2034 implicitdefault=$(get_feature_value "$arg") ;; --enable-extended-default*|--disable-extended-default) # shellcheck disable=SC2034 extendeddefault=$(get_feature_value "$arg") ;; --enable-advanced-version-spec*|--disable-advanced-version-spec) # shellcheck disable=SC2034 advversspec=$(get_feature_value "$arg") ;; --enable-unique-name-loaded*|--disable-unique-name-loaded) # shellcheck disable=SC2034 uniquenameloaded=$(get_feature_value "$arg") ;; --enable-source-cache*|--disable-source-cache) # shellcheck disable=SC2034 sourcecache=$(get_feature_value "$arg") ;; --enable-ml*|--disable-ml) # shellcheck disable=SC2034 ml=$(get_feature_value "$arg") ;; --enable-wa-277*|--disable-wa-277) # shellcheck disable=SC2034 wa277=$(get_feature_value "$arg") ;; --enable-windows-support*|--disable-windows-support) # shellcheck disable=SC2034 windowssupport=$(get_feature_value "$arg") ;; --enable-mcookie-version-check*|--disable-mcookie-version-check) # shellcheck disable=SC2034 mcookieversioncheck=$(get_feature_value "$arg") ;; --with-bin-search-path=*|--without-bin-search-path) binsearchpath=$(get_package_value "$arg") ;; --with-moduleshome=*|--without-moduleshome) moduleshome=$(get_package_value "$arg") ;; --with-initconf-in=*|--without-initconf-in) allowedval=" initdir etcdir " ; check_and_get_package_value "initconfin" "$arg" "$allowedval" ;; --with-tclsh=*|--without-tclsh) tclshbin=$(get_package_value "$arg") ;; --with-logger=*|--without-logger) logger=$(get_package_value "$arg" "") ;; --with-logger-opts=*|--without-logger-opts) loggeropts=$(get_package_value "$arg" "") defloggeropts=0 ;; --with-logged-events=*|--without-logged-events) allowedval=" auto_eval requested_eval requested_cmd " ; check_and_get_package_value_list "loggedevents" "$arg" "$allowedval" "" ;; --with-pager=*|--without-pager) pager=$(get_package_value "$arg" "") ;; --with-pager-opts=*|--without-pager-opts) pageropts=$(get_package_value "$arg" "") defpageropts=0 ;; --with-verbosity=*|--without-verbosity) allowedval=" silent concise normal verbose trace debug debug2 " ; check_and_get_package_value "verbosity" "$arg" "$allowedval" ;; --enable-color*|--disable-color) # shellcheck disable=SC2034 color=$(get_feature_value "$arg") ;; --enable-new-features*|--disable-new-features) val=$(get_feature_value "$arg") ; if [ "$val" = 'y' ]; then abortonerror='load:ml:reload:switch' ; # shellcheck disable=SC2034 conflictunload=y ; fi ;; --with-dark-background-colors=*|--without-dark-background-colors) darkbgcolors=$(get_package_value "$arg" "") ;; --with-light-background-colors=*|--without-light-background-colors) lightbgcolors=$(get_package_value "$arg" "") ;; --with-terminal-background=*|--without-terminal-background) allowedval=" dark light " ; check_and_get_package_value "termbg" "$arg" "$allowedval" ;; --with-locked-configs=*|--disable-locked-configs) lockedconfigs=$(get_package_value "$arg" "") ; allowedval=" extra_siteconfig implicit_default logged_events logger " ; for val in $lockedconfigs; do if [ "${allowedval// $val /}" = "$allowedval" ]; then echo_error "Bad value for option \`--with-locked-configs'"\ "Allowed values are:$allowedval" fi ; done ;; --with-unload-match-order=*|--without-unload-match-order) allowedval=" returnlast returnfirst " ; check_and_get_package_value "unloadmatchorder" "$arg" "$allowedval" ;; --with-search-match=*|--without-search-match) allowedval=" starts_with contains " ; check_and_get_package_value "searchmatch" "$arg" "$allowedval" ;; --with-icase=*|--without-icase) allowedval=" never search always " ; check_and_get_package_value "icase" "$arg" "$allowedval" "never";; --with-nearly-forbidden-days=*|--without-nearly-forbidden-days) nearlyforbiddendays=$(get_package_value "$arg") ; if [ -z "$nearlyforbiddendays" ] || ! [ "$nearlyforbiddendays" -eq "$nearlyforbiddendays" ] 2>/dev/null\ || ! [ "$nearlyforbiddendays" -ge 0 ] || ! [ "$nearlyforbiddendays" -le 365 ]; then echo_error "Bad value for option \`--with-nearly-forbidden-days'"\ "Value should be an integer comprised between 0 and 365" fi ;; --with-tag-abbrev=*|--without-tag-abbrev) tagabbrev=$(get_package_value "$arg" "") ;; --with-tag-color-name=*|--without-tag-color-name) tagcolorname=$(get_package_value "$arg" "") ;; --with-sticky-purge=*|--without-sticky-purge) allowedval=" error warning silent " ; check_and_get_package_value "stickypurge" "$arg" "$allowedval" ;; --with-abort-on-error=*|--without-abort-on-error) allowedval=" load ml mod-to-sh purge reload switch switch_unload try-load unload " ; check_and_get_package_value_list "abortonerror" "$arg" "$allowedval" "" ;; --with-avail-output=*|--without-avail-output) allowedval=" modulepath alias dirwsym indesym sym tag key hidden variant variantifspec via " ; check_and_get_package_value_list "availoutput" "$arg" "$allowedval" "" ;; --with-avail-terse-output=*|--without-avail-terse-output) allowedval=" modulepath alias dirwsym indesym sym tag key hidden variant variantifspec " ; check_and_get_package_value_list "availterseoutput" "$arg" "$allowedval" "" ;; --with-list-output=*|--without-list-output) allowedval=" header idx variant alias indesym sym tag hidden key " ; check_and_get_package_value_list listoutput "$arg" "$allowedval" "" ;; --with-list-terse-output=*|--without-list-terse-output) allowedval=" header idx variant alias indesym sym tag hidden key " ; check_and_get_package_value_list "listterseoutput" "$arg" "$allowedval" "" ;; --with-spider-output=*|--without-spider-output) allowedval=" modulepath alias dirwsym indesym sym tag key hidden variant variantifspec via " ; check_and_get_package_value_list "spideroutput" "$arg" "$allowedval" "" ;; --with-spider-terse-output=*|--without-spider-terse-output) allowedval=" modulepath alias dirwsym indesym sym tag key hidden variant variantifspec " ; check_and_get_package_value_list "spiderterseoutput" "$arg" "$allowedval" "" ;; --with-variant-shortcut=*|--without-variant-shortcut) variantshortcut=$(get_package_value "$arg" "") ;; --with-editor=*|--without-editor) editor=$(get_package_value "$arg") ;; --with-modulepath=*|--without-modulepath) modulepath=$(get_package_value "$arg" "") ;; --with-loadedmodules=*|--without-loadedmodules) loadedmodules=$(get_package_value "$arg" "") ;; --with-quarantine-vars=*|--without-quarantine-vars) # shellcheck disable=SC2034 quarantinevars=$(get_package_value "$arg" "") ;; --with-bashcompletiondir=*|--without-bashcompletiondir) # shellcheck disable=SC2034 bashcompletiondir=$(get_package_value "$arg" "") ;; --with-fishcompletiondir=*|--without-fishcompletiondir) # shellcheck disable=SC2034 fishcompletiondir=$(get_package_value "$arg" "") ;; --with-zshcompletiondir=*|--without-zshcompletiondir) # shellcheck disable=SC2034 zshcompletiondir=$(get_package_value "$arg" "") ;; --with-tcl-linter=*|--without-tcl-linter) tcllinter=$(get_package_value "$arg" "") ;; --with-tcl-linter-opts=*|--without-tcl-linter-opts) # shellcheck disable=SC2034 tcllinteropts=$(get_package_value "$arg" "") ;; --with-tcl=*|--without-tcl|--with-tclinclude=*|--without-tclinclude) libarglist+=("$arg") ;; --with-python=*|--without-python) pythonbin=$(get_package_value "$arg") ;; --with-module-path=*) echo_warning "Option \`--with-module-path' ignored, use \`--modulepath' instead" ;; -h|--help) echo_usage exit 0 ;; --build|--host|--target) # pass argument supported by lib to its ./configure script libarglist+=("$arg") ; # and set next arg should also be send to lib script nextargislibarg=y ;; --build=*|--host=*|--target=*) # pass argument supported by lib to its ./configure script libarglist+=("$arg") ;; --program-prefix|--program-suffix|--program-transform-name|--exec-prefix|\ --sbindir|--sysconfdir|--datadir|--includedir|--localstatedir|\ --sharedstatedir|--infodir|--runstatedir|--oldincludedir|--localedir|\ --htmldir|--dvidir|--pdfdir|--psdir) # ignore standard configure option and value which has no meaning here echo_warning "Option \`$arg' ignored" ; nextargisign=y ;; --program-prefix=*|--program-suffix=*|--program-transform-name=*|\ --exec-prefix=*|--sbindir=*|--sysconfdir=*|--datadir=*|--includedir=*|\ --localstatedir=*|--sharedstatedir=*|--infodir=*|--runstatedir=*|\ --oldincludedir=*|--localedir=*|--htmldir=*|--dvidir=*|--pdfdir=*|\ --psdir=*) # ignore standard configure option which has no meaning here echo_warning "Option \`$arg' ignored" ;; --enable-*|--disable-*|--with-*|--without-*) # ignore --enable-*/--with-* options not supported here to comply with # GNU Configuration specification # (https://www.gnu.org/prep/standards/html_node/Configuration.html) echo_warning "Option \`$arg' ignored" ;; -*) echo_error "Unrecognized option \`$arg'" tryhelp;; *=*) echo -e "Export \`$arg' in environment" ; export "${arg?}" ;; *) # type of system to build the program for (not needed here but useful # for true autoconf configure script below libarglist+=("$arg") ;; esac done # test requirements availability check_requirement uname kernelname=$(uname -s) # Makefile for this project are GNU Makefile so we must ensure correct make # command is available, on Linux/Darwin systems the 'make' bin refers to GNU # Make whereas on other system it is not the default make flavor, so 'gmake' # should be checked case "$kernelname" in Linux|Darwin|CYGWIN*|MINGW*|MSYS_NT*) make='make' ;; *) make='gmake' esac check_requirement $make check_requirement sed check_requirement runtest "Install \`dejagnu' if you want to run the \ testsuite" check_requirement manpath 'Will rely on MANPATH to get enabled man directories' # shellcheck disable=SC2034 [ -z "$reqpath" ] && usemanpath=n # rmdir option may not be available, use || true in any case # shellcheck disable=SC2034 if [ "$kernelname" = 'Linux' ]; then RMDIR_IGN_NON_EMPTY='rmdir --ignore-fail-on-non-empty' else RMDIR_IGN_NON_EMPTY='rmdir' fi # sed -E option may not be available, use -r option otherwise if [ "$(echo foo | $SED_ERE 's|foo|bar|' 2>/dev/null)" != 'bar' ]; then SED_ERE='sed -r' fi export GIT_DIR="${progdir}/.git" export GIT_WORK_TREE="${progdir}" test -e "${GIT_DIR}" work_from_git_repo=$? # if we install from git repository, must have git to fetch current release number if [ $work_from_git_repo -eq 0 ]; then check_requirement git fi # if pre-built docs are available (but not from a previous make run), no doc # build but install pre-built files builddocdir="${progdir}/doc/build" oldbuilddoc=$(sed -n '/^builddoc/{s/.*:= //p;q;}' Makefile.inc 2>/dev/null) if [ -e "${builddocdir}/changes.txt" ] && [ -e "${builddocdir}/MIGRATING.txt" ] \ && [ -e "${builddocdir}/INSTALL.txt" ] && [ -e "${builddocdir}/INSTALL-win.txt" ] \ && [ -e "${builddocdir}/NEWS.txt" ] && [ -e "${builddocdir}/CONTRIBUTING.txt" ] \ && [ -e "${builddocdir}/module.1.in" ] && [ -e "${builddocdir}/ml.1" ] \ && [ -e "${builddocdir}/envml.1" ] && [ -e "${builddocdir}/modulefile.5" ] \ && [ "$oldbuilddoc" != 'y' ]; then builddoc=p # test sphinx availability otherwise else # pass even if sphinx not there but no doc will be built check_requirement sphinx-build "Install \`sphinx-build' if you want to \ build the documentation" '' 'sphinx-1.0-build' # shellcheck disable=SC2034 SPHINXBUILD=$reqpath # shellcheck disable=SC2034 [ -z "$reqpath" ] && builddoc=n fi # get tclsh location from standard PATHs or /usr/local/bin # or validate location passed as argument if [ -n "$tclshbin" ]; then check_requirement "$tclshbin" '' "PATH=$binsearchpath" else # also check version-specific names in case no generic tclsh binary exists check_requirement $TCLSH '' "PATH=$binsearchpath" 'tclsh8.6' 'tclsh8.5' 'tclsh8.4' fi TCLSH=$reqpath # python is mandatory if installing from git repository to build ChangeLog if [ $work_from_git_repo -eq 0 ]; then missmsg='' elif [ -n "$pythonbin" ]; then missmsg="Specified Python command \`$pythonbin' cannot be found" else missmsg='-' fi # only look at --with-python specification if set if [ -n "$pythonbin" ]; then check_requirement "$pythonbin" "$missmsg" "PATH=$binsearchpath" else check_requirement $PYTHON "$missmsg" "PATH=$binsearchpath" 'python3' 'python2' fi # define a generic launching name if command not found at build time if [ -z "$reqpath" ]; then # use --with-python specification if set if [ "${pythonbin:0:1}" = '/' ]; then PYTHON="$pythonbin" elif [ -n "$pythonbin" ]; then PYTHON="/usr/bin/env $pythonbin" else PYTHON="/usr/bin/env $PYTHON" fi else PYTHON=$reqpath fi # gzip is mandatory if installing from git repository to build ChangeLog.gz if [ $work_from_git_repo -eq 0 ]; then check_requirement gzip fi # get location of commands used 'fullpath' in init scripts check_requirement 'ps' '' "PATH=$binsearchpath" # shellcheck disable=SC2034 PS=$reqpath check_requirement 'basename' '' "PATH=$binsearchpath" # shellcheck disable=SC2034 BASENAME=$reqpath # get logger program location from standard PATHs or /usr/local/bin # or validate location passed as argument if [ -n "$logger" ]; then check_requirement "$logger" '' "PATH=$binsearchpath" logger=$reqpath fi # adapt logger program settings dependings of specified args if [ $defloggeropts -eq 1 ] && [ "${logger##*/}" != 'logger' ]; then loggeropts='' echo_warning "As chosen logger is not \`logger', default logger options are cleared" fi # get pager program location from standard PATHs or /usr/local/bin # or validate location passed as argument if [ -n "$pager" ]; then check_requirement "$pager" '' "PATH=$binsearchpath" pager=$reqpath fi # adapt pager program settings dependings of specified args if [ $defpageropts -eq 1 ] && [ "${pager##*/}" != 'less' ]; then pageropts='' echo_warning "As chosen pager is not \`less', default pager options are cleared" fi if [ -n "$tcllinter" ]; then check_requirement "$tcllinter" "$tcllinter could not be found" "PATH=$binsearchpath" if [ -n "$reqpath" ]; then tcllinter=$reqpath fi fi # fetch modules version from version.inc.in file (which may be raw data to # refine or exact values if dist has been built by `git archive`) if [ -r "${progdir}/version.inc.in" ]; then release=$(sed -n '/^MODULES_RELEASE/{s/.*= //p;q;}' \ "${progdir}/version.inc.in") build_hash=$(sed -n '/^MODULES_BUILD_HASH/{s/.*= //p;q;}' \ "${progdir}/version.inc.in") build_refs=$(sed -n '/^MODULES_BUILD_REFS/{s/.*= //p;q;}' \ "${progdir}/version.inc.in") build_refs=${build_refs//,} build_refs=${build_refs//origin\/} else echo_error "${progdir}/version.inc.in is missing" fi # refine build number if working from git repository # shellcheck disable=SC2016 if [ $work_from_git_repo -eq 0 ]; then gitcurtag=$(git describe --tags --abbrev=0) gitcurdesc=$(git describe --tags) gitcurbranch=$(git rev-parse --abbrev-ref HEAD) if [ "$gitcurtag" = "$gitcurdesc" ]; then build='' elif [ "$gitcurbranch" = 'main' ]; then build="+${gitcurdesc#"${gitcurtag}"-}" else build="+${gitcurbranch}${gitcurdesc#"${gitcurtag}"}" fi # set a recognizable build number if one found in version.inc.in is raw data elif [ "$build_hash" = '$Format:%h' ]; then build='+XX-gffffffff' # or compute it from these information as if working from git repository elif [[ " $build_refs " == *" v$release "* ]]; then build='' elif [[ " $build_refs " == *" main "* ]]; then build="+XX-g$build_hash" # %D placeholder may not be known by old version of git elif [ "$build_refs" = "%D" ]; then build="+XX-g$build_hash" else build="+${build_refs##* }-XX-g$build_hash" fi VERSION=$release$build # shellcheck disable=SC2034 RELEASE=$release if [ -z "$VERSION" ]; then echo_error "Cannot fetch modules version" fi # refer to binary exes and libs to build with the appropriate extension # shellcheck disable=SC2034 case "$kernelname" in CYGWIN*) SHLIB_SUFFIX='.dll' ;; MINGW*|MSYS_NT*) SHLIB_SUFFIX='.dll' ;; Darwin) SHLIB_SUFFIX='.dylib' ;; esac # adapt prefix if versioning enabled baseprefix=$prefix if [ "$versioning" = 'y' ]; then # append modules version to installation prefix prefix=$prefix/$VERSION fi # set argument default values for those depending of other argument [ -z "$bindir" ] && bindir=$prefix/bin [ -z "$libdir" ] && libdir=$prefix/lib [ -z "$libexecdir" ] && libexecdir=$prefix/libexec [ -z "$etcdir" ] && etcdir=$prefix/etc [ -z "$initdir" ] && initdir=$prefix/init [ -z "$datarootdir" ] && datarootdir=$prefix/share [ -z "$mandir" ] && mandir=$datarootdir/man [ -z "$docdir" ] && docdir=$datarootdir/doc [ -z "$vimdatadir" ] && vimdatadir=$datarootdir/vim/vimfiles [ -z "$emacsdatadir" ] && emacsdatadir=$datarootdir/emacs/lisp [ -z "$nagelfardatadir" ] && nagelfardatadir=$datarootdir/nagelfar [ -z "$modulefilesdir" ] && modulefilesdir=$prefix/modulefiles [ -z "$moduleshome" ] && moduleshome=$prefix # default modulepath based on MODULE_VERSION if versioning enabled [ -z "$modulepath" ] && [ "$versioning" = 'y' ] && modulepath=${modulefilesdir/#$prefix/$baseprefix\/\$MODULE_VERSION} [ -z "$modulepath" ] && modulepath=$modulefilesdir # define libdir64 and libdir32 based on libdir if multilib support enabled if [ "$multilibsupport" = 'y' ]; then # shellcheck disable=SC2034 case "$libdir" in *64*) libdir64=$libdir ; libdir32=${libdir/64} ;; *) libdir64=${libdir/lib/lib64} ; libdir32=$libdir ;; esac fi # check feature requirements are met if [ "$setmodulespath" = 'y' ] && [ -n "$loadedmodules" ]; then featmesg="As \`setmodulespath' is enabled beware that \`loadedmodules' may be ignored by init scripts" echo_warning "$featmesg" fi if [ -n "$loadedmodules" ] && [ -z "$modulepath" ]; then featmesg="A value is set for \`loadedmodules' whereas \`modulepath' is not defined" echo_warning "$featmesg" fi # prepare extension library sources if not yet done whether libtclenvmodules # is enabled or not to create consistent dist in any cases. if [ ! -e "${progdir}/lib/configure" ]; then check_requirement autoreconf echo "--- preparing extension library sources ----------" pushd "${progdir}/lib" || exit 1 autoreconf -i || exit 1 popd || exit 1 echo "--------------------------------------------------" fi # display configuration set # and build Makefile translation expression translation_regexp=() for arg in ${arglist}; do echo "$arg = ${!arg}" translation_regexp+=('-e' "s|@${arg}@|${!arg}|g") done # configure extension library sources if [ "$libtclenvmodules" = 'y' ]; then echo "--- configuring extension library sources --------" echo "libarglist = ${libarglist[*]}" pushd "${progdir}/lib" || exit 1 ./configure "${libarglist[@]}" || exit 1 popd || exit 1 echo "--------------------------------------------------" fi # generate Makefiles for target in ${targetlist}; do # escape any '$' in value for Makefile or testsuite interpretation if [ "${target/Makefile}" = "${target}" ]; then extra_regexp=() else extra_regexp=('-e' 's|\$|\$\$|g') fi echo "creating $target" sed "${translation_regexp[@]}" "${extra_regexp[@]}" "${target}.in" >"$target" done exit 0 # vim:set tabstop=3 shiftwidth=3 expandtab autoindent: