#!/usr/bin/env bash #----------------------------------------------------------------------------- # script configure # purpose To generate a Makefile in a compilation directory (usually # starting as an empty directory apart from the source). # requires bash, gawk # author Phil Howard, #----------------------------------------------------------------------------- allargs=( "$@" ) tab=" " trap "echo Hangup 1>&2 ; exit 1" HUP trap "echo Interrupt 1>&2 ; exit 1" INT trap "echo Termination 1>&2 ; exit 1" TERM #----------------------------------------------------------------------------- # Define message functions. All messages go to stderr. #----------------------------------------------------------------------------- function dmsg { echo "DEBUG" "`exec date +%H:%M:%S`" "$@" 1>&2 } function msg { echo "`exec date +%H:%M:%S`" "$@" 1>&2 } function vmsg { [[ $1 -gt ${verbose} ]] && return shift echo "`exec date +%H:%M:%S`" "$@" 1>&2 } function emsg { echo "ERROR" "`exec date +%H:%M:%S`" "$@" 1>&2 } #----------------------------------------------------------------------------- # Define other general use functions. #----------------------------------------------------------------------------- function extension { echo "${1}" | gawk -F. '{print $(NF);}' } function noextension { echo "${1}" | gawk -F. '{if(NF>1){print substr($0,1,length($0)-length($(NF)-1));}else{print $0;}}' } function sortpath { tr / '\034' | sort "$@" | tr '\034' / } function oneof { local a local s s="${1}" shift for a in "$@"; do if [[ "${s}" = "${a}" ]]; then return 0 fi done return 1 } #----------------------------------------------------------------------------- # Initialize defaults before command line parsing. #----------------------------------------------------------------------------- verbose=0 #----------------------------------------------------------------------------- # If the --BUILDHEADER option is specified, then extract header contributions # Argument 1 is the name of the header file to append to. # Argument 2 is the identity of the pass. # Remaining arguments are source files to extract from. #----------------------------------------------------------------------------- # prefix # include includes for other headers # config configuration definitions # define structs, defines, value definitions # fmacro macro functions # inline inline functions # proto function prototypes # alias function aliases # suffix #----------------------------------------------------------------------------- hdropt="BUILDHEADER" hdrlist=( prefix include config define fmacro inline proto alias suffix ) if [[ "${1}" = "--${hdropt}" ]]; then shift hdrfile="${1}" shift rm -f "${hdrfile}" hdrdir=$( dirname "${hdrfile}" ) [[ -d "${hdrdir}" ]] || mkdir -p "${hdrdir}" for pass in "${hdrlist[@]}"; do export PASS=$( echo "${pass}" | tr 'a-z' 'A-Z' ) hdrdir=$( dirname "${hdrfile}" ) [[ -d "${hdrdir}" ]] || mkdir -p "${hdrdir}" || exit 1 for infile in "$@"; do gawk 'BEGIN{p=ENVIRON["PASS"];e="__" p "_";b=e "BEGIN__";e=e "END__";}{if($1==e){if(p=="PROTO"){printf ";\n\n";}else{printf "\n";};x=0;}else if($1==b){x=1;}else if(x){print $0;}}' <"${infile}" >>"${hdrfile}" done done exit 0 fi #----------------------------------------------------------------------------- # Set initial defaults which can be overridden by empty values. #----------------------------------------------------------------------------- std="gnu99" #----------------------------------------------------------------------------- # Parse command line for options. #----------------------------------------------------------------------------- while [[ $# -gt 0 ]]; do value=$( echo "${1}" | cut -d = -f 2 ) case "${1}" in ( --no-arlib | --noarlib ) noarlib=1 ;; ( --no-solib | --nosolib ) nosolib=1 ;; ( --no-strip | --nostrip ) nostrip=1 ;; ( --execdynamic | --exec-dynamic ) execdynamic=1 ;; ( --execstatic | --exec-static ) execstatic=1 ;; ( --hardalias ) hardalias=1 ;; ( --quiet | -q ) verbose=$[ $verbose - 1 ] ;; ( --verbose=* | -v=* ) verbose="${value}" ;; ( --verbose | -v ) verbose=$[ $verbose + 1 ] ;; ( --cp-verbose=* ) cp_verbose="${value}" ;; ( --cp-verbose ) cp_verbose=1 ;; ( --cc-verbose=* ) cc_verbose="${value}" ;; ( --cc-verbose ) cc_verbose=1 ;; ( --as-verbose=* ) as_verbose="${value}" ;; ( --as-verbose ) as_verbose=1 ;; ( --ld-verbose=* ) ld_verbose="${value}" ;; ( --ld-verbose ) ld_verbose=1 ;; ( --static-libgcc=* ) static_libgcc="${value}" ;; ( --static-libgcc ) static_libgcc=1 ;; ( --optimize=* ) optimize="${value}" ;; ( --optimize ) optimize=3 ;; ( --std=* ) std="${value}" ;; ( -O[0-9] ) optimize="${1:2:1}" ;; ( --warninline | --warn-inline ) warninline=1 ;; ( --remove-old ) removeold=1 ;; ( --cpreprocess | --cpp ) cpp=1 ;; ( --assembly | --asm ) asm=1 ;; ( --save-temps | --savetemps ) savetemps=1 ;; ( --source=* | -s=* ) source="${value}" ;; ( --package=* ) package="${value}" ;; ( --version=* ) version="${value}" ;; ( --prefix=* | -p=* ) prefix="${value}" ;; ( --bin-prefix=* ) binprefix="${value}" ;; ( --cgi-prefix=* ) cgiprefix="${value}" ;; ( --include-prefix=* ) includeprefix="${value}" ;; ( --lib-prefix=* ) libprefix="${value}" ;; ( --sbin-prefix=* ) sbinprefix="${value}" ;; ( --install-prefix=* ) installprefix="${value}" ;; ( --install-bin-prefix=* ) installbinprefix="${value}" ;; ( --install-cgi-prefix=* ) installcgiprefix="${value}" ;; ( --install-include-prefix=* ) installincludeprefix="${value}" ;; ( --install-lib-prefix=* ) installlibprefix="${value}" ;; ( --install-man-prefix=* ) installmanprefix="${value}" ;; ( --install-sbin-prefix=* ) installsbinprefix="${value}" ;; ( --make ) domake=1 ;; ( --make-install ) domakeinstall=1 ;; ( -* ) echo "Unknown option '${1}'" 1>&2 ;; ( * ) echo "Unknown argument '${1}'" 1>&2 ;; esac shift done #----------------------------------------------------------------------------- # Make sure at least one of the library classes is to be built. #----------------------------------------------------------------------------- if [[ -n "${noarlib}" && -n "${nosolib}" ]]; then emsg "Options '--no-arlib' and '--no-solib' cannot be used together" exit 1 fi #----------------------------------------------------------------------------- # If source is not specified, derive it from this script path, if known. #----------------------------------------------------------------------------- scriptfile="${0}" if [[ -z "${source}" ]]; then source=$( dirname "${scriptfile}" ) if [[ -z "${source}" || "${source}" = "${scriptfile}" ]]; then emsg "Unable to determine source directory from script name" emsg "Use the --source= option to specify the source directory" exit 1 fi if [[ "${source}" = "." && "${scriptfile:0:2}" != "./" ]]; then emsg "Unable to determine source directory from script name" emsg "Use the --source= option to specify the source directory" exit 1 fi fi canonsource=$( cd "${source}" && exec pwd ) #----------------------------------------------------------------------------- # If the current directory is the source directory, go to a subdirectory. #----------------------------------------------------------------------------- pwd=$( exec pwd ) if [[ "${pwd}" = "${canonsource}" || -f configure ]]; then if [[ -e build ]]; then echo "" echo "This configure script does not support compiling in the source directory" echo "if subdirectory 'build' already exists. Either remove 'build' or create" echo "an empty directory, change to it as the current directory, then execute:" echo " ${canonsource}/configure" echo "" exit 1 fi #----------------------------------------------------------- # Build a tiny Makefile to switch to the build subdirectory. #----------------------------------------------------------- rm -f Makefile echo "all:" >Makefile echo "${tab}( cd build && exec make all )" >>Makefile echo "" >>Makefile echo "install:" >>Makefile echo "${tab}( cd build && exec make install )" >>Makefile echo "" >>Makefile echo "love:" >>Makefile echo "${tab}@echo not war!" >>Makefile echo "" >>Makefile echo "pwd =" $( exec pwd ) #------------------------------------------------- # Do the rest of the building in the subdirectory. #------------------------------------------------- echo "Switching to subdirectory 'build'" mkdir build || exit 1 ls -ld build || exit 1 cd build || exit 1 source=".." canonsource=$( cd "${source}" && exec pwd ) scriptfile="../configure" fi pwd=$( exec pwd ) #----------------------------------------------------------------------------- # Derive the package name. #----------------------------------------------------------------------------- if [[ -z "${package}" ]]; then sourceabs=$( cd "${source}" && exec pwd ) package=$( echo "${sourceabs}" | gawk -F/ '{print $NF;}' ) fi #----------------------------------------------------------------------------- # Derive the package version number, which gets appended to library names, # from the source path, unless specified. #----------------------------------------------------------------------------- if [[ -z "${version}" ]]; then sourceabs=$( cd "${source}" && exec pwd ) version=$( echo "${sourceabs}" | gawk -F- '{print $NF;}' ) fi vstr="version = ${version}" vernums=( $( echo "${version}" | tr . ' ' ) ) if [[ "${#vernums[@]}" -ge 1 ]]; then version1="${vernums[0]}" vstr="${vstr} (${version1})" if [[ "${#vernums[@]}" -ge 2 ]]; then version2="${vernums[0]}.${vernums[1]}" vstr="${vstr} (${version2})" if [[ "${#vernums[@]}" -ge 3 ]]; then version3="${vernums[0]}.${vernums[1]}.${vernums[2]}" vstr="${vstr} (${version3})" if [[ "${#vernums[@]}" -ge 4 ]]; then version4="${vernums[0]}.${vernums[1]}.${vernums[2]}.${vernums[3]}" vstr="${vstr} (${version4})" fi fi fi fi msg "${vstr}" #----------------------------------------------------------------------------- # Set up defaults where nothing was specified, or was specified empty. #----------------------------------------------------------------------------- [[ -n "${prefix}" ]] || prefix="/tmp/${package}" [[ -n "${binprefix}" ]] || binprefix="${prefix}" [[ -n "${cgiprefix}" ]] || cgiprefix="${prefix}" [[ -n "${includeprefix}" ]] || includeprefix="${prefix}" [[ -n "${libprefix}" ]] || libprefix="${prefix}" [[ -n "${manprefix}" ]] || manprefix="${prefix}" [[ -n "${sbinprefix}" ]] || sbinprefix="${prefix}" [[ -n "${installprefix}" ]] || installprefix="${prefix}" [[ -n "${installbinprefix}" ]] || installbinprefix="${installprefix}" [[ -n "${installcgiprefix}" ]] || installcgiprefix="${installprefix}" [[ -n "${installincludeprefix}" ]] || installincludeprefix="${installprefix}" [[ -n "${installlibprefix}" ]] || installlibprefix="${installprefix}" [[ -n "${installmanprefix}" ]] || installmanprefix="${installprefix}" [[ -n "${installsbinprefix}" ]] || installsbinprefix="${installprefix}" [[ -n "${optimize}" ]] || optimize=2 #----------------------------------------------------------------------------- # Compile tools we need to use. #----------------------------------------------------------------------------- rm -fr tool mkdir tool vmsg 1 "Compiling tools while in directory" $( exec pwd ) gcc -o tool/readsymlink "${sourceabs}/CONFIG/readsymlink.c" || die=1 [[ 1 -gt ${verbose} ]] || ls -ld "${pwd}/tool/readsymlink" gcc -o tool/buildheader "${sourceabs}/CONFIG/buildheader.c" || die=1 [[ 1 -gt ${verbose} ]] || ls -ld "${pwd}/tool/buildheader" [[ -z "${die}" ]] || exit 1 readsymlink="${pwd}/tool/readsymlink" buildheader="${pwd}/tool/buildheader" function readlink { "${readsymlink}" "$@" } #----------------------------------------------------------------------------- # Configure system specific features. #----------------------------------------------------------------------------- unamem=$( uname -m | tr ' ' '_' ) unames=$( uname -s | tr ' ' '_' ) unamer=$( uname -r | tr ' ' '_' ) gcc="gcc" lib_cp_cmd="${gcc}" pgm_cp_cmd="${gcc}" lib_cc_cmd="${gcc}" pgm_cc_cmd="${gcc}" lib_as_cmd="${gcc}" pgm_as_cmd="${gcc}" lib_ld_cmd="${gcc}" pgm_ld_cmd="${gcc}" lib_def=( "${lib_def[@]}" "-DARCH_${unamem}" "-DARCH=${unamem}" ) pgm_def=( "${pgm_def[@]}" "-DARCH_${unamem}" "-DARCH=${unamem}" ) lib_warn=( -Werror -Wall -Wnested-externs -Wno-cast-qual -Wno-trigraphs -Wuninitialized -Wwrite-strings ) pgm_warn=( -Werror -Wall -Wnested-externs -Wno-cast-qual -Wno-trigraphs -Wuninitialized -Wwrite-strings ) if [[ -n "${warninline}" ]]; then lib_warn=( "${lib_warn[@]}" -Winline ) pgm_warn=( "${pgm_warn[@]}" -Winline ) fi lib_feat=( -fomit-frame-pointer -funsigned-char -funsigned-bitfields -frerun-loop-opt -finline -finline-functions ) pgm_feat=( -fomit-frame-pointer -funsigned-char -funsigned-bitfields -frerun-loop-opt -finline -finline-functions ) lib_cp_opt=( -pipe ) pgm_cp_opt=( -pipe ) if [[ -n "${std}" ]]; then lib_cp_opt=( "${lib_cp_opt[@]}" "-std=${std}" ) pgm_cp_opt=( "${pgm_cp_opt[@]}" "-std=${std}" ) fi if [[ -n "${cp_verbose}" ]]; then lib_cp_opt=( -v "${lib_cp_opt[@]}" ) pgm_cp_opt=( -v "${pgm_cp_opt[@]}" ) fi lib_cc_opt=( -pipe "-O${optimize}" ) pgm_cc_opt=( -pipe "-O${optimize}" ) if [[ -n "${std}" ]]; then lib_cc_opt=( "${lib_cc_opt[@]}" "-std=${std}" ) pgm_cc_opt=( "${pgm_cc_opt[@]}" "-std=${std}" ) fi if [[ -n "${static_libgcc}" ]]; then lib_cc_opt=( "${lib_cc_opt[@]}" -static-libgcc ) pgm_cc_opt=( "${pgm_cc_opt[@]}" -static-libgcc ) fi if [[ -n "${cc_verbose}" ]]; then lib_cc_opt=( -v "${lib_cc_opt[@]}" ) pgm_cc_opt=( -v "${pgm_cc_opt[@]}" ) fi lib_as_opt=( -pipe ) pgm_as_opt=( -pipe ) if [[ -n "${as_verbose}" ]]; then lib_as_opt=( -v "${lib_as_opt[@]}" ) pgm_as_opt=( -v "${pgm_as_opt[@]}" ) fi lib_ld_opt=( -pipe -shared -nostdlib -nostartfiles ) pgm_ld_opt=( -pipe ) if [[ -n "${ld_verbose}" ]]; then lib_ld_opt=( -v "${lib_ld_opt[@]}" ) pgm_ld_opt=( -v "${pgm_ld_opt[@]}" ) fi case "${unamem}" in ( i386 | i486 | i586 | i686 ) lib_def=( "${lib_def[@]}" -DGENARCH_i386 -DGENARCH=i386 -DENDIAN2=01 -DENDIAN4=0123 -DENDIAN8=01234567 ) pgm_def=( "${pgm_def[@]}" -DGENARCH_i386 -DGENARCH=i386 -DENDIAN2=01 -DENDIAN4=0123 -DENDIAN8=01234567 ) ;; ( sparc | sparc32 ) # lib_warn=( "${lib_warn[@]}" -Wcast-align ) # pgm_warn=( "${lib_warn[@]}" -Wcast-align ) lib_def=( "${lib_def[@]}" -DGENARCH_sparc -DGENARCH=sparc -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) pgm_def=( "${pgm_def[@]}" -DGENARCH_sparc -DGENARCH=sparc -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) ;; ( ultrasparc | usparc | sparc64 ) # lib_warn=( "${lib_warn[@]}" -Wcast-align ) # pgm_warn=( "${lib_warn[@]}" -Wcast-align ) lib_def=( "${lib_def[@]}" -DGENARCH_usparc -DGENARCH=usparc -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) pgm_def=( "${pgm_def[@]}" -DGENARCH_usparc -DGENARCH=usparc -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) ;; ( s390 ) lib_def=( "${lib_def[@]}" -DGENARCH_s390 -DGENARCH=s390 -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) pgm_def=( "${pgm_def[@]}" -DGENARCH_s390 -DGENARCH=s390 -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) ;; ( * ) lib_def=( "${lib_def[@]}" -DGENARCH_unknown -DGENARCH=unknown -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) pgm_def=( "${pgm_def[@]}" -DGENARCH_unknown -DGENARCH=unknown -DENDIAN2=10 -DENDIAN4=3210 -DENDIAN8=76543210 ) ;; esac case "${unames}" in ( OpenBSD ) lib_def=( "${lib_def[@]}" -DOpenBSD -DBSD ) pgm_def=( "${pgm_def[@]}" -DOpenBSD -DBSD ) case "${unamer}" in ( 2.* | 3.* ) havec99=0 strtoq=1 strtouq=1 lib_def=( "${lib_def[@]}" -DLIBC1999=0 -DUSE_strtoq -DUSE_strtouq -DNO_strtold ) pgm_def=( "${pgm_def[@]}" -DLIBC1999=0 -DUSE_strtoq -DUSE_strtouq -DNO_strtold ) ;; ( * ) ;; esac ;; ( FreeBSD ) lib_def=( "${lib_def[@]}" -DFreeBSD -DBSD ) pgm_def=( "${pgm_def[@]}" -DFreeBSD -DBSD ) v=$( echo "${unamer}" | cut -d . -f 1-2 ) case "${unamer}" in ( 2.* | 3.* | 4.* ) havec99=0 strtoq=1 strtouq=1 lib_def=( "${lib_def[@]}" -DLIBC1999=0 -DUSE_strtoq -DUSE_strtouq -DNO_strtold ) pgm_def=( "${pgm_def[@]}" -DLIBC1999=0 -DUSE_strtoq -DUSE_strtouq -DNO_strtold ) ;; ( * ) ;; esac ;; ( NetBSD ) lib_def=( "${lib_def[@]}" -DNetBSD -DBSD ) pgm_def=( "${pgm_def[@]}" -DNetBSD -DBSD ) havec99=0 strtoq=1 strtouq=1 lib_def=( "${lib_def[@]}" -DLIBC1999=0 -DUSE_strtoq -DUSE_strtouq -DNO_strtold ) pgm_def=( "${pgm_def[@]}" -DLIBC1999=0 -DUSE_strtoq -DUSE_strtouq -DNO_strtold ) ;; ( Linux ) lib_def=( "${lib_def[@]}" -DLIBC1999=1 -DLinux -DGNU ) pgm_def=( "${pgm_def[@]}" -DLIBC1999=1 -DLinux -DGNU ) ;; ( * ) lib_def=( "${lib_def[@]}" -DunknownOS -DOSunknown ) pgm_def=( "${pgm_def[@]}" -DunknownOS -DOSunknown ) ;; esac case "${unames}/${unamem}" in ( FreeBSD/i386 | FreeBSD/i486 | FreeBSD/i586 | FreeBSD/i686 ) ;; ( FreeBSD/ultrasparc | FreeBSD/usparc | FreeBSD/sparc64 ) ;; ( Linux/i386 | Linux/i486 | Linux/i586 | Linux/i686 ) ;; ( Linux/sparc | Linux/sparc32 ) ;; ( Linux/ultrasparc | Linux/usparc | Linux/sparc64 ) ;; ( Linux/s390 ) ;; ( NetBSD/i386 | NetBSD/i486 | NetBSD/i586 | NetBSD/i686 ) ;; ( NetBSD/sparc | NetBSD/sparc32 ) ;; ( NetBSD/ultrasparc | NetBSD/usparc | NetBSD/sparc64 ) ;; ( OpenBSD/i386 | OpenBSD/i486 | OpenBSD/i586 | OpenBSD/i686 ) ;; ( OpenBSD/sparc | OpenBSD/sparc32 ) ;; ( OpenBSD/ultrasparc | OpenBSD/usparc | OpenBSD/sparc64 ) ;; ( */* ) ;; esac #----------------------------------------------------------------------------- # Clean up and prepare to build the Makefile. #----------------------------------------------------------------------------- tablefile="config.dat" datalog="config.log" #----------------------------------------------------------------------------- # Record all products. #----------------------------------------------------------------------------- function product { echo "$@" 1>&3 } #----------------------------------------------------------------------------- # Record how this contribution is to be produced. #----------------------------------------------------------------------------- function namescan { local alias local dir local fulldir local fullname local name name="${1}" dir="${2}" fulldir="${3}" fullname="${fulldir}/${name}" #------------------------------------------- # Check if this directory is a target class. #------------------------------------------- case "${dir}" in ( bin-* | cgi-* | lib-* ) obj_class="${dir:0:3}" obj_target="${dir:4}" ;; ( sbin-* | test-* ) obj_class="${dir:0:4}" obj_target="${dir:5}" ;; ( hdr-* ) hdr_target="${dir:4}" ;; ( bin | cgi | lib | sbin | test ) obj_class="${dir}" obj_target=$( noextension "${name}" ) ;; ( hdr ) hdr_target=$( noextension "${name}" ) ;; esac #--------------------------------------------- # If a directory, descend into it via dirscan. # Symlinks are program aliases. #--------------------------------------------- if [[ -d "${name}" && ! -L "${name}" ]]; then ( cd "${name}" && dirscan "${name}" "${fulldir}/${name}" ) return $? fi #--------------------------------------------- # Check if this name is to be installed as-is. # The value is the subdirectory to install to. #--------------------------------------------- if [[ -L "${name}.DIR" ]]; then target=$( readlink "${name}.DIR" ) product "copy ${target}/${name} ${fullname}" return 0 fi if [[ -L "${name}.FILE" ]]; then target=$( readlink "${name}.FILE" ) product "copy ${target} ${fullname}" return 0 fi #----------------------------------------------------- # Check if this name has a different target specified. #----------------------------------------------------- if [[ -L "${name}.OBJ" ]]; then tmp=$( readlink "${name}.OBJ" ) tmp_class=$( dirname "${tmp}" ) if [[ "${tmp_class}" != "." ]]; then obj_class="${tmp_class}" fi obj_target=$( basename "${tmp}" ) fi #------------------------------------------ # Also check for a different header target. #------------------------------------------ if [[ -L "${name}.HDR" ]]; then hdr_target=$( readlink "${name}.HDR" ) hdr_ext=$( extension "${hdr_target}" ) if [[ "${hdr_ext}" != "h" ]]; then hdr_target="${hdr_target}.h" fi fi #----------------------------------------- # Check if this file needs more libraries. #----------------------------------------- if [[ -L "${name}.DEPLIB" ]]; then deps=$( readlink "${name}.DEPLIB" ) dep_libs="${dep_libs} ${deps}" fi #----------------------------------- # If not a file, nothing to do here. #----------------------------------- if [[ ! -f "${name}" ]]; then return 0 fi #----------------------------------------- # If this is a symlink for a program class # then it will be a produced alias. #----------------------------------------- if [[ -L "${name}" ]]; then if oneof "${obj_class}" bin cgi sbin test; then alias=$( readlink "${name}" ) if [[ -d "${alias}" ]]; then product "alias ${obj_class} ${alias} ${name}" else a=$( noextension "${alias}" ) b=$( noextension "${name}" ) case "${name}" in ( *.c ) product "alias ${obj_class} ${a} ${b}" ;; ( *.m ) product "alias ${obj_class} ${a} ${b}" ;; ( *.cc | *.cp | *.cxx | *.cpp | *.c++ | *.C ) product "alias ${obj_class} ${a} ${b}" ;; ( *.f | *.for | *.FOR ) product "alias ${obj_class} ${a} ${b}" ;; ( *.s | *.S ) product "alias ${obj_class} ${a} ${b}" ;; esac fi fi return 0 fi #------------------------------------- # Otherwise this is a regular product. #------------------------------------- case "${1}" in ( *.h ) if [[ -n "${hdr_target}" ]]; then product "hdr ${hdr_target} ${fullname}" fi ;; ( *.c ) if [[ -n "${obj_class}" && -n "${obj_target}" ]]; then if [[ "${obj_class}" = "lib" && -n "${hdr_target}" ]]; then product "hdr ${hdr_target} ${fullname}" fi product "${obj_class} c ${obj_target} ${fullname} ${dep_libs}" fi ;; ( *.m ) if [[ -n "${obj_class}" && -n "${obj_target}" ]]; then if [[ "${obj_class}" = "lib" && -n "${hdr_target}" ]]; then product "hdr ${hdr_target} ${fullname}" fi product "${obj_class} objc ${obj_target} ${fullname} ${dep_libs}" fi ;; ( *.cc | *.cp | *.cxx | *.cpp | *.c++ | *.C ) if [[ -n "${obj_class}" && -n "${obj_target}" ]]; then if [[ "${obj_class}" = "lib" && -n "${hdr_target}" ]]; then product "hdr ${hdr_target} ${fullname}" fi product "${obj_class} c++ ${obj_target} ${fullname} ${dep_libs}" fi ;; ( *.f | *.for | *.FOR ) if [[ -n "${obj_class}" && -n "${obj_target}" ]]; then product "${obj_class} for ${obj_target} ${fullname} ${dep_libs}" fi ;; ( *.s | *.S ) if [[ -n "${obj_class}" && -n "${obj_target}" ]]; then product "${obj_class} asm ${obj_target} ${fullname} ${dep_libs}" fi ;; #----------------------------------------------- # Man page files contribute to their own target. #----------------------------------------------- ( *.[0-9] ) sec=$( extension "${name}" ) product "man man/man${sec}/${name} ${fullname}" ;; #------------------------------------ # Anything else is not a contributor. #------------------------------------ ( * ) # product "# ${fullname}" ;; esac } #----------------------------------------------------------------------------- # Scan the source file tree at each level incrementally. #----------------------------------------------------------------------------- function dirscan { local deps local dir local fulldir local link local links local prefix local uclink dir="${1}" fulldir="${2}" dirdepth=$[ $dirdepth + 1 ] vmsg $dirdepth "directory: ${fulldir}" #---------------------------------- # Scan object target symlink names. #---------------------------------- links=( ) for link in bin cgi lib sbin test; do uclink=$( echo "${link}" | tr 'a-z' 'A-Z' ) if [[ -L "${link}" ]]; then links=( "${links[@]}" "${link}" ) obj_class="${link}" obj_target=$( readlink "${uclink}" ) fi done #---------------------------------------------------- # No more than one of these is allowed to be present. #---------------------------------------------------- if [[ ${#links[@]} -gt 1 ]]; then echo "in ${fulldir}: redundant object target class links: ${links[*]}" 1>&2 return fi #-------------------------------------------- # If a header target is specified, record it. #-------------------------------------------- if [[ -L HDR ]]; then hdr_target=$( readlink HDR ) fi #------------------------------------------------------------ # If dependent libraries are specified, add them to the list. #------------------------------------------------------------ if [[ -L DEPLIB ]]; then deps=$( readlink DEPLIB ) dep_libs="${dep_libs} ${deps}" fi #-------------------------------------------------- # Scan all files and directories for contributors. # Directory names must be lower case to contribute. #-------------------------------------------------- ls -1 | egrep '^[a-z]' | while read name; do ( namescan "${name}" "${dir}" "${fulldir}" ) done return 0 } dirdepth=0 ( cd "${source}" && dirscan . "${source}" ) 3>"${tablefile}" ls -ld "${tablefile}" #----------------------------------------------------------------------------- # function hr1 # function hr2 # function hr3 #----------------------------------------------------------------------------- function hr1 { echo "##############################################################################" echo "" } function hr2 { echo "#=============================================================================" echo "" } function hr3 { echo "#-----------------------------------------------------------------------------" echo "" } function hr4 { echo "#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -" echo "" } #----------------------------------------------------------------------------- # function make_start #----------------------------------------------------------------------------- function make_start { vmsg 2 "Generating Makefile section: start" echo "##############################################################################" echo "# This Makefile was generated:" echo "# date/time: " $( exec date '+%Y-%m-%d %H:%M:%S' ) echo "# configure: " "${scriptfile}" echo "# sourcetree:" "${source}" echo "# hostname: " $( exec hostname ) echo "# username: " $( exec whoami ) echo "##############################################################################" echo "" echo "lib_def = ${lib_def[@]}" echo "pgm_def = ${pgm_def[@]}" echo "" echo "lib_warn = ${lib_warn[@]}" echo "pgm_warn = ${pgm_warn[@]}" echo "" echo "lib_feat = ${lib_feat[@]}" echo "pgm_feat = ${pgm_feat[@]}" if [[ -n "${cpp}" ]]; then echo "" echo "lib_cp_cmd = ${lib_cp_cmd}" echo "pgm_cp_cmd = ${pgm_cp_cmd}" echo "" echo "lib_cp_opt =" "${lib_cp_opt[@]}" "\$(lib_def)" echo "pgm_cp_opt =" "${pgm_cp_opt[@]}" "\$(pgm_def)" if [[ -n "${asm}" ]]; then echo "" echo "lib_cc_cmd = ${lib_cc_cmd}" echo "pgm_cc_cmd = ${pgm_cc_cmd}" echo "" echo "lib_cc_opt =" "${lib_cc_opt[@]}" "\$(lib_feat)" "\$(lib_warn)" echo "pgm_cc_opt =" "${pgm_cc_opt[@]}" "\$(pgm_feat)" "\$(pgm_warn)" echo "" echo "lib_as_cmd = ${lib_as_cmd}" echo "pgm_as_cmd = ${pgm_as_cmd}" echo "" echo "lib_as_opt =" "${lib_as_opt[@]}" echo "pgm_as_opt =" "${pgm_as_opt[@]}" else echo "" echo "lib_cc_cmd = ${lib_cc_cmd}" echo "pgm_cc_cmd = ${pgm_cc_cmd}" echo "" echo "lib_cc_opt =" "${lib_cc_opt[@]}" "\$(lib_feat)" "\$(lib_warn)" echo "pgm_cc_opt =" "${pgm_cc_opt[@]}" "\$(pgm_feat)" "\$(pgm_warn)" fi else if [[ -n "${asm}" ]]; then echo "" echo "lib_cc_cmd = ${lib_cc_cmd}" echo "pgm_cc_cmd = ${pgm_cc_cmd}" echo "" echo "lib_cc_opt =" "${lib_cc_opt[@]}" "\$(lib_def)" "\$(lib_feat)" "\$(lib_warn)" echo "pgm_cc_opt =" "${pgm_cc_opt[@]}" "\$(pgm_def)" "\$(pgm_feat)" "\$(pgm_warn)" echo "" echo "lib_as_cmd = ${lib_as_cmd}" echo "pgm_as_cmd = ${pgm_as_cmd}" echo "" echo "lib_as_opt =" "${lib_as_opt[@]}" echo "pgm_as_opt =" "${pgm_as_opt[@]}" else echo "" echo "lib_cc_cmd = ${lib_cc_cmd}" echo "pgm_cc_cmd = ${pgm_cc_cmd}" echo "" echo "lib_cc_opt =" "${lib_cc_opt[@]}" "\$(lib_def)" "\$(lib_feat)" "\$(lib_warn)" echo "pgm_cc_opt =" "${pgm_cc_opt[@]}" "\$(pgm_def)" "\$(pgm_feat)" "\$(pgm_warn)" fi fi echo "" echo "lib_ld_cmd = ${lib_ld_cmd}" echo "pgm_ld_cmd = ${pgm_ld_cmd}" echo "" echo "lib_ld_opt =" "${lib_ld_opt[@]}" echo "pgm_ld_opt =" "${pgm_ld_opt[@]}" echo "" echo "##############################################################################" echo "" echo ".SUFFIXES:" echo "" } #----------------------------------------------------------------------------- # function just_once # purpose Return true the first time, and false all subsequent times # for a given string. This will be saved in a file named # "just_once" in the build directory. # arguments 1 key string #----------------------------------------------------------------------------- justonce="${pwd}/just_once" function just_once { local result if [[ -e "${justonce}" ]]; then result=$( egrep '^'"${1}"'$' < "${justonce}" | head -1 ) else result="" fi [[ -z "${result}" ]] || return 1 echo "x${1}" | cut -c 2- >>"${justonce}" return 0 } #----------------------------------------------------------------------------- # function make_dir # purpose Output Makefile specs to create a directory. # arguments 1 directory name #----------------------------------------------------------------------------- function make_dir { local dir for dir in "$@"; do if just_once "${dir}"; then echo "${dir}:" echo "${tab}mkdir -p ${dir}" echo "" fi done return 0 } #----------------------------------------------------------------------------- # function all_headers # function header_src header # function all_products class # function class_product_src class product # function class_product_obj class product # function class_product_lib class product #----------------------------------------------------------------------------- # These are functions to extract specific lists from the stored tables. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # function all_headers # arguments -none- # results list of all produced header files #----------------------------------------------------------------------------- function all_headers { gawk '{if($1=="hdr"){print $2;}}' <"${tablefile}" | sort -u } #----------------------------------------------------------------------------- # function header_src # arguments 1: header target # results list of source files that contribute to that header target #----------------------------------------------------------------------------- function header_src { N="${1}" gawk '{if($1=="hdr"&&$2==ENVIRON["N"]){print $3;}}' <"${tablefile}" | sortpath } #----------------------------------------------------------------------------- # function all_copy # arguments -none- # results files to install: destination, source #----------------------------------------------------------------------------- function all_copy { gawk '{if($1=="copy"){print $2,$3;}}' <"${tablefile}" } #----------------------------------------------------------------------------- # function all_products # arguments 1: product class # results product name #----------------------------------------------------------------------------- function all_products { C="${1}" gawk '{if($1==ENVIRON["C"]){print $3;}}' <"${tablefile}" | sort -u } #----------------------------------------------------------------------------- # function class_product_src # arguments 1: product class # 2: product target name # results product source file names (in source tree) #----------------------------------------------------------------------------- function class_product_src { C="${1}" N="${2}" gawk '{if($1==ENVIRON["C"]&&$3==ENVIRON["N"]){print $4;}}' <"${tablefile}" | sortpath } #----------------------------------------------------------------------------- # function class_product_dep # arguments 1: product class # 2: product target name # results product library dependencies #----------------------------------------------------------------------------- function class_product_dep { C="${1}" N="${2}" gawk '{if($1==ENVIRON["C"]&&$3==ENVIRON["N"]){for(i=5;i<=NF;++i){print $i;}}}' <"${tablefile}" | sort -u } #----------------------------------------------------------------------------- # function class_product_obj # arguments 1: product class # 2: product target name # results product object file names #----------------------------------------------------------------------------- function class_product_obj { C="${1}" N="${2}" gawk '{if($1==ENVIRON["C"]&&$3==ENVIRON["N"]){print $4;}}' <"${tablefile}" | gawk -F/ '{print $NF;}' | gawk -F. 'BEGIN{OFS=".";}{$NF="o";print $0;}' | sort } #----------------------------------------------------------------------------- # function class_product_lib # arguments 1: product class # 2: product target name # results additional libraries the product depends on #----------------------------------------------------------------------------- function class_product_lib { C="${1}" N="${2}" gawk '{if($1==ENVIRON["C"]&&$3==ENVIRON["N"]){for(i=5;i<=NF;++i){print $i;}}}' <"${tablefile}" | sort -u } #----------------------------------------------------------------------------- # function these_classes # arguments list of classes to determine # results list of given classes in which a product is produced #----------------------------------------------------------------------------- function these_classes { local class for class in "$@"; do C="${class}" gawk 'BEGIN{c=ENVIRON["C"];}{if($1==c){++n;}}END{if(n>0){print c;}}' <"${tablefile}" done } #----------------------------------------------------------------------------- # function alias_of # arguments 1: alias target name # results list of alias names #----------------------------------------------------------------------------- function alias_of { C="${1}" N="${2}" gawk '{if($1=="alias"&&$2==ENVIRON["C"]&&$3==ENVIRON["N"]){print $4;}}' <"${tablefile}" } #----------------------------------------------------------------------------- # function logdata #----------------------------------------------------------------------------- # Log the output of the specified data source. #----------------------------------------------------------------------------- function logdata { local name # if [[ -n "${dologdata}" ]]; then echo "" >>"${datalog}" echo "==>" "$@" "<==" >>"${datalog}" "$@" >>"${datalog}" # fi } #----------------------------------------------------------------------------- # function make_all #----------------------------------------------------------------------------- # Generate Makefile target "all" with prerequisites of each product class # that actually has a product. #----------------------------------------------------------------------------- function make_all { vmsg 2 "Generating Makefile section: all" hr1 echo -n "all:" logdata these_classes copy hdr lib bin cgi sbin test these_classes copy hdr lib bin cgi sbin test | gawk '{printf " all_%s",$1;}END{printf "\n\n";}' } #----------------------------------------------------------------------------- # function make_copy #----------------------------------------------------------------------------- # Generate Makefile specs for files to be copied. #----------------------------------------------------------------------------- function make_copy { vmsg 2 "Generating Makefile section: copy" hr1 logdata all_copy echo -n "all_copy:" all_copy | gawk '{printf " %s",$1;}END{printf "\n";}' echo "" all_copy | while read dst src; do dstdir=$( dirname "${dst}" ) vmsg 3 "Generating Makefile section: copy ${dst}" make_dir "${dstdir}" echo "${dst}: ${dstdir} ${src}" echo "${tab}cp -p ${src} ${dst}" echo "" done } #----------------------------------------------------------------------------- # function make_hdr #----------------------------------------------------------------------------- # Generate Makefile specs for: # 1. Target "all_hdr" listing all headers as prerequisites. # 2. Targets for each header to build it from all its sources. #----------------------------------------------------------------------------- function make_hdr { vmsg 2 "Generating Makefile section: hdr" hdr=$( these_classes hdr ) [[ -n "${hdr}" ]] || return hr1 echo -n "all_hdr:" logdata all_headers all_headers | gawk '{printf " include/%s",$1;}END{printf "\n";}' echo "" all_headers | while read hdrname; do vmsg 3 "Generating Makefile section: hdr ${hdrname}" hr2 make_dir $( dirname "include/${hdrname}" ) echo -n "include/${hdrname}:" echo -n $( dirname " include/${hdrname}" ) logdata header_src "${hdrname}" header_src "${hdrname}" | gawk '{printf " %s",$1;}END{printf "\n";}' # echo -n "${tab}${scriptfile} --${hdropt} include/${hdrname}" echo -n "${tab}${buildheader} include/${hdrname}" header_src "${hdrname}" | gawk '{printf " %s",$1;}END{printf "\n";}' echo "" done } #----------------------------------------------------------------------------- # function make_lib #----------------------------------------------------------------------------- # Generate Makefile specs for: # 1. Target "all_lib" listing all libraries as prerequisites. # 2. Targets for each library to build it from the .o files. # 3. Targets for each library .o to build it from its source. #----------------------------------------------------------------------------- function make_lib { vmsg 2 "Generating Makefile section: lib" hr1 #------------------------------------------- # Generate Makefile specs for all libraries. #------------------------------------------- echo -n "all_lib:" [[ -n "${noarlib}" ]] || echo -n " all_arlib" [[ -n "${nosolib}" ]] || echo -n " all_solib" echo "" echo "" if [[ -z "${noarlib}" ]]; then all_products lib \ | V="${version}" gawk 'BEGIN{printf "all_arlib:";}{printf " lib/lib%s.a.%s",$1,ENVIRON["V"];}' echo "" echo "" fi if [[ -z "${nosolib}" ]]; then all_products lib \ | V="${version}" gawk 'BEGIN{printf "all_solib:";}{printf " lib/lib%s.so.%s",$1,ENVIRON["V"];}' echo "" echo "" fi #----------------------------------------------- # Generate Makefile specs to build each library. #----------------------------------------------- for libname in "${all_libs[@]}"; do vmsg 3 "Generating Makefile section: lib ${libname}" hr2 logdata class_product_obj lib "${libname}" logdata class_product_dep lib "${libname}" logdata class_product_src lib "${libname}" #----------------------------------------------------- # Generate Makefile specs to build an archive library. #----------------------------------------------------- if [[ -z "${noarlib}" ]]; then make_dir "lib" make_dir "obj/arlib/${libname}" echo -n "lib/lib${libname}.a.${version}: lib obj/arlib/${libname}" class_product_obj lib "${libname}" | N="${libname}" gawk '{printf " obj/arlib/%s/%s",ENVIRON["N"],$1;}' echo "" echo -n "${tab}ar qcs lib/lib${libname}.a.${version}" class_product_obj lib "${libname}" | N="${libname}" gawk '{printf " obj/arlib/%s/%s",ENVIRON["N"],$1;}' echo "" if [[ "${#vernums[@]}" -gt 3 ]]; then echo "${tab}ln -fs lib${libname}.a.${version4} lib/lib${libname}.a.${version3}" fi if [[ "${#vernums[@]}" -gt 2 ]]; then echo "${tab}ln -fs lib${libname}.a.${version3} lib/lib${libname}.a.${version2}" fi if [[ "${#vernums[@]}" -gt 1 ]]; then echo "${tab}ln -fs lib${libname}.a.${version2} lib/lib${libname}.a.${version1}" fi if [[ "${#vernums[@]}" -gt 0 ]]; then echo "${tab}ln -fs lib${libname}.a.${version1} lib/lib${libname}.a" fi echo "" fi #--------------------------------------------------- # Generate Makefile specs to build a shared library. #--------------------------------------------------- if [[ -z "${nosolib}" ]]; then make_dir "lib" make_dir "obj/solib/${libname}" echo -n "lib/lib${libname}.so.${version}: lib obj/solib/${libname}" class_product_obj lib "${libname}" | N="${libname}" gawk '{printf " obj/solib/%s/%s",ENVIRON["N"],$1;}' echo "" echo -n "${tab}\$(lib_ld_cmd) \$(lib_ld_opt)" \ "-Wl,-S,-soname,lib${libname}.so.${version1} -o lib/lib${libname}.so.${version}" class_product_obj lib "${libname}" | N="${libname}" gawk '{printf " obj/solib/%s/%s",ENVIRON["N"],$1;}' class_product_dep lib "${libname}" | gawk '{printf " -l%s",$1;}' echo "" if [[ "${#vernums[@]}" -gt 3 ]]; then echo "${tab}ln -fs lib${libname}.so.${version4} lib/lib${libname}.so.${version3}" fi if [[ "${#vernums[@]}" -gt 2 ]]; then echo "${tab}ln -fs lib${libname}.so.${version3} lib/lib${libname}.so.${version2}" fi if [[ "${#vernums[@]}" -gt 1 ]]; then echo "${tab}ln -fs lib${libname}.so.${version2} lib/lib${libname}.so.${version1}" fi if [[ "${#vernums[@]}" -gt 0 ]]; then echo "${tab}ln -fs lib${libname}.so.${version1} lib/lib${libname}.so" fi echo "" fi #---------------------------------------------------- # Generate Makefile specs to compile library sources. #---------------------------------------------------- class_product_src lib "${libname}" | while read srcname; do vmsg 9 "Generating Makefile section: lib ${libname} ${srcname}" srcdir=$( dirname "${srcname}" ) srcref="-I ${srcdir} -I ${source}/include -I ./include ${srcname}" objname=$( echo "${srcname}" | gawk -F/ '{print $NF;}' | gawk -F. 'BEGIN{OFS=".";}{$NF="o";print $0;}' ) for lc in arlib solib; do [[ "${lc}" = "arlib" ]] && libfeat=( -DARLIBRARY=1 ) [[ "${lc}" = "solib" ]] && libfeat=( -DSOLIBRARY=1 -DfPIC=1 -fPIC ) echo "obj/${lc}/${libname}/${objname}: ${srcname}" if [[ -n "${asm}" ]]; then if [[ -n "${cpp}" ]]; then cppname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="i";print $0;}' ) asmname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="s";print $0;}' ) echo "${tab}\$(lib_cp_cmd) \$(lib_cp_opt)" \ "-E -o obj/${lc}/${libname}/${cppname} ${srcref}" echo "${tab}\$(lib_cc_cmd) \$(lib_cc_opt)" "${libfeat[@]}" "-fverbose-asm" \ "-S -o obj/${lc}/${libname}/${asmname} obj/${lc}/${libname}/${cppname}" echo "${tab}\$(lib_as_cmd) \$(lib_as_opt)" \ "-c -o obj/${lc}/${libname}/${objname} obj/${lc}/${libname}/${asmname}" else asmname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="s";print $0;}' ) echo "${tab}\$(lib_cc_cmd) \$(lib_cc_opt)" "${libfeat[@]}" "-fverbose-asm" \ "-S -o obj/${lc}/${libname}/${asmname} ${srcref}" echo "${tab}\$(lib_as_cmd) \$(lib_as_opt)" \ "-c -o obj/${lc}/${libname}/${objname} obj/${lc}/${libname}/${asmname}" fi else if [[ -n "${cpp}" ]]; then cppname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="i";print $0;}' ) echo "${tab}\$(lib_cp_cmd) \$(lib_cp_opt)" \ "-E -o obj/${lc}/${libname}/${cppname} ${srcref}" echo "${tab}\$(lib_cc_cmd) \$(lib_cc_opt)" "${libfeat[@]}" \ "-c -o obj/${lc}/${libname}/${objname} obj/${lc}/${libname}/${cppname}" else echo "${tab}\$(lib_cc_cmd) \$(lib_cc_opt)" "${libfeat[@]}" \ "-c -o obj/${lc}/${libname}/${objname} ${srcref}" fi fi echo "" done done done } #----------------------------------------------------------------------------- # function make_pgm #----------------------------------------------------------------------------- # Generate Makefile specs for each of: bin cgi sbin test # 1. Target "all_class" listing all programs as prerequisites. # 2. Targets for each program to build it from the .o files. # 3. Targets for each program .o to build it from its source. #----------------------------------------------------------------------------- function make_pgm { local pgmclass pgmclass="${1}" vmsg 2 "Generating Makefile section: ${pgmclass}" logdata all_products "${pgmclass}" # specify all targets hr1 make_dir "${pgmclass}" echo -n "all_${pgmclass}: ${pgmclass}" all_products "${pgmclass}" | while read pgmname; do echo -n " ${pgmclass}/${pgmname}" done echo "" echo "" all_products "${pgmclass}" | while read pgmname; do vmsg 3 "Generating Makefile section: ${pgmclass} ${pgmname}" logdata class_product_obj "${pgmclass}" "${pgmname}" logdata class_product_dep "${pgmclass}" "${pgmname}" # target: dependencies hr2 make_dir "obj/${pgmclass}/${pgmname}" echo -n "${pgmclass}/${pgmname}: ${pgmclass} obj/${pgmclass}/${pgmname}" class_product_obj "${pgmclass}" "${pgmname}" | while read objname; do echo -n " obj/${pgmclass}/${pgmname}/${objname}" done echo "" # link, object files, libraries echo -n "${tab}\$(pgm_ld_cmd) \$(pgm_ld_opt) -o ${pgmclass}/${pgmname}" class_product_obj "${pgmclass}" "${pgmname}" | while read objname; do echo -n " obj/${pgmclass}/${pgmname}/${objname}" done if [[ -z "${nosolib}" && -n "${execdynamic}" ]]; then echo -n " -L./lib" class_product_dep "${pgmclass}" "${pgmname}" | while read depname; do echo -n " -l${depname}" done else class_product_dep "${pgmclass}" "${pgmname}" | while read depname; do if [[ -n "${execstatic}" ]]; then # make it entirely static for all libs echo -n " -static" fi if oneof "${depname}" "${all_libs[@]}"; then # if built here then use the static library echo -n " lib/lib${depname}.a.${version}" else # otherwise use the dynamic shared library echo -n " -l${depname}" fi done fi echo "" # strip executable [[ -n "${nostrip}" ]] || echo "${tab}strip ${pgmclass}/${pgmname}" # create aliases alias_of "${pgmclass}" "${pgmname}" | while read aliasname; do if [[ -n "${hardalias}" ]]; then echo "${tab}ln -f ${pgmclass}/${pgmname} ${pgmclass}/${aliasname}" else echo "${tab}ln -fs ${pgmname} ${pgmclass}/${aliasname}" fi done echo "" # compile each source file for each object needed by this executable class_product_src "${pgmclass}" "${pgmname}" | while read srcname; do vmsg 9 "Generating Makefile section: ${pgmclass} ${pgmname} ${srcname}" srcdir=$( dirname "${srcname}" ) srcref="-I ${srcdir} -I ${source}/include -I ./include ${srcname}" objname=$( echo "${srcname}" | gawk -F/ '{print $NF;}' | gawk -F. 'BEGIN{OFS=".";}{$NF="o";print $0;}' ) echo "obj/${pgmclass}/${pgmname}/${objname}: ${srcname}" if [[ -n "${asm}" ]]; then if [[ -n "${cpp}" ]]; then cppname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="i";print $0;}' ) asmname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="s";print $0;}' ) echo "${tab}\$(pgm_cp_cmd) \$(pgm_cp_opt)" \ "-E -o obj/${pgmclass}/${pgmname}/${cppname} ${srcref}" echo "${tab}\$(pgm_cc_cmd) \$(pgm_cc_opt)" "-fverbose-asm" \ "-S -o obj/${pgmclass}/${pgmname}/${asmname} obj/${pgmclass}/${pgmname}/${cppname}" echo "${tab}\$(pgm_as_cmd) \$(pgm_as_opt)" \ "-c -o obj/${pgmclass}/${pgmname}/${objname} obj/${pgmclass}/${pgmname}/${asmname}" else asmname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="s";print $0;}' ) echo "${tab}\$(pgm_cc_cmd) \$(pgm_cc_opt)" "-fverbose-asm" \ "-S -o obj/${pgmclass}/${pgmname}/${asmname} ${srcref}" echo "${tab}\$(pgm_as_cmd) \$(pgm_as_opt)" \ "-c -o obj/${pgmclass}/${pgmname}/${objname} obj/${pgmclass}/${pgmname}/${asmname}" fi else if [[ -n "${cpp}" ]]; then cppname=$( echo "${objname}" | gawk -F. 'BEGIN{OFS=".";}{$NF="i";print $0;}' ) echo "${tab}\$(pgm_cp_cmd) \$(pgm_cp_opt)" \ "-E -o obj/${pgmclass}/${pgmname}/${cppname} ${srcref}" echo "${tab}\$(pgm_cc_cmd) \$(pgm_cc_opt)" \ "-c -o obj/${pgmclass}/${pgmname}/${objname} obj/${pgmclass}/${pgmname}/${cppname}" else echo "${tab}\$(pgm_cc_cmd) \$(pgm_cc_opt)" \ "-c -o obj/${pgmclass}/${pgmname}/${objname} ${srcref}" fi fi echo "" done done } #----------------------------------------------------------------------------- # functions install_X #----------------------------------------------------------------------------- # Generate Makefile specs to do a general install in 5 phases. Each phase # is done across all file names before the next phase is done. #----------------------------------------------------------------------------- # 1: remove any leftover "new" files from incomplete previous installs # 2: copy installable files to a temporary "new" name # 3: hard link the current file to an "old" name # 4: move the "new" file to replace and become the current one # 5: remove the old files, if the --remove-old option is requested # prep copy link move final #----------------------------------------------------------------------------- function install_1 { echo "${tab}rm -f ${2}.NEW ${2}.OLD" } function install_2 { echo "${tab}cp -dfp ${1} ${2}.NEW" echo "${tab}chmod go=u-w ${2}.NEW" } function install_3 { echo "${tab}-ln -f ${2} ${2}.OLD" } function install_4 { echo "${tab}mv -f ${2}.NEW ${2}" name="${2}" shift shift for link in "$@"; do echo "${tab}ln -fs" $( basename "${name}" ) "${link}" name="${link}" done } function install_5 { if [[ -n "${removeold}" ]]; then echo "${tab}rm -f ${2}.OLD" fi } #----------------------------------------------------------------------------- # function install_dirs # purpose output all the needed install target directory names #----------------------------------------------------------------------------- function install_dirs { logdata all_copy if [[ $( all_copy | wc -l ) -gt 0 ]]; then all_copy | while read dst src; do thisclass=$( echo "${dst}" | cut -d / -f 1 ) case "${thisclass}" in ( include ) thisprefix="${installincludeprefix}" ;; ( lib ) thisprefix="${installlibprefix}" ;; ( man ) thisprefix="${installmanprefix}" ;; ( bin ) thisprefix="${installbinprefix}" ;; ( cgi ) thisprefix="${installcgiprefix}" ;; ( sbin ) thisprefix="${installsbinprefix}" ;; ( * ) continue ;; esac dirname "${thisprefix}/${dst}" done fi logdata all_headers if [[ $( all_headers | wc -l ) -gt 0 ]]; then all_headers | while read hdrname; do dirname "${installincludeprefix}/include/${hdrname}" done fi if [[ ${#all_libs[@]} -gt 0 ]]; then echo "${installlibprefix}/lib" fi logdata all_products bin if [[ $( all_products bin | wc -l ) -gt 0 ]]; then all_products bin | while read pgmname; do dirname "${installbinprefix}/bin/${pgmname}" done fi logdata all_products cgi if [[ $( all_products cgi | wc -l ) -gt 0 ]]; then all_products cgi | while read pgmname; do dirname "${installcgiprefix}/cgi/${pgmname}" done fi logdata all_products sbin if [[ $( all_products sbin | wc -l ) -gt 0 ]]; then all_products sbin | while read pgmname; do dirname "${installsbinprefix}/sbin/${pgmname}" done fi return 0 } #----------------------------------------------------------------------------- # function make_install #----------------------------------------------------------------------------- function make_install { vmsg 2 "Generating Makefile section: install" hr1 echo "install: all" install_dirs | sortpath -u | gawk '{printf "\ttest -d %s || mkdir -p %s\n",$1,$1;}' for phase in 1 2 3 4 5; do vmsg 3 "Generating Makefile section: install ${phase}" logdata all_copy if [[ $( all_copy | wc -l ) -gt 0 ]]; then all_copy | while read dst src; do vmsg 9 "Generating Makefile section: install ${phase} copy: ${src}" thisclass=$( echo "${dst}" | cut -d / -f 1 ) case "${thisclass}" in ( include ) thisprefix="${installincludeprefix}" ;; ( lib ) thisprefix="${installlibprefix}" ;; ( man ) thisprefix="${installmanprefix}" ;; ( bin ) thisprefix="${installbinprefix}" ;; ( cgi ) thisprefix="${installcgiprefix}" ;; ( sbin ) thisprefix="${installsbinprefix}" ;; ( * ) continue ;; esac install_${phase} "${src}" "${thisprefix}/${dst}" done fi logdata all_headers if [[ $( all_headers | wc -l ) -gt 0 ]]; then all_headers | while read hdrname; do vmsg 9 "Generating Makefile section: install ${phase} hdr: ${hdrname}" install_${phase} "include/${hdrname}" "${installincludeprefix}/include/${hdrname}" done fi if [[ "${#all_libs[@]}" -gt 0 ]]; then if [[ -z "${noarlib}" ]]; then for libname in "${all_libs[@]}"; do vmsg 9 "Generating Makefile section: install ${phase} arlib: ${libname}" case "${#vernums[@]}" in ( 1 ) install_${phase} "lib/lib${libname}.so.${version}" \ "${installlibprefix}/lib/lib${libname}.a.${version1}" \ "${installlibprefix}/lib/lib${libname}.a" ;; ( 2 ) install_${phase} "lib/lib${libname}.a.${version}" \ "${installlibprefix}/lib/lib${libname}.a.${version2}" \ "${installlibprefix}/lib/lib${libname}.a.${version1}" \ "${installlibprefix}/lib/lib${libname}.a" ;; ( 3 ) install_${phase} "lib/lib${libname}.a.${version}" \ "${installlibprefix}/lib/lib${libname}.a.${version3}" \ "${installlibprefix}/lib/lib${libname}.a.${version2}" \ "${installlibprefix}/lib/lib${libname}.a.${version1}" \ "${installlibprefix}/lib/lib${libname}.a" ;; ( 4 ) install_${phase} "lib/lib${libname}.a.${version}" \ "${installlibprefix}/lib/lib${libname}.a.${version4}" \ "${installlibprefix}/lib/lib${libname}.a.${version3}" \ "${installlibprefix}/lib/lib${libname}.a.${version2}" \ "${installlibprefix}/lib/lib${libname}.a.${version1}" \ "${installlibprefix}/lib/lib${libname}.a" ;; esac done fi if [[ -z "${nosolib}" ]]; then for libname in "${all_libs[@]}"; do vmsg 9 "Generating Makefile section: install ${phase} solib: ${libname}" case "${#vernums[@]}" in ( 1 ) install_${phase} "lib/lib${libname}.so.${version}" \ "${installlibprefix}/lib/lib${libname}.so.${version1}" \ "${installlibprefix}/lib/lib${libname}.so" ;; ( 2 ) install_${phase} "lib/lib${libname}.so.${version}" \ "${installlibprefix}/lib/lib${libname}.so.${version2}" \ "${installlibprefix}/lib/lib${libname}.so.${version1}" \ "${installlibprefix}/lib/lib${libname}.so" ;; ( 3 ) install_${phase} "lib/lib${libname}.so.${version}" \ "${installlibprefix}/lib/lib${libname}.so.${version3}" \ "${installlibprefix}/lib/lib${libname}.so.${version2}" \ "${installlibprefix}/lib/lib${libname}.so.${version1}" \ "${installlibprefix}/lib/lib${libname}.so" ;; ( 4 ) install_${phase} "lib/lib${libname}.so.${version}" \ "${installlibprefix}/lib/lib${libname}.so.${version4}" \ "${installlibprefix}/lib/lib${libname}.so.${version3}" \ "${installlibprefix}/lib/lib${libname}.so.${version2}" \ "${installlibprefix}/lib/lib${libname}.so.${version1}" \ "${installlibprefix}/lib/lib${libname}.so" ;; esac done fi fi for pgmclass in bin cgi sbin; do logdata all_products "${pgmclass}" all_products "${pgmclass}" | while read pgmname; do vmsg 9 "Generating Makefile section: install ${phase} ${pgmclass}: ${pgmname}" eval "thisdir=\${install${pgmclass}prefix}/${pgmclass}" install_${phase} "${pgmclass}/${pgmname}" "${thisdir}/${pgmname}" if [[ "${phase}" = 4 ]]; then alias_of "${pgmclass}" "${pgmname}" | while read aliasname; do if [[ -n "${hardalias}" ]]; then echo "${tab}ln -f ${thisdir}/${pgmname} ${thisdir}/${aliasname}" else echo "${tab}ln -fs ${pgmname} ${thisdir}/${aliasname}" fi done fi done done done echo "" return 0 } #----------------------------------------------------------------------------- # function make_clean #----------------------------------------------------------------------------- function make_clean { vmsg 2 "Generating Makefile section: clean" hr1 echo "clean:" echo "${tab}rm -fr bin" echo "${tab}rm -fr cgi" echo "${tab}rm -fr include" echo "${tab}rm -fr lib" echo "${tab}rm -fr obj" echo "${tab}rm -fr sbin" echo "${tab}rm -fr test" echo "" echo "distclean: clean" echo "${tab}rm -f config.dat" echo "${tab}rm -f readsymlink" echo "${tab}rm -f readsymlink.c" echo "${tab}rm -f Makefile" echo "" } #----------------------------------------------------------------------------- # function make_finish #----------------------------------------------------------------------------- function make_finish { vmsg 2 "Generating Makefile section: finish" echo "love:" echo "${tab}@echo not war!" echo "" echo "##############################################################################" } #----------------------------------------------------------------------------- # function make_make #----------------------------------------------------------------------------- function make_make { make_start make_all make_copy make_hdr make_lib make_pgm bin make_pgm cgi make_pgm sbin make_pgm test make_install make_clean make_finish } #----------------------------------------------------------------------------- # Collect a list of libraries built in this package. #----------------------------------------------------------------------------- logdata all_products lib all_libs=( $( all_products lib ) ) #----------------------------------------------------------------------------- # Output the Makefile. #----------------------------------------------------------------------------- rm -f Makefile make_make >Makefile #----------------------------------------------------------------------------- # Display the final messages. #----------------------------------------------------------------------------- ls -ld Makefile if [[ -z "${domake}" && -z "${domakeinstall}" ]]; then echo "" echo "You may now build the project with:" echo " make" echo "and install the project with:" echo " make install" echo "" else [[ -z "${domake}" ]] || make || exit 1 [[ -z "${domakeinstall}" ]] || make install || exit 1 fi exit 0