tbs - a tcl/tk build system

TBS, by Johann Oberdorfer, is a shell script, which can be fine-tuned for individual platforms in order to compile a tclsh, wish and kbskit executable. This script is especially helpful when trying to compile with xlC under AIX - a platform, which isn't supported quite well these days.

Usage

  • Copy the script to an empty directory,
  • chmod +x tbs0.2.ksh
  • download required source packages (gzipped tar balls), and copy them into the source directory, inspect the script, to see, what's required,
  • run the script, e.g. like: tbs0.2.ksh make tkit
  • once, the build process has finished successfully execute: . tbs0.2.ksh setenv to extend the PATH var' accordingly

Implementation

#!/usr/bin/ksh
# tbs0.2.ksh ---
#       ######## ######   #####
#          #    #     # #     #
#          #    #     # #
#          #    ######   #####
#          #    #     #       #
#          #    #     # #     #
#          #    ######   #####    A tcl/tk build system.
# -------------------------------------------------------------------------
# Purpose:
#   Support shell script for building tcl/tk from source code.
#   Compile step by step from source, allowing to inspect the status
#   after compilation for each individual package.
#   Allows to configure each operating system (abnormalities)
#   separately.
#
# Licence:
#   Same as tcl/tk, feel free to use.
#   2004 (c) Johann Oberdorfer, [email protected]
# -------------------------------------------------------------------------
# Revision Change History:
# Sept.2004:  Johann Oberdorfer, V0.1: Initial Release
# Nov. 2008:         -*-       , V0.2: code improved and adopted to be used
#                                in parallel with kbs.tcl and as a fallback
#                                solution in case kbs.tcl don't work out
#                                of the box ...
# -------------------------------------------------------------------------
# rgb: D6/DD/E5 sidebar / #788c9c / #D6DDff / EC/F3/FE listbox
# set -x


print_usage () {

cat << EOF
  ---------------------------------------------
  Tcl Build Shell - compile tcl/tk and various
                    essential support packages.
  ---------------------------------------------
  You might need to adopt this file to fit your environment.

  Usage: `basename \$0` cmd option

    cmd: \
      source, configure, make, install, clean,
      setenv ... allows to propagate required settings
                 into the current shell (terminal window),
                 the callup sequence typically is:
                 . `basename \$0` setenv

    option:
      - core distribution:
          tcl, tk, tile, dict, tclhtml, tcloo,
          tkshared
 
      - support packages:
          sqlite, tktable, treectrl, thread,
          oratcl, odbc, metakit, vlerq, kbskit,
          blt, tkhtml, zlib

      - pure tcl/tk packages:
          bwidget, tablelist, tcllib, tklib

      - various:
       nedit

       tcore ... building tcl/tk core all in one go
       tkit  ... building kit all in one go
       docu  ... copy varioaus documentations


   Note: Source packages need to be available as *.tgz
         (gzipped tarballs) in the sources sub-directory:
         
         If a package is missing or can not be detected in the
         source tree, you might need to check it out from cvs
         manually.

EOF
}

# verify cmd line arguments

# to-do: not implemented right now!
cmd=""
mode=""

if [ -z "$1" ]; then

  print_usage
  echo "  *** Function argument is missing."
  echo "  --> Please specify your prefered option!\n"
  exit 1

else
  cmd=$1

  if [[ ! ( "$cmd" = "source"    ||
            "$cmd" = "configure" ||
            "$cmd" = "make"    ||
            "$cmd" = "install" ||
            "$cmd" = "clean"   ||
            "$cmd" = "setenv" ) ]]
  then
    echo "Option string $cmd is invalid!"
    print_usage
    exit 1
  fi

  if [ "$cmd" = "setenv" ]; then
    mode="setenv"
  else
    # 2nd argument must be present:

    if [ -z "$2" ]; then
      print_usage
      echo "  *** Function argument is missing."
      echo "  --> Please specify your prefered option!\n"
    else
      mode=$2
    fi
  fi
  
fi

# package reference list to handle version numbers

# --- C O N F I G U R A T I O N   S E C T I O N ---

# toggle version
# export VER=8.4.7
# export VER_STR="84"

export VER=8.5
export VER_STR="85"

# using PLATFORM as variable gives a different result on darwin
# (native scrollbars and buttons are used by default)
export THIS_PLATFORM=`uname`

case ${THIS_PLATFORM} in
  "Darwin")

     export CC=gcc
     export CXX=g++
     export ARFLAGS=
     export STRIPFLAGS=

     export ENABLE_64B=
     export SHARED_OPT="--disable-shared"
     export THREAD_OPT="--enable-threads"

     export ORACLE_HOME=""

     KBSDIR=${HOME}/d/t/kbs

     export BUILD_DIR=${KBSDIR}/darwin${VER_STR}
     export SOURCE_DIR=${KBSDIR}/sources

     # make sure, directory exists:
     if [ ! -d ${BUILD_DIR} ]; then
       cd ${KBSDIR}
       mkdir -p darwin${VER_STR}
       cd -
     fi

   ;;

   "AIX")
     # AIX:
     # xlC

     # after a lot of core dump's and "cannot load (share) *.so"
     # I was successfull with the following settings -heureka-!

     export CC=xlC
     export CXX=xlC
     export CPPFLAGS=-q64
     export ARFLAGS=-X64
     export STRIPFLAGS=-X64

     export ENABLE_64B="--enable-64bit"
     export SHARED_OPT="--disable-shared"
     export THREAD_OPT="--enable-threads"

     # ---------------------------------------------
     export ORACLE_HOME=/oracle/product/10.2.0/rte_1
     # ---------------------------------------------

     export LDFLAGS=-lm

     # on AIX Makefile needs to specify math lib
     # export LANG=en_US
     # tried as well those opt's (edited the Makefile directly):
     # CFLAGS = $(CFLAGS_OPTIMIZE) -g -lm -q32 -qlonglong -qnamemangling=v4

     KBSDIR=${HOME}/t/kbs

     export BUILD_DIR=${KBSDIR}/aix${VER_STR}
     export SOURCE_DIR=${KBSDIR}/sources

     # make sure, directory exists:
     if [ ! -d ${BUILD_DIR} ]; then
       cd ${KBSDIR}
       mkdir -p aix${VER_STR}
       cd -
     fi
   ;;

   "MINGW32_NT-5.2")

     export CC=gcc
     export CXX=g++
     export ARFLAGS=
     export STRIPFLAGS=

     export ENABLE_64B=
     export SHARED_OPT="--disable-shared"
     export THREAD_OPT="--enable-threads"

     export ORACLE_HOME="C:\oracle\product\10.2.0\client_1"

     KBSDIR=${HOME}/kbs

     export BUILD_DIR=${KBSDIR}/win${VER_STR}
     export SOURCE_DIR=${KBSDIR}/sources

     # make sure, directory exists:
     if [ ! -d ${BUILD_DIR} ]; then
       cd ${KBSDIR}
       mkdir -p darwin${VER_STR}
       cd -
     fi
   ;;

   *)
    echo "Unknown operating-system: ${THIS_PLATFORM} - exit."
    exit 0
   ;;
esac


export PATH=${BUILD_DIR}/bin:${PATH}


# -------------------------------------------------------------------------
# -------------------------------------------------------------------------

# argument processing...
print_version () {

  case ${VER_STR} in
  "84")

cat << EOF
                           #####          #
    #####   ####   #      #     #         #    #
      #    #    #  #      #     #         #    #
      #    #       #       #####          #    #
      #    #       #      #     #   ###   #######
      #    #    #  #      #     #   ###        #
      #     ####   ######  #####    ###        #
EOF

  ;;

  "85")

cat << EOF
                           #####          ######
    #####   ####   #      #     #         #
      #    #    #  #      #     #         #
      #    #       #       #####          ######
      #    #       #      #     #   ###        #
      #    #    #  #      #     #   ###        #
      #     ####   ######  #####    ###   ######
EOF

  ;;

  *)
    echo "Unknown option given for ${VER_STR}!"
  ;;
  esac
}


print_current_settings () {

cat << EOF
    Current settings are:

      Current Operating system ......... $THIS_PLATFORM
      Tcl/Tk version to be compiled .... $VER

    Compiler Options (supported by configure):

      CC ........... $CC
      CXX .......... $CXX
      CPPFLAGS ..... $CPPFLAGS
      ARFLAGS ...... $ARFLAGS
      STRIPFLAGS ... $STRIPFLAGS

    Other options (internal usage):

      VER_STR ...... $VER_STR
      ENABLE_64B ... $ENABLE_64B
      SHARED_OPT ... $SHARED_OPT
      BUILD_DIR .... $BUILD_DIR

EOF
}


# package name and source dir must be exactly the same!

getSourceAndCreatePkgDir () {
  pkgName=$1
  
  # solve a problem with NFS(-cache) ?
  ls ${BUILD_DIR}/${pkgName}
  
  if [ -d ${BUILD_DIR}/${pkgName} ]; then

    echo "  Directory ${BUILD_DIR}/${pkgName} already exists!"
    echo "  Delete manually to force re-compilation!"
    echo ""
    return 1

  else
    echo "Extracting source package..."
  
    if [ ! -d ${SOURCE_DIR}/${pkgName} ]; then
      cd ${SOURCE_DIR}
      # todo: check out current sources from cvs!
      gzip -dc "${pkgName}.tgz" | tar xvf -
    fi

    cd ${BUILD_DIR}
    mkdir -p ${pkgName}
  fi
  
  return 0
}


make_tcl () {
  pkgName=$1
  pkgType=$2
  echo "Compiling: ${pkgName}..."

  if [ ! -z "$pkgType" ]; then
    shared_opt="--enable-shared"
  else
    shared_opt=${SHARED_OPT}
  fi

  getSourceAndCreatePkgDir ${pkgName}

  if [ -z "$pkgType" ]; then
    # package compilation already done ?
    if [ ${?} = 1 ]; then return; fi
  fi

  cd ${BUILD_DIR}/${pkgName}

  # make distclean
  # ?? export LIBPATH=${BUILD_DIR}tcl8.5.0/unix
  # AIX: without "--enable-64bit" produced executable failed !

  if [[ "${THIS_PLATFORM}" = "AIX" ]]; then
    export LIBS="${LIBS} -lm"
  fi

  if [ ! -z "$pkgType" ]; then make clean; fi

  ${SOURCE_DIR}/${pkgName}/unix/configure \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     ${THREAD_OPT} \
     ${ENABLE_64B} \
     ${shared_opt}

  make
  make install

  # establish link:

  cd ${BUILD_DIR}/bin
  if [ ! -f tclsh ]; then
  
    case ${VER_STR} in
      "84") ln -s tclsh8.4 tclsh ;;
      "85") ln -s tclsh8.5 tclsh ;;
         *) echo "No Link created!"
            echo " -> Pls. check script for correct version handling!" ;;
    esac
  fi

  # cleanup of unused directories...
  # rm -rf ${BUILD_DIR}/man
  # rm -rf ${BUILD_DIR}/share

  echo "Done."
}


make_tk () {
  cfile=$1
  pkgName=$1
  pkgType=$2
  echo "Compiling: ${pkgName}..."
  
  if [ ! -z "$pkgType" ]; then
    shared_opt="--enable-shared"
  else
    shared_opt=${SHARED_OPT}
  fi

  getSourceAndCreatePkgDir ${pkgName}

  if [ -z "$pkgType" ]; then
    # package compilation already done ?
    if [ ${?} = 1 ]; then return; fi
  fi

  cd ${BUILD_DIR}/${pkgName}

  if [ ! -z "$pkgType" ]; then make clean; fi

  ${SOURCE_DIR}/${pkgName}/unix/configure \
     --with-tcl=${BUILD_DIR}/tcl${VER} \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     ${THREAD_OPT} \
     ${ENABLE_64B} \
     ${shared_opt}


  make
  make install

  cd ${BUILD_DIR}/bin
  if [ ! -f wish ]; then

    case ${VER_STR} in
      "84") ln -s wish8.4 wish ;;
      "85") ln -s wish8.5 wish ;;
         *) echo "No Link created!"
            echo " -> Pls. check script for correct version handling!" ;;
    esac
  fi

  # cleanup of unused directories...
  # rm -rf ${BUILD_DIR}/man
  # rm -rf ${BUILD_DIR}/share

  echo "Done."
}


# should work out for most of the standard TEA packages
# pkgType allows to control the type of the library, which is
# going to be compiled: shared or static library

make_generic () {
  pkgName=$1
  pkgType=$2
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # try to find configure
  configureCmd=${SOURCE_DIR}/${pkgName}/configure

  if [ ! -f ${configureCmd} ]; then
    configureCmd=${SOURCE_DIR}/${pkgName}/unix/configure
  fi

  if [ ! -z "$pkgType" ]; then
    shared_opt=${SHARED_OPT}
  fi

  # make distclean
  ${configureCmd} \
     --with-tcl=${BUILD_DIR}/tcl${VER} \
     --with-tk=${BUILD_DIR}/tk${VER} \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     ${ENABLE_64B} \
     ${shared_opt}

  make
  make install
  echo "Done."
}


make_oratcl () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # ---------------------------------------------
  export ORACLE_HOME=/oracle/product/10.2.0/rte_1
  # ---------------------------------------------

  # make distclean
  ${SOURCE_DIR}/${pkgName}/configure \
      --with-oracle-directory=${ORACLE_HOME} \
      --with-oracle-version=9 \
      --with-tcl=${BUILD_DIR}/tcl${VER} \
      --prefix=${BUILD_DIR} \
      --exec-prefix=${BUILD_DIR} \
      ${ENABLE_64B}

  make
  make install

  echo "Done."
}


install_package () {
  pkgName=$1
  echo "Installing: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  rm -rf ${BUILD_DIR}/lib/${pkgName}

  cd ${SOURCE_DIR}
  cp -r ${pkgName} ${BUILD_DIR}/lib

  echo "Done."
}


copy_source () {
  pkgName=$1
  echo "Copying source of: ${pkgName} ..."

  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  # if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}
  rm -rf ${pkgName}

  cd ${SOURCE_DIR}
  # cp -rf ${pkgName} ${BUILD_DIR}/${pkgName}

  if [ -d ${BUILD_DIR}/$subDir ]; then
    cp -r ${pkgName} ${BUILD_DIR}/${subDir}
  else
    cp -r ${pkgName} ${BUILD_DIR}
  fi

  echo "Done."
}


build_kit () {
  pkgName=$1
  kitName=$2

  # PackageLinks - e.g.: "sqlite3.6.10 treectrl2.2.7 tktable2.10"
  # PackageNames - e.g.: "sqlite3 treectrl Tktable"

  echo "Creating kit: ${kitName} ..."

  # 1.) create vfs directory:
  # -------------------------
  kitVfs="${kitName}.vfs"

  cd ${BUILD_DIR}
  rm -rf ${kitVfs}
  mkdir -p ${kitVfs}

  # 2.) copy app' sources
  # ---------------------
  cp -r ${pkgName} ${kitVfs}
  
  # 3.) collect packages
  # --------------------
  cd ${BUILD_DIR}/${kitVfs}

  rm -rf lib
  mkdir -p lib
  cd ${BUILD_DIR}/${kitVfs}/lib

  for pName in `echo ${PackageLinks}`
    do
    echo "Creating link for package: ${pName}..."
    if [ ! -d ${pName} ]; then
      ln -s ${BUILD_DIR}/lib/${pName} ${pName}
    fi
  done

  # 4.) create "main.tcl"
  # ----------------------
  cd ${BUILD_DIR}/${kitVfs}

  if [ -f main.tcl ]; then
    echo "The file ${BUILD_DIR}/${kitName}/main.tcl already exists!"
    echo "Delete manually and try again!"
    exit 0

  else

# --- main.tcl ---
# ----------------

cat << EOF > main.tcl
#!/usr/bin/env tclkit
# startup
if {[catch {
  package require starkit
  if {[starkit::startup] eq "sourced"} return
}]} {
  namespace eval ::starkit { variable topdir [file dirname [info script]] }
  set auto_path [linsert \$auto_path 0 [file join $::starkit::topdir lib]]
}

# used packages
EOF

  # not required within starkit 
  # echo "lappend auto_path [file join \$topdir lib]"  >> main.tcl

  for pName in `echo ${PackageNames}`
    do
    echo "Establishing \"package require\" for: ${pName}..."
    echo "package require ${pName}" >> main.tcl
  done

  echo ""  >> main.tcl
  echo "# start application"  >> main.tcl
  echo "source \$::starkit::topdir/${pkgName}/${kitName}.tcl" >> main.tcl

  # ----------------
  fi

  # step 2: wrap the application!
  # -----------------------------

  cd ${BUILD_DIR}

  KITBIN=${BUILD_DIR}/bin/kbskit8.5-gui
  SDXKIT=${BUILD_DIR}/bin/sdx.kit

  # copy runtime
  KITRUNTIME=${BUILD_DIR}/${kitName}
  rm -rf ${KITRUNTIME}
  cp ${KITBIN} ${KITRUNTIME}

  ${KITBIN} ${SDXKIT} wrap ${kitName} -runtime ${KITRUNTIME}
  
  cd ${BUILD_DIR}/bin
  if [ -f tclkit ]; then rm -f tclkit; fi
  
  case ${VER_STR} in
    "85") ln -s kbskit8.5-gui tclkit ;;
    "86") ln -s kbskit8.6-gui tclkit ;;
       *) echo "No Link created!"
          echo " -> Pls. check script for correct version handling!" ;;
  esac

  echo "Done."
}


make_tcltklib () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # make distclean
  ${SOURCE_DIR}/${pkgName}/configure \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \

  make install
  make html-doc
  echo "Done."
}


patch () {
  fileName=$1
  lineNum=$2
  currStr=$3
  newStr=$4
  
  # lineNum currently not used
  if [ ! -f $fileName ]; then return; fi
  cp $fileName ${fileName}.orig
  sed < ${fileName}.orig "s/${currStr}/${newStr}/g" > $fileName
}


make_zlib () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${SOURCE_DIR}
  cp -r ${pkgName} ${BUILD_DIR}

  cd ${BUILD_DIR}/${pkgName}

  # make distclean
  # --shared

  if [[ "${THIS_PLATFORM}" = "AIX" ]]; then
    CC="${CC} -q64"
    # -doesn't work- AR="${AR} -X64"
  fi

  ./configure \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR}

  # patch the makefile!
  patch ${BUILD_DIR}/${pkgName}/Makefile 36 "AR=ar rc" "AR=ar -X64 rc"

  make
  make install
  echo "Done."
}


make_tkhtml () {
  cfile=$1
  echo "--- Compiling: ${cfile}..."

  if [ -d ${BUILD_DIR}/htmlwidget ]; then
    echo "Directory already exists -> delete manually to re-compile!"
    return
  fi

  cd ${BUILD_DIR}
  gzip -dc ../src/common/${cfile} | tar xvf -

  cd ${BUILD_DIR}/htmlwidget
  mkdir _build
  cd _build

  # make distclean
  ../configure \
     --with-tcl=${BUILD_DIR}/tcl${VER}/unix \
     --with-tk=${BUILD_DIR}/tk${VER}/unix \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR}

  make
  make install
  echo "Done."
}



make_BLT () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  # if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # ??? doesn't compile under tcl8.5 ???

  make distclean
  ${SOURCE_DIR}/${pkgName}/configure
     --with-tclincls=${SOURCE_DIR}/tcl${VER}/generic \
     --with-tkincls=${SOURCE_DIR}/tk${VER}/generic \
     --with-tcllibs=${BUILD_DIR}/lib \
     --with-tklibs=${BUILD_DIR}/lib \
     \
     --includedir=${BUILD_DIR}/include \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR}
     --enable-shared

     # ${ENABLE_64B}
     # ${SHARED_OPT}

  make
  make install
  echo "Done."
}


make_metakit () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  # if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # by default, a shared library is build!
  # --enable-shared

  export CXX=xlC

  make distclean
  ${SOURCE_DIR}/${pkgName}/unix/configure \
     --with-tcl=${BUILD_DIR}/include \
     --includedir=${BUILD_DIR}/include \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     ${THREAD_OPT}
     ${ENABLE_64B}

  # for AIX: manually edit Makefile such as:
  # some editing in source files is required:
  # - comment out the following code block in: src/header.h:
  #   
  # /* hans: -disabled-
  # #if SIZEOF_LONG == 8
  # typedef int t4_i32; // longs are 64b, so int must be 32b
  # #else 
  # typedef long t4_i32; // longs aren't 64b, so they are 32b
  # #endif 
  # */
  # tcl/mk4tcl.cpp:
  # tweaked the code, see source:
  #   #ifdef TCL_WIDE_INT_TYPE
  #     case 'L':
  # //      Tcl_SetWideIntObj(obj_, ((c4_LongProp &)prop_)(row_));
  #       Tcl_SetWideIntObj(obj_, ((c4_IntProp &)prop_)(row_));
  # 
  #       break;
  # #endif 
  # .. and more in tcl/mk4too.cpp:
  #   // hans:        wtmp = wideVal - ((c4_LongProp &)prop)(view[row]);
  #         wtmp = wideVal - ((c4_IntProp &)prop)(view[row]);
  #
  # Makefile:
  # - overcome missing objects, such as __PureVirtualCalled with:
  #   (remark: it took me very long, to find out, that libC is required !)
  #     LINK_SPECIAL_FLAGS        = -lpthread -lc -lC
  # instead of: "g++ -shared"
  # - and use ldAix to produce a valid (loadable) shareable library:
  #     SHLIB_LD = $(BUILD_DIR)/tcl8.5.5/unix/ldAix \
  #                    /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry -b64
  # !!! required !!!
  # SHLIB_LD = $(BUILD_DIR)/lib/tcl8.5/ldAix \
  #        /bin/ld -bhalt:4 -bM:SRE -bE:lib.exp -H512 -T512 -bnoentry -b64
  # chmod +x $(BUILD_DIR)/lib/tcl8.5/ld
  #
  # - and remove -fPIC from
  #     CXX_FLAGS = -q64 -g -Dq4_MULTI -DTCL_THREADS -DUSE_TCL_STUBS \
  #                    -I$(srcdir)/../include
  # ar needs to be changed to: ar -X64
  #

  make
  make install-tcl

  echo "Done."
}


make_kbskit () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  # fix the problem: ./sources/tcl8.5/unix/tclUnixPort.h not found...
  # ... include file "tclInt.h" not found...

  CC="${CC} -I${SOURCE_DIR}/tcl${VER}/unix"
  CC="${CC} -I${SOURCE_DIR}/tcl${VER}/generic"


  if [[ "${THIS_PLATFORM}" = "AIX" ]]; then
    cp ${SOURCE_DIR}/tcl${VER}/generic/tclInt.h ${BUILD_DIR}/include
    cp ${SOURCE_DIR}/tcl${VER}/generic/tclPort.h ${BUILD_DIR}/include
    cp ${SOURCE_DIR}/tcl${VER}/generic/tclIntDecls.h ${BUILD_DIR}/include
    cp ${SOURCE_DIR}/tcl${VER}/generic/tclIntPlatDecls.h ${BUILD_DIR}/include
    cp ${SOURCE_DIR}/tcl${VER}/unix/tclUnixPort.h ${BUILD_DIR}/include
  fi


  # not required so far:
  # --with-tclinclude=${BUILD_DIR}/include \

  # required:
  export LDFLAGS="${LDFLAGS} -L/${BUILD_DIR}/lib/vfs1.4 -lvfs1.4"
  export LDFLAGS="${LDFLAGS} -L/${BUILD_DIR}/lib/vqtcl4.1 -lvqtcl4.1"

  cd ${BUILD_DIR}/${pkgName}

  ${SOURCE_DIR}/${pkgName}/configure \
     --with-tcl=${BUILD_DIR}/lib \
     --with-tk=${BUILD_DIR}/lib \
     \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     ${THREAD_OPT} \
     ${SHARED_OPT} \
     ${ENABLE_64B}

  # encodings, messages

  if [[ "${THIS_PLATFORM}" = "AIX" ]]; then
    MYKITOPTS="-e"
  else 
    MYKITOPTS="-e -m"
  fi

  if [ "$_{TZDATA}" = "--enable-tzdata" ]; then
    MYKITOPTS="${MYKITOPTS} -z"
  fi

  MYLIBS="-L${BUILD_DIR}/lib -ltcl8.5 -ltk8.5 -lz"
  MYLIBS="${MYLIBS} -L${BUILD_DIR}/lib/vfs1.4 -lvfs1.4"
  MYLIBS="${MYLIBS} -L${BUILD_DIR}/lib/vqtcl4.1 -lvqtcl4.1"

  if [ ${THREAD_OPT} = "--enable-threads" ]
  then
    MYLIBS="${MYLIBS} -L${BUILD_DIR}/lib/thread2.6.5 -lthread2.6.5"
    # MYKITOPTS="${MYKITOPTS} -t"
  fi

  # Makefile takes the environment variable MYLIBS into account!
  make ${MYKITOPTS} "MYLIBS=${MYLIBS}"

  # not requ. so far:
  # edit makefile in order to find appInit.o:
  # $(KBSKIT_CLI): $(PKG_OBJECTS) kitInit.o $(CLI_OBJ) setupvfs.tcl
  #        ${CC} ${CFLAGS} ${LDFLAGS} $(PKG_OBJECTS) kitInit.o \
  #        ${TCL_BIN_DIR}/tclAppInit.o\
  #        $(MYLIBS) -o $@ $(TCL_LIBS) 
  #        cp $@ my$@
  #        ./my$@ -init- setupvfs.tcl $(KITOPTS) $@ cli

  make install

  echo "Done."
}


# does not work for now!
make_kbskit03 () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  # fix the problem: ./sources/tcl8.5/unix/tclUnixPort.h not found...
  CC="${CC} -I${SOURCE_DIR}/tcl${VER}/unix"
  CC="${CC} -I${SOURCE_DIR}/tcl${VER}/generic"

  cd ${BUILD_DIR}/${pkgName}

  ${SOURCE_DIR}/${pkgName}/configure \
     --with-tcl=${BUILD_DIR}/lib \
     --with-tk=${BUILD_DIR}/lib \
     \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     ${THREAD_OPT} \
     ${SHARED_OPT} \
     ${ENABLE_64B}

  MYCLI="-L${BUILD_DIR}/lib -ltcl8.5 -ltk8.5 -lz"
  MYCLI="${MYCLI} -L${BUILD_DIR}/lib/vfs1.4 -lvfs1.4"
  MYCLI="-L${BUILD_DIR}/lib -ltk8.5"

  MYVQ="-L${BUILD_DIR}/lib/vqtcl4.1 -lvqtcl4.1"
  MYMK="${BUILD_DIR}/lib/mk4tclstatic2.4.9.7/Mk4tcl.a"

  if [ ${THREAD_OPT} = "--enable-threads" ]; then
    MYKITVQ="-L${BUILD_DIR}/lib/thread2.6.5 -lthread2.6.5"
    MYKITMK="itcl3.4"
  else
    MYKITVQ=""
    MYKITMK="itcl3.4"
  fi

  if [ "${THIS_PLATFORM}" = "Linux" ]; then
    MYXFT="-lXft"
  else
    MYXFT=""
  fi

  # Makefile takes the specified environment variable as into account!
  MYKITBI=""

  # "vq-cli vq-dyn vq-gui mk-cli"
  for my in `echo "vq-cli"`
  do
    MY="${MYCLI} ${MYGUI} ${MYXFT}"
    MY="${MY} ${MYVQ} ${MYKITVQ} ${MYMK}"
    MY="${MY} ${MYKITMK} ${MYKITBI}"
  
# ?????
# doesn't work ????
# !!! need some fine tuning !!!  
    make all-${my} -e "MYCLI=${MY}"
  done

  make install

  echo "Done."
}


make_unixodbc () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # AIX extra xlibs...
  # export LD_LIBRARY_PATH=/usr/lpp/X11/lib/R6:${LD_LIBRARY_PATH}

  # tested, but without success:
  # export LIBDIR=/usr/lpp/X11/lib/R6:${LIBDIR}
  # export USRLIBDIR=/usr/lpp/X11/lib/R6:${USRLIBDIR}

  # --without-qt-libraries
  # --with-extra-xlibs=/usr/lpp/X11/include/X11
  # --with-extra-includes=${BUILD_DIR}/tk${VER}/xlib/X11
  # --libdir=/usr/lpp/X11/lib/R6
  #  --x-includes=/usr/lpp/X11/include/X11 \
  #  --libdir=/usr/lpp/X11/lib/R6
  # updated version 2.2.11 gave another configure advise
  #   to use "--enable-gui=no", which finally worked out well!

  # required on AIX as well:
  if [[ "${THIS_PLATFORM}" = "AIX" ]]; then
    export AR_FLAGS="-X64 cru"
  fi

  # make distclean
  ${SOURCE_DIR}/${pkgName}/configure \
     --with-tcl=${BUILD_DIR}/tcl${VER} \
     --with-tk=${BUILD_DIR}/tk${VER} \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     --enable-gui=no \
     ${SHARED_OPT} \
     ${ENABLE_64B}

  make
  make install

  echo "Please Note:"
  echo "  \"make install\" finally raises an error,"
  echo "  but seems to be O.K. for the created lib's!"
  echo "Done."
}


make_freetds () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  if [[ "${THIS_PLATFORM}" = "AIX" ]]; then

    # required on AIX as well:
    export AR_FLAGS="-X64 cru"
    export CFLAGS=-q64

    # libtool requires this for AIX:
    export CC="xlC -q64"
    export NM="/usr/bin/nm -B -X64"
  fi

  # make distclean
  ${SOURCE_DIR}/${pkgName}/configure \
     --with-tcl=${BUILD_DIR}/tcl${VER} \
     --with-tk=${BUILD_DIR}/tk${VER} \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     --with-unixodbc=${SOURCE_DIR}/unixODBC-2.2.11 \
     --with-tdsver=8.0 \
     ${ENABLE_64B}

  make
  make install

  echo "Error at one of the last steps, for the lib's is seems, we are O.K.!"
  echo "Done."
}


make_sqsh () {
  pkgName=$1
  echo "Compiling: ${pkgName} ..."
  getSourceAndCreatePkgDir ${pkgName}

  # package compilation already done
  if [ ${?} = 1 ]; then return; fi

  cd ${BUILD_DIR}/${pkgName}

  # dependencies:
  #  required libs are: -lblk -lcs -lct -ltcl -lcomn -lintl
  export SYBASE=${SOURCE_DIR}/unixODBC-2.2.11
  export SYBASE_LIBDIR=${SOURCE_DIR}/lib
  # export SYBASE_LIBS=

  export CFLAGS="-q64 -I${SOURCE_DIR}/freetds-0.62.1/include "
  export CFLAGS="${CFLAGS} -DBLK_VERSION_150=150 -DBLK_VERSION_125=125 -DBLK_VERSION_120=120"
  export CFLAGS="${CFLAGS} -I${BUILD_DIR}/include"

  # although documented, this one is not recognized ?!:
  # (we need to manually edit the Makefile after configure)
  export LDFLAGS="-q64 -L/${BUILD_DIR}/lib -lct"
 
  # other valid options:  
  # --sysconfdir=DIR  read-only single-machine data in DIR [BUILD_DIR/etc]
  # --includedir=${BUILD_DIR}/include

  # -L$(BUILD_DIR)/lib -lct
  # -ldl -lodbc  -lsybdb -ltdsodbc -lodbcinst -liconv -lthread

  # sqsh depends on FREE-TDS !


  # make distclean
  ${SOURCE_DIR}/${pkgName}/configure \
     --with-tcl=${BUILD_DIR}/tcl${VER} \
     --with-tk=${BUILD_DIR}/tk${VER} \
     --prefix=${BUILD_DIR} \
     --exec-prefix=${BUILD_DIR} \
     --sysconfdir=${BUILD_DIR}/etc \
     ${ENABLE_64B}
     
  make
  
  # ld: 0711-317 ERROR: Undefined symbol: .ct_con_props, ...
  # *** mod's required in <install_dir>/src/Makefile
  #   SYBASE_LIBS   =  -lm -L$(BUILD_DIR)/lib -lct
  #   CC             = xlC -q64

  # to list objects in a library use e.g.:
  #  ar -X64 -v -t libct.a

  echo  ""
  echo "*** Linking failed! ***"
  echo "  > Modify  ${BUILD_DIR}/sqsh-2.1.5/src/Makefile"
  echo "  > according to description found *here* !"
  echo ""

  make install

  echo ""
  echo "sqsh Configuration note:"
  echo "  > make sure etc directory in $BUILD_DIR/etc"
  echo "  > and all relevant configuration files are available !"
  echo ""

  echo "Done."
}


make_nedit () {
  cfile=$1
  echo "Compiling: ${cfile}..."

  if [ -d ${BUILD_DIR}/nedit-5.5 ]; then
    echo "Directory already exists -> delete manually to re-compile!"
    return
  fi

  cd ${BUILD_DIR}
  gzip -dc ../src${VER}/util/${cfile} | tar xvf -

  cd ${BUILD_DIR}/nedit-5.5

  make generic

  make install
  echo "Done."
}


# -------------------------------------------------------------------------
# here we go ...
# -------------------------------------------------------------------------

build_package () {
  pkg=$1

  case $pkg in

  "tcl")
    # core distribution:

    case ${VER_STR} in
      "84") make_tcl "tcl8.4.7"  ;;
      "85") make_tcl "tcl8.5" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;

  "tclshared")
  
    # AIX notes:
    # required to comile metakit
    # (which requires ldAIX in turn !)
    # note: obviousliy, when compiling with this option,
    # the makefile needs to be amended as following:
    #   LIBS                = -ldl  -lpthread -lc  -lbsd -lm

    case ${VER_STR} in
      "84") make_tcl "tcl8.4.7" "shared" ;;
      "85") make_tcl "tcl8.5"   "shared" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;


  "tk")
    case ${VER_STR} in
      "84") make_tk "tk8.4.7" ;;
      "85") make_tk "tk8.5" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;
    
  "tkshared")
    case ${VER_STR} in
      "84") make_tk "tk8.4.7" "shared" ;;
      "85") make_tk "tk8.5"   "shared" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;
    

  "tile")
    case ${VER_STR} in
      "84") make_generic "tile-0.8.2" ;;
      "85") echo "Tile is already part of the distribution!" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;

  "dict")
    case ${VER_STR} in
      "84") make_generic "tclDict8.5.2" ;;
      "85") echo "Dict is already part of the distribution!" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;

  "tclhtml")
    case ${VER_STR} in
      "84") copy_source "tcl8.4.7-html" ;;
      "85") copy_source "tcl8.5.5-html" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;

  "tcloo")
    case ${VER_STR} in
      "84") "tcloo requires at least a version >= 8.5!" ;;
      "85")  make_generic "tcloo-0.6" ;;
       "*") echo "Unknown Version - edit script!" ;;
    esac
    ;;

  # support packages:

  "tktable")  make_generic  "tktable2.10" ;;
  "treectrl") make_generic  "tktreectrl-2.2.7" ;;
  "sqlite")   make_generic  "sqlite3.6.10" ;;

  "oratcl")

    # needs to be customized:
    echo "Required environment var' for oracle"
    echo "ORACLE_HOME points to ${ORACLE_HOME}!"
    echo "--> Check, it this is still o.k."
  
    case ${THIS_PLATFORM} in
      "AIX") make_oratcl  "oratcl4.4" ;;
       "*") echo "Unknown platform - you need to edit the script!" ;;
    esac
    ;;

  # pure tcl/tk packages:

  "bwidget")   install_package "bwidget-1.8.0" ;;
  "tablelist") install_package "tablelist-4.10" 
  
    echo "  > Make sure to remove tablelist package from tklib!"
    echo "  > Might be out of date in the tklib distribution!"
    echo "  > Done."
               ;;

  "tcllib")    make_tcltklib  "tcllib-1.11" ;;
  "tklib")     make_tcltklib  "tklib0.5" ;;

  # various:

  "odbc")

     # odbc + free-TDS:
     # packages need to be compiled in this order:

     # 1.) (maybe not *really* required... ?!)
     make_unixodbc "unixODBC-2.2.11"

     # 2.) free TDS:
     # does compile, but object missing when linking:
     #   make_freetds  "freetds-stable0.8.2"

     make_freetds "freetds-0.62.1"
     
     # 3.) sqsh depends on FREE-TDS !
     make_sqsh "sqsh-2.1.5"
     ;;

  "metakit")
     case ${THIS_PLATFORM} in
      "AIX") 
             # the one which is under source is already modified
             # to cure comiler errors under AIX/xlC
             # metakit-2.4.9.7_mod_aix has been renamed to:
             metakit="metakit-2.4.9.7" ;;
          *) metakit="metakit-2.4.9.7" ;;
     esac
 
     # AIX notes:
     # metakit requires a dynamically build of tcl
     # where the ldAIX file is generated and can be referenced
     # within the metakit Makefile - the Makefile needs to be
     # edited by hand as described above!
 
     make_metakit ${metakit}
     ;;

  # utility programs

  "nedit") make_nedit "nedit-5.5-src"  ;;

  # trials:

  "blt")    
            echo "BLT: doesn't compile under tcl8.5 ?!"
            # make_BLT    "blt2.4z"
            ;;

  "tkhtml") make_tkhtml "tkhtml3-alpha-16" ;;

  # kit build
  # requires the following static libraries:

  "thread")   make_generic "thread-2.6.5" "static_build";;
  "vfs")      make_generic "vfs1.4"       "static_build";;
  "vlerq")    make_generic "vlerq-4.1"    "static_build" ;;
  "memchan")  make_generic "memchan-2.2.1" "static_build" ;;
  "zlib")     make_zlib    "zlib-1.2.3" ;;

  "vqtcl")    echo "Same effect as vlerq ?! - use vlerq instead!"
              # make_generic "vqtcl4.1"
              ;;
  "kbskit")   
              make_kbskit "kbskit-8.5" ;;
              # doesn't work so far:
              # make_kbskit03 "kbskit0.3" ;;

  "tksqlite") 
              copy_source "tksqlite0.5.6"
              cp ${SOURCE_DIR}/sdx.kit ${BUILD_DIR}/bin

              PackageLinks="sqlite3.6.10 treectrl2.2.7 tktable2.10"
              PackageNames="sqlite3 treectrl Tktable"
              
              build_kit "tksqlite0.5.6" "tksqlite"
  ;;

  "fm")
              # another test for a *kit executable !
              pkgName="fm.0.1"
              
              cd ${BUILD_DIR}
              rm -rf ${pkgName}
              mkdir -p ${pkgName}
              cp ${HOME}/d/t/FM.tcl ${BUILD_DIR}/${pkgName}/fm.tcl
 
              PackageLinks=""
              PackageNames=""

              build_kit "fm.0.1" "fm"
  ;;

  *)
     echo "Unknown Option!" ;;
  esac
}

# main command dispatcher
# -----------------------

case $mode in
  "setenv")

      # environment variables are set already,
      # so, there's nothing more to do!
      dummy=0
   ;;

   "tcore")
      corepackages="tcl tk sqlite tktable treectrl"
      corepackages="${corepackages} tcllib tklib tablelist bwidget"

      for pkg in `echo ${corepackages}`
      do
        build_package $pkg
      done
   ;;

   "tkit")
      # static build comes 1st + shared build required for kbskit:
      # remember: tk itself is a stub enabled dyn. loadable lib for tcl

      kitpackages="tcl tk memchan vfs vlerq zlib thread"
      kitpackages="${kitpackages} tclshared tkshared kbskit"

      for pkg in `echo ${kitpackages}`
      do
        build_package $pkg
      done
   ;;

   "docu")

      # note: the tcl/tk docu has been reassembled within
      # the tarball, to fit with our "standard" mechanism,
      # see copy_source as well

      doculist="tcl8.5.5-html sqlite-docs-3.5.9 metakit-2.4.9.7-html"
      for docu in `echo ${doculist}`
      do
        copy_source ${docu}
      done
   ;;      

   *)
      print_version
      print_current_settings

      build_package $mode
   ;;
esac


echo "Done."