#!/bin/sh # # Author: Pekka Riikonen # # Copyright (C) 2005 - 2007 Pekka Riikonen # All rights reserved. # # 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. The name of the author may not be used to endorse or promote # products derived from this software without specific prior written # permission. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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. # ############################################################################### # Shell compatibility # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then # Despite of this, we have managed to segfault some zsh's. emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' fi DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # Work around bugs in pre-3.0 UWIN ksh. $as_unset ENV MAIL MAILPATH PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var fi done ############################################################################### # Global variables # Packaging and compressing ad_gzip=true ad_bzip2=false ad_compress=false ad_zip=false # Distribution subdirectory distdir="distdir" am_distdir= # This current distribution distribution=default distfile=$distribution dist_version=0.0 package= bug_report= # All inherited distributions in this distribution inherits= # All distribution defines for this distribution distdefs= # All distribution undefines for this distribution undistdefs= # All distribution options doptions= opt_template=false opt_no_dist=false opt_no_inherit=false # All includes includes= # All excludes excludes= # All noprocesses noprocess= # All hooks pre_hooks= post_hooks= pre_dist_hooks= post_dist_hooks= pre_p_dist_hooks= post_p_dist_hooks= # Distribution license and license header license= licenseh= # Whether to output ad_debug information debug=false nolog=false # Autodist version ver=@VERSION@ ############################################################################### # Configuration file if test -f "$distdir/autodist.conf"; then . $distdir/autodist.conf fi DP=$DISTPREFIX ############################################################################### # Functions # # Print out debug information if debugging is enabled. To enable debugging # set the global variable "debug" to true value. # # Arguments: ad_debug # ad_debug() { if test x$debug = xtrue; then set -f echo autodist: $1 set +f fi } # # Prints out error message and exits the script. # # Arguments: ad_fatal # ad_fatal() { set -f ad_log "error: $1" echo autodist: error: $1 set +f exit 1 } # # Prints out warning message # # Arguments: ad_warning # ad_warning() { set -f ad_log "warning: $1" echo autodist: warning: $1 set +f } # # Opens a log file. # # Arguments: ad_log_open # ad_log_open() { rm -rf $1 exec 5> $1 cat >&5 << EOF This file contains messages produced by the Autodist $ver. EOF } # # Prints to an open log file # # Arguments: ad_log # ad_log() { if test x$nolog = xfalse; then echo "$1" >&5 fi } # # Initializes the Autodist environment, creates default distribution # directory, and default distribution. # # Arguments: ad_initialize # ad_initialize() { ad_debug "Initializing Autodist environment" # Create default distdir if test '!' -f $distdir; then mkdir -p -- $distdir fi # Create Autodist configuration file if test -f @AUTODISTDIR@/autodist.conf; then cp -p @AUTODISTDIR@/autodist.conf $distdir fi # Create default distribution if test -f @AUTODISTDIR@/default; then cp -p @AUTODISTDIR@/default $distdir fi ad_debug "Autodist environment initialized" } # # Creates the distdefs header file including defined distdefs # # Arguments: ad_create_distdefs_h # ad_create_distdefs_h() { ad_debug "Creating distdef header file" fname=$DISTDEFS rm -f $fname cat > $fname <>$fname done cat >> $fname </dev/null 2>/dev/null fi if test $? != 0; then ad_fatal "aclocal failed" fi fi if test "$AUTOCONF"; then ad_debug "Running autoconf" $AUTOCONF if test $? != 0; then ad_fatal "autoconf failed" fi run_autoconf=true fi if test "$AUTOHEADER"; then ad_debug "Running autoheader" $AUTOHEADER if test $? != 0; then ad_fatal "autoheader failed" fi fi if test "$LIBTOOLIZE"; then ad_debug "Running libtoolize" $LIBTOOLIZE if test $? != 0; then ad_fatal "libtoolize failed" fi fi if test x$run_autoconf = xtrue; then if test '!' -f configure; then ad_fatal "creating configure script failed" fi fi ad_debug "Ending configure creation" } # # Creates the configure.ac script from the configure.ad fragments in # the source tree. Takes the source configure file as argument which # is used to create the actual configure.ac. # # Arguments: ad_make_configure_ac # ad_make_configure_ac() { local check ad_debug "Starting creating configure.ac: $1" ad_log "" ad_log "Following configure.ad files were processed into configure.ac:" ad_log "--------------------------------------------------------------" if test '!' -f $1; then ad_fatal "The configure file '$1' does not exist" fi check="`sed 's/^[ ]*//' < $1 | grep -v "^#" | grep -e "AD_INIT"`" if test -z $check; then rm -f configure.ad.cfs rm -f $fname $fname.tmp ad_fatal "The 'AD_INIT' macro has not been set in configure.ac" fi rm -f configure.ac configure.ad.cfs cfs=`find . -type f -name configure\*\.ad` for i in $cfs do if test "x$i" = "x$1"; then continue fi ad_debug "including $i" ad_log " $i" cat $i >> configure.ad.cfs done if test -f configure.ad.cfs; then check="`sed 's/^[ ]*//' < $1 | grep -v "^#" | grep -e "AD_INCLUDE_CONFIGURE"`" if test -z $check; then rm -f configure.ad.cfs ad_warning "configure.ad fragments found but 'AD_INCLUDE_CONFIGURE' is not set" fi fi # Header for configure.ac fname="configure.tmp.ac" cat > $fname < $fname.tmp sed -e "/^AD_INCLUDE_CONFIGURE/d" $fname.tmp >> $fname rm -f configure.ad.cfs $fname.tmp else cat $1 >> $fname fi # Process AD_INIT sed -e "/AD_INIT/s//AC_INIT([$distribution], [$dist_version], [$bug_report], [$package])/" $fname > $fname.tmp # Remove AD_DISABLE_DEPENDENCIES sed -e "/^AD_DISABLE_DEPENDENCIES/d" $fname.tmp > $fname # Process for distribution rm -f $fname.tmp ad_process_file $fname $fname.tmp false # Remove any trailing backslashes if test -f "$fname.tmp"; then sed -e :a -e '/\\$/N; s/[ ]*\\\n//; ta' < $fname.tmp > configure.ac else cp -p $fname configure.ac fi rm -f $fname $fname.tmp ad_log " ./configure.ad" ad_log "" ad_debug "Ending creating configure.ac: $1" } # # Creates the Makefile.in files by running the automake tool. # # Arguments: ad_make_makefile_ins # ad_make_makefile_ins() { ad_debug "Starting creating Makefile.in files" if test "$AUTOMAKE"; then ad_debug "Running automake" $AUTOMAKE if test $? != 0; then ad_fatal "automake failed" fi fi ad_debug "Ending creating Makefile.in files" } # # Creates the Makefile.am files from the Makefile.ad files in the # source tree. This runs the distribution specific processing for the # Makefile.ad files. # # Arguments: ad_make_makefile_ams # ad_make_makefile_ams() { ad_debug "Starting creating Makefile.am files" ad_log "" ad_log "Following Makefile.ad files were processed into Makefile.am files:" ad_log "------------------------------------------------------------------" files=`find . -type f -name Makefile\.ad` for ff in $files do ad_log " $ff" fname=`echo $ff | sed s/\.ad//` ad_make_makefile_am $ff $fname.am done ad_log "" ad_debug "Ending creating Makefile.am files" } # # Creates Makefile.am file from the Makefile.ad file. # # Arguments: ad_make_makefile_am # ad_make_makefile_am() { local am_deps=true local f=$1 local fname=$2 # Disable dependencies if requested dc=`sed 's/^[ ]*//' < configure.ad | grep -v "^#" \ | grep "AD_DISABLE_DEPENDENCIES"` if test "$dc" = "AD_DISABLE_DEPENDENCIES"; then am_deps=false fi # Header for the Makefile.am cat > $fname <> $fname else cat $f >> $fname fi # Enable dependencies if requested if test x$am_deps = xtrue; then # Get list of configure.ad's to get them into deps also cfs=`find . -type f -name configure\*\.ad` cfs=`echo $cfs | sed 's/\.\///g'` cat >> $fname < $fname else cp -p $orig $fname || exit 1 fi rm -f $fname.tmp done ad_log "" ad_debug "Ending processing .ad files" } # # Includes files specified in the distribution for inclusion. Used when # creating the distribution for packaging. # # include has the following format in distfile: # # include [] # # If only source path, which may be file, directory or regular expression, # is specified the path will be same in distribution. If the destination # path is specified that will be the new name and/or new location of the # source path. This, in effect, is a cp utility with ability to create # directories if they do not exist. # # Arguments: ad_dist_includes # ad_dist_includes() { local incs ad_debug "Starting running includes: $1 $2" if test x$3 = xtrue; then ad_log "" ad_log "Following files and directories were included in distribution:" ad_log "--------------------------------------------------------------" fi # By default do not expand pathnames set -f # Add : separator at the end incs="`echo "$1" | sed 's/$/ : /'`" src= dst= for i in $incs do if test "$i" = ":" && test -z "$src"; then continue fi if test -z "$src"; then src=$i continue fi if test -z "$dst" && test "$i" != ":"; then dst=$i else dst=$src fi ad_debug "Including $src into $dst" if test -f "$src"; then # Add file if test "$src" = "$dst"; then # Add to same location d=`echo $src | sed 's,/[^/]*$,,'` if test "$d" != "$src" && test "$d" != "." && \ test '!' -d $am_distdir/$d; then mkdir -p -- $am_distdir/$d || exit 1 fi else # Add to different location check=`echo "$dst" | sed 's/?//; s/*//; s/\[//; s/\]//'` if test "$check" != "$dst"; then ad_fatal "Invalid destination in 'include $src $dst'" fi d=`echo $dst | sed 's,/[^/]*$,,'` if test "$d" != "$dst" && test "$d" != "." && \ test '!' -d $am_distdir/$d; then mkdir -p -- $am_distdir/$d || exit 1 fi fi if test x$3 = xtrue; then ad_log " $src into $am_distdir/$d" fi cp -p $src $am_distdir/$d || exit 1 elif test -d "$src"; then # Add directory if test "$src" = "$dst"; then # Add to same location d=`echo $src | sed 's,/[^/]*$,,'` ds=`echo $src | sed 's/\/$//'` if test "$ds" = "$d"; then d=`echo $d | sed 's,/[^/]*$,,'` fi if test "$ds" = "$d"; then d="" fi if test '!' -d $am_distdir/$d && test "$ds" != "$d"; then mkdir -p -- $am_distdir/$d || exit 1 fi if test x$3 = xtrue; then ad_log " $src into $am_distdir/$d" fi cp -pR $src $am_distdir/$d || exit 1 else # Add to different location check=`echo "$dst" | sed 's/?//; s/*//; s/\[//; s/\]//'` if test "$check" != "$dst"; then ad_fatal "Invalid destination in 'include $src $dst'" fi d=`echo $dst | sed 's,/[^/]*$,,'` ds=`echo $dst | sed 's/\/$//'` if test "$ds" = "$d"; then d=`echo $d | sed 's,/[^/]*$,,'` fi if test '!' -d $am_distdir/$d && test "$dst" != "$d"; then mkdir -p -- $am_distdir/$d || exit 1 fi if test x$3 = xtrue; then ad_log " $src into $am_distdir/$dst" fi cp -pR $src $am_distdir/$dst || exit 1 fi elif test x$2 != xtrue; then # We assume regular expression in filename check=`echo "$src" | sed 's/?//; s/*//; s/\[//; s/\]//'` if test "$check" == "$src"; then if test '!' -a $src; then ad_fatal "Including $src: No such file or directory" fi src= dst= continue fi # Recursively call this function with expanded pathnames. The # reason why we don't let sh by default expand pathnames is that # the include's destination is optional. If sh expands by default # we don't know the destination. For this reason, we handle the # expansion here ourselves. # If src and dst are same, then expand the pathname as we'll copy # matches to their own locations. if test "$src" = "$dst"; then # Expand pathnames, and format to our include format set +f srcs=`echo $src | sed -e 's/ / : /g' -e 's/^/ : /'` || exit 1 set -f else # Destination is new, and it has to be a directory. check=`echo "$dst" | sed 's/?//; s/*//; s/\[//; s/\]//'` if test "$check" != "$dst"; then ad_fatal "Invalid destination in 'include $src $dst'" fi # Make sure dst has / at the end, as this must be a directory dst=`echo $dst | sed 's/\/$//; s/$/\//'` # Escape dst for sed dste=`echo $dst | sed 's/\\//\\\\\//g'` || exit 1 # Expand pathnames, and format to our include format set +f srcs=`echo $src | sed -e "s/ / $dste : /g" \ -e 's/^/ : /' -e "s/$/ $dste/"` || exit 1 set -f fi # Include recursively ad_dist_includes "$srcs" true elif test '!' -a $src; then ad_fatal "Including $src: No such file or directory" fi src= dst= done if test x$3 = xtrue; then ad_log "" fi set +f ad_debug "Ending running includes: $1 $2" } # # Excludes files specified in the distribution for exclusion. Used when # creating the distribution for packaging. # # exclude has the following format in distfile: # # exclude # # The path may be file, directory or regular expression. # # Arguments: ad_dist_includes # ad_dist_excludes() { ad_debug "Starting running excludes: $1" if test x$2 = xtrue; then ad_log "" ad_log "Following files and directories were excluded from distribution:" ad_log "----------------------------------------------------------------" fi cur=`pwd` cd $am_distdir || exit 1 for i in $1 do ad_debug "Excluding $i" if test x$2 = xtrue; then ad_log " $i" fi rm -rf $i done cd $cur || exit 1 if test x$2 = xtrue; then ad_log "" fi ad_debug "Ending running excludes: $1" } # # Processes the entire tree for distribution. This inspects files other # than source and header files, with exception of any file with .ad # suffix, and performs distribution processing for the file. The original # file is replaced with the processed file. This function is used when # creating the distribution for packaging. # # Arguments: ad_process_tree # ad_process_tree() { ad_debug "Starting processing non-source files: $1" # Take files, except source and .ad files. files=`find $am_distdir -type f \! -name \*\.ad \( \ \! -name \*\.[cC] -a \ \! -name \*\.[cC][cCpP] -a \ \! -name \*\.[cC][xX][xX] -a \ \! -name \*\.[cC][pP][pP] -a \ \! -name \*\.[cC]++ -a \ \! -name \*\.m -a \ \! -name \*\.mm -o \ \! -name \*\.M -o \ \! -name \*\.S -o \ \! -name \*\.[hH] -a \ \! -name \*\.hh -a \ \! -name \*\.[cC]\.in -a \ \! -name \*\.[cC][cCpP]\.in -a \ \! -name \*\.[cC][xX][xX]\.in -a \ \! -name \*\.[cC][pP][pP]\.in -a \ \! -name \*\.[cC]++\.in -a \ \! -name \*\.m\.in -a \ \! -name \*\.[hH]\.in -a \ \! -name \*\.hh\.in \)` files=`echo $files | sed 's/$am_distdir//'` for ff in $files do ad_process_file $ff $ff.tmp true if test -f $ff.tmp; then rm -f $ff || exit 1 mv -f $ff.tmp $ff || exit 1 fi done ad_debug "Ending processing non-source files: $1" } # # Processes the entire source tree for distribution. This inspects files # in the source tree, with exception of any file with .ad suffix, and # performs distribution processing for the file. The original file is # replaced with the processed file. This function is used when creating # the distribution for packaging. # # Call this before ad_process_tree(). # # Arguments: ad_process_source_tree # ad_process_source_tree() { ad_debug "Starting processing source files: $1" # We take only C/C++ (and other files that are run through traditional # preprocessor) files since they use the C compiler friendly version # of distdefs. Other files are not assumed to use them. files=`find $am_distdir -type f \! -name \*\.ad \( \ -name \*\.[cC] -o \ -name \*\.[cC][cCpP] -o \ -name \*\.[cC][xX][xX] -o \ -name \*\.[cC][pP][pP] -o \ -name \*\.[cC]++ -o \ -name \*\.m -o \ -name \*\.mm -o \ -name \*\.M -o \ -name \*\.S -o \ -name \*\.[hH] -o \ -name \*\.hh -o \ -name \*\.[cC]\.in -o \ -name \*\.[cC][cCpP]\.in -o \ -name \*\.[cC][xX][xX]\.in -o \ -name \*\.[cC][pP][pP]\.in -o \ -name \*\.[cC]++\.in -o \ -name \*\.m\.in -o \ -name \*\.[hH]\.in -o \ -name \*\.hh\.in \)` for ff in $files do ad_process_source_file $ff $ff.tmp true if test -f $ff.tmp; then rm -f $ff || exit 1 mv -f $ff.tmp $ff || exit 1 fi done ad_debug "Ending processing source files: $1" } # # Removes Autodist dependencies, as they cannot be delivered to distribution. # # Arguments: ad_remove_dependencies # ad_remove_dependencies() { ad_debug "Removing dependencies" ams=`find $1 -type f -name Makefile\.\*` for i in $ams do sed -e "/^# S_AD_ENABLE_DEPENDENCIES/,/^# E_AD_ENABLE_DEPENDENCIES/d" $i > $i.tmp mv $i.tmp $i done } # # Makes distribution sane, ala modtimes. Since we modify the distribution # we need to make it sane after that. # # Arguments: ad_makedist_makesane # ad_makedist_makesane() { ad_debug "Making distribution file modtimes sane" # DO NOT change these order unless you know what you are doing. if test -f $am_distdir/configure.ac; then touch $am_distdir/configure.ac fi if test -f $am_distdir/aclocal.m4; then touch $am_distdir/aclocal.m4 fi if test '!' -f Makefile; then ad_fatal "Makefile: No such file or directory" fi configh=`grep "^CONFIG_HEADER" Makefile | cut -d= -f2 | sed 's/^[ ]*//'` touch $am_distdir/$configh.in 1>/dev/null 2>/dev/null files=`find $am_distdir -type f -name Makefile\.in` for i in $files do touch $i done if test -f $am_distdir/configure; then touch $am_distdir/configure fi if test -f $am_distdir/config.status; then touch $am_distdir/config.status fi ad_debug "Distribution made sane" } # # Creates distribution of the source tree. All files in the distribution # will be processed and the distribution will be packaged. # # Arguments: ad_makedist # ad_makedist() { ad_log_open "makedist.log" ad_debug "Starting distribution creation" ad_log "Created distribution" ad_log "--------------------" ad_log "" if test '!' -f autodist.dist; then ad_fatal "Autodist has not been run yet to prepare source tree" fi if test -z $MAKE; then ad_fatal "The MAKE variable is not set in autodist.conf" fi # Get distdir from Makefile if test '!' -f Makefile; then ad_fatal "The source tree is not configured, run ./configure first" fi # Parse the requested distribution distribution=`grep "dist:" < autodist.dist | cut -d: -f2` || exit 1 dist_version=`grep "ver:" < autodist.dist | cut -d: -f2` || exit 1 am_distdir=`grep "distdir:" < autodist.dist | cut -d: -f2` || exit 1 params=`grep "params:" < autodist.dist | cut -d: -f2` || exit 1 ad_parse_distribution $distribution false ad_log " Distribution: $distribution $dist_version" ad_log " Destination directory: $am_distdir" ad_log "" ad_process_distdefs if test x$opt_no_dist = xtrue; then ad_fatal "The '$distribution' distribution cannot be packaged" fi # Run pre-dist-hooks ad_run_dist_hooks "$pre_dist_hooks" "$params" # Create distribution directory ad_debug "Creating distribution directory $am_distdir" $MAKE distdir || exit 1 chmod -R a+r $am_distdir if test '!' -d $am_distdir; then ad_fatal "Distribution directory $am_distdir not created" fi # Run pre-process-dist-hooks ad_run_dist_hooks "$pre_p_dist_hooks" "$params" # Run excludes ad_dist_excludes "$excludes" true # Run includes ad_dist_includes "$includes" false true # Include specific license file if specified if test "$license" != ""; then ad_log "" ad_log "License file in distribution:" ad_log "-----------------------------" ad_log " $license into $am_distdir/COPYING" ad_log "" cp -p $license $am_distdir/COPYING || exit 1 fi # Remove dependencies ad_remove_dependencies $am_distdir # Process noprocesses, first pass ad_process_noprocess true ad_log "" ad_log "Following files were not re-licensed:" ad_log "-------------------------------------" # Process source files ad_debug "Process distribution source tree" ad_process_source_tree $am_distdir # Process non-source files ad_debug "Process distribution tree" ad_process_tree $am_distdir ad_log "" # Process noprocesses, second pass ad_process_noprocess false # Run post-process_dist-hooks ad_run_dist_hooks "$post_p_dist_hooks" "$params" # Make distribution sane ad_makedist_makesane # Package ad_debug "Packaging distribution" tar chof $am_distdir.tar $am_distdir || exit 1 # Compress ad_debug "Compressing distribution package" if test x$ad_gzip = xtrue; then ad_debug "Compressing distribution package $am_distdir.tar.gz" gzip -9 -c $am_distdir.tar > $am_distdir.tar.gz || exit 1 fi if test x$ad_bzip2 = xtrue; then ad_debug "Compressing distribution package $am_distdir.tar.bz2" bzip2 -9 -c $am_distdir.tar > $am_distdir.tar.bz2 || exit 1 fi if test x$ad_compress = xtrue; then ad_debug "Compressing distribution package $am_distdir.tar.Z" compress -c $am_distdir.tar > $am_distdir.tar.Z || exit 1 fi if test x$ad_zip = xtrue; then rm -f $am_distdir.zip ad_debug "Compressing distribution package $am_distdir.zip" zip -rq $am_distdir.zip $am_distdir || exit 1 fi rm -f $am_distdir.tar # Run post-dist-hooks ad_run_dist_hooks "$post_dist_hooks" "$params" # Cleanup rm -rf $am_distdir ad_log "Distribution created successfully." ad_debug "Ending distribution creation" } # # Handles distribution options. # # option has the following format in distfile: # # option