# # $Id: general.in,v 1.100 2004/05/14 16:43:09 jmmv Exp $ # Base support functions # # buildtool # Copyright (c) 2002, 2003, 2004 Julio M. Merino Vidal. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. Neither the name of the author nor the names of contributors may # be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # Language=c AutoTypes= # -------------------------------------------------------------------- # Main functions # -------------------------------------------------------------------- bt_init() { if [ -z "${BT_PKG_NAME}" -o -z "${BT_PKG_VERSION}" ]; then btcmn_err "defs file not included or misses information" fi BT_TOPDIR=$(pwd) [ ! -d ${BT_WORKDIR} ] && mkdir -p ${BT_WORKDIR} BT_CONFIGH=${BT_WORKDIR}/bt_config.h BT_CONFIGMK=${BT_WORKDIR}/bt_config.mk BT_CONFIGENV=${BT_WORKDIR}/bt_config.env BT_CONFIGSED=${BT_WORKDIR}/bt_config.sed BT_LOGICENV=${BT_WORKDIR}/bt_logic.env BT_OUTPUT=${BT_WORKDIR}/bt_output : ${BT_PATH:=${PATH}} btcmn_log_start ${BT_WORKDIR}/bt_config.log BT_FILES_CLEANDIRTOP="${BT_CONFIGH} ${BT_CONFIGMK} ${BT_CONFIGENV}" BT_FILES_CLEANDIRTOP+="${BT_LOGICENV}" BT_FILES_CLEANDIRTOP+=$(btcmn_log_name) BT_FILES_CLEANDIRTOP+="${BT_CONFIGSED} ${BT_OUTPUT}" BT_FLAGS_CPP="-I. -I${BT_TOPDIR} -I${BT_WORKDIR} ${BT_FLAGS_CPP}" bt_msg "starting configuration for ${BT_PKG_NAME}-${BT_PKG_VERSION}" bt_define BT_PKG_NAME "${BT_PKG_NAME}" bt_define BT_PKG_VERSION "${BT_PKG_VERSION}" bt_define BT_PKG_LICENSE "${BT_PKG_LICENSE}" bt_define BT_PKG_MAINTAINER "${BT_PKG_MAINTAINER}" bt_define BT_PKG_HOMEPAGE "${BT_PKG_HOMEPAGE}" bt_subst BT_PKG_NAME BT_PKG_VERSION BT_PKG_LICENSE bt_subst BT_PKG_MAINTAINER BT_PKG_HOMEPAGE BT_PKG_COMMENT bt_subst BT_TOPDIR BT_WORKDIR bt_subst BT_CONFIGH BT_CONFIGMK BT_CONFIGENV BT_OUTPUT bt_subst BT_PATH : ${BT_BIN_GROUP:=DEFAULT} : ${BT_BIN_MODE:=0555} : ${BT_BIN_OWNER:=DEFAULT} bt_subst BT_BIN_GROUP BT_BIN_MODE BT_BIN_OWNER : ${BT_DATA_GROUP:=DEFAULT} : ${BT_DATA_MODE:=0644} : ${BT_DATA_OWNER:=DEFAULT} bt_subst BT_DATA_GROUP BT_DATA_MODE BT_DATA_OWNER : ${BT_DIR_GROUP:=DEFAULT} : ${BT_DIR_MODE:=0755} : ${BT_DIR_OWNER:=DEFAULT} bt_subst BT_DIR_GROUP BT_DIR_MODE BT_DIR_OWNER local hook for hook in ${BT_INIT_HOOKS}; do ${hook} done } bt_argsinit() { BT_PREFIX=/usr/local bt_subst BT_PREFIX bt_msg_summary 'Prefix is: ${BT_PREFIX}' if [ "${BT_USE_WORKDIR}" = yes ]; then BT_WORKDIR=${BT_TOPDIR}/work.bt else BT_WORKDIR=${BT_TOPDIR} fi bt_dir BIN '${BT_PREFIX}/bin' \ "Where user executables are installed." bt_dir DOC '${BT_PREFIX}/share/doc/${BT_PKG_NAME}' \ "Where package documentation is installed." bt_dir ETC '${BT_PREFIX}/etc' \ "Where system wide configuration files will be searched." bt_dir EXAMPLES \ '${BT_PREFIX}/share/examples/${BT_PKG_NAME}' \ "Where configuration files (between others) are installed." bt_dir INCLUDE '${BT_PREFIX}/include' \ "Where include files (commonly used by C/C++) are installed." bt_dir INFO '${BT_PREFIX}/info' \ "Where info documentation is installed (top level directory)." bt_dir LIB '${BT_PREFIX}/lib' \ "Where shared and static libraries are installed." bt_dir LIBDATA '${BT_PREFIX}/libdata' \ "Where static data related to libraries are installed." bt_dir LIBEXEC '${BT_PREFIX}/libexec' \ "Where executables related to libraries are installed." bt_dir MAN '${BT_PREFIX}/man' \ "Where manual pages are installed (top level directory)." bt_dir PKGFLAGS '@DIR_PKGFLAGS@' \ "Where package flags files are installed." bt_dir SBIN '${BT_PREFIX}/sbin' \ "Where super-user executables are installed." bt_dir SHARE '${BT_PREFIX}/share' \ "Where machine independant data is installed." bt_dir VAR '${BT_PREFIX}/var' \ "Where variable data will be created." bt_feature SHARED auto \ "Whether shared libraries are built (yes, no, auto)." bt_feature STATIC auto \ "Whether static libraries are built (yes, no, auto)." bt_feature RPATH yes \ "Whether rpath is supported or wanted (yes, no)." # Developer mode bt_feature DEVELOPER no \ "Whether developer mode is enabled or not (yes, no)." bt_msg_summary 'Developer mode: ${BT_FEATURE_DEVELOPER}' # Install documentation? bt_feature DOC yes \ "Whether to install documentation or not (yes, no)." bt_msg_summary 'Install documentation: ${BT_FEATURE_DOC}' } bt_finish() { local hook for hook in ${BT_FINISH_HOOKS}; do ${hook} done bt_generate_configenv bt_generate_logicenv btcmn_log_msg "Configuration successful" } bt_define() { local value=$(echo $2 | tr ' ' '¬') if [ -z ${value} ]; then Defines_Quoted_List+=$1 else Defines_Quoted_List+="$1=${value}" fi } bt_define_unquoted() { value=$(echo $2 | tr ' ' '¬') if [ -z ${value} ]; then Defines_Unquoted_List+=$1 else Defines_Unquoted_List+="$1=${value}" fi } bt_subst() { local var for var in $*; do Subst_List+=${var} done } bt_subst_cache() { Subst_List+=${Cache_List} } bt_cache() { local var for var in $*; do Cache_List+=${var} done } bt_subrload() { local d found name path name=$1.subr path=$(echo ${BT_PATH_SUBRS}:@DIR_SHARE@/bt_config | tr ':' ' ') echo "bt_config: loading subroutines ${name}" found= for d in ${path}; do if [ -f ${d}/${name} ]; then . "${d}/${name}" found=yes fi done if [ -z "${found}" ]; then bt_err "cannot load required subroutine file ${name}." \ "if it exists, set a proper path in BT_PATH_SUBRS." fi } bt_def_name() { if [ ${BT_REQUIRE} '<' 0.16 ]; then echo "${1}_$(echo $3 | swcase -ud)" else echo "${1}_$(echo $2 | swcase -ud)_$(echo $3 | swcase -ud)" fi } bt_cache_name() { echo "${1}_$(echo $2 | swcase -ud)_$(echo $3 | swcase -ud)" } bt_define_ml_check() { eval "$1() { \ if ! isfunc ${1}_\${Language}; then btcmn_warn \"the \\\`$1' check is not supported by the \\\`\${Language}' language\" # NOLINT else ${1}_\${Language} \"\$@\" fi }" } # -------------------------------------------------------------------- # File generation functions # -------------------------------------------------------------------- bt_generate_output() { local sep var [ -z "${BT_PROG_SH}" ] && bt_check_prog_sh bt_msg "creating bt_output" AutoTypes+=output cat > ${BT_OUTPUT} < \${f} elif [ -f \${BT_SRCDIR}/\${f}.in ]; then echo "\${progname}: creating \${f}" sed -f \${configsed} < \${BT_SRCDIR}/\${f}.in > \${f} else echo "\${progname}: \${f}.in not found" fi done EOF chmod +x ${BT_OUTPUT} rm -f ${BT_CONFIGSED} touch ${BT_CONFIGSED} for var in ${Subst_List}; do eval val=\"\$${var}\" sep=, echo ${var}${val} | grep ${sep} >/dev/null && sep='|' eval eval echo \\\"\""s${sep}@${var}@${sep}${val}${sep}g"\"\\\" \ >> ${BT_CONFIGSED} done [ $# -gt 0 ] && ${BT_OUTPUT} } bt_generate_configh() { local var bt_msg "generating C include header" rm -f ${BT_CONFIGH} echo "/* File generated by buildtool */" > ${BT_CONFIGH} echo >> ${BT_CONFIGH} for var in ${Defines_Quoted_List}; do var=$(echo ${var} | sed -e 's|=\(.*\)| \"\1\"|g') var=$(echo ${var} | tr '¬' ' ') echo "#define ${var}" >> ${BT_CONFIGH} done for var in ${Defines_Unquoted_List}; do var=$(echo ${var} | tr '=¬' ' ') echo "#define ${var}" >> ${BT_CONFIGH} done } bt_generate_configenv() { local val var bt_msg "generating configuration environment" rm -f ${BT_CONFIGENV} echo "# File generated by buildtool" > ${BT_CONFIGENV} echo >> ${BT_CONFIGENV} for var in ${Subst_List}; do eval val=\"\$${var}\" echo "${var}=\"${val}\"" >> ${BT_CONFIGENV} done } bt_generate_logicenv() { local t bt_msg "generating package dependent build logic" rm -f ${BT_LOGICENV} cat >${BT_LOGICENV} </dev/null 2>&1 || true } EOF [ ${BT_FEATURE_DOC} = yes ] && cat >>${BT_LOGICENV} <&2 shift while [ $# -gt 0 ]; do echo " $1" 1>&2 shift done } bt_err() { echo "bt_config: *** STOP ***" 1>&2 while [ $# -gt 0 ]; do echo "$1" 1>&2 btcmn_log_msg "ERROR: $1" shift done exit 1 } # -------------------------------------------------------------------- # Shell-list management # -------------------------------------------------------------------- bt_list_contains() { local listname=$1 item="$2" local i items eval items=\"\$${listname}\" for i in ${items}; do [ ${i} = ${item} ] && return 0 done return 1 } # -------------------------------------------------------------------- # Language control # -------------------------------------------------------------------- bt_language_select() { local lang lang=$(echo $1 | swcase -ld) btcmn_log_msg "LANGUAGE SELECT: ${lang}" Language="${lang}" } # XXX: Remove bt_language_is_supported() { local listname listname=${1}_languages if ! bt_list_contains "${listname}" "${Language}"; then bt_warn "$1 does not support the selected \`${Language}' language" return 1 fi return 0 } # -------------------------------------------------------------------- # Features # -------------------------------------------------------------------- Features= bt_feature() { local val Features+=$1 eval val=\"\${BT_FEATURE_$1}\" if [ -z "${val}" ]; then eval BT_FEATURE_$1=\'$2\' fi eval BT_FEATURECMT_$1=\'$3\' bt_subst BT_FEATURE_$1 } bt_feature_list() { local cmt f val for f in $(echo ${Features} | tr ' ' '\n' | sort); do eval val=\"\${BT_FEATURE_${f}}\" eval cmt=\"\${BT_FEATURECMT_${f}}\" echo " ${f} - Current value: \`${val}'." 1>&2 echo " ${cmt}" 1>&2 done } bt_feature_parse() { local name val name=$(echo $1 | cut -d '=' -f 1 | swcase -ud) val=$(echo $1 | cut -d '=' -f 2) if ! bt_list_contains Features ${name}; then bt_warn "unknown feature ${name}" return fi [ -z "${val}" ] && val=yes eval BT_FEATURE_${name}=\"${val}\" } # -------------------------------------------------------------------- # Directories # -------------------------------------------------------------------- Dirs= bt_dir() { local val Dirs+=$1 eval val=\"\${BT_DIR_${1}}\" if [ -z "${val}" ]; then eval BT_DIR_$1=\'$2\' fi eval BT_DIRCMT_$1=\'$3\' bt_subst BT_DIR_$1 } bt_dir_list() { local cmt d val for d in $(echo ${Dirs} | tr ' ' '\n' | sort); do eval val=\"\${BT_DIR_${d}}\" eval cmt=\"\${BT_DIRCMT_${d}}\" echo " ${d} - Current value: \`${val}'." 1>&2 echo " ${cmt}" 1>&2 done } bt_dir_parse() { local name val name=$(echo $1 | cut -d '=' -f 1 | swcase -ud) val=$(echo $1 | cut -d '=' -f 2) eval BT_DIR_${name}=\"${val}\" } # Local Variables: *** # mode: shell-script *** # End: *** # vim: syntax=sh