build.in 5.99 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
#!/bin/bash
# top-level build script for LALSuite

# autoconf variables
MKDIR_P="@MKDIR_P@"
builddir="@abs_builddir@"
configure_args="@configure_args@"
prefix="@prefix@"
srcdir="@abs_srcdir@"
subdirs="@subdirs@"

# function to print a message
msg () {
  echo "$0: $1"
}

# function to print an error message and exit
fail () {
  echo "!!! $0: $1" >&2
  exit 1
}

# function to clean up files if a command fails or is interrupted
cleanup() {
    [ -n "${cleanup_files}" ] && rm -rf ${cleanup_files}
}
cleanup_files=""
trap cleanup 1 2 13 15

# function to run a command, or print an error message
run() {
Karl Wette's avatar
Karl Wette committed
32
    msg "running (cd ${PWD} && $1)"
33
    eval "( $1 ) ${mute_redirect}" || { cleanup; fail "(cd ${PWD} && $1) failed"; }
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
}

# function to check whether $1 is out of date relative to $2
outofdate() {
    [ -f "$2" ] || fail "missing $2, required for building $1"
    [ "$2" -nt "$1" ]
}

# function to remove duplicates from a list of words in variable $1
uniquify() {
    local uniq arg
    for arg in ${!1}; do
        case " ${uniq} " in
            (*${arg}*)
                ;;
            (*)
                uniq="${uniq} ${arg}"
                ;;
        esac
    done
    eval "$1='${uniq}'"
}

# parse command line
make_cmd="${MAKE-make}"
mute_redirect=""
any_targets=no
make_targets=""
make_clean_targets=""
for arg in "$@"; do
    case ${arg} in

        # print help
        (-h|--help)
            cat <<EOF

$0: top-level build script for LALSuite

Usage:
   $0 [--mute] [make-options...] [make-targets...]

Options:
   --mute           only print error messages from build processes
   make-options     options for make, e.g. -j<jobs>, -k, V=1, etc.
   make-targets     targets for make, e.g. all, check, distcheck, clean, etc.

EOF
            exit 1
            ;;

        # only print error messages from build processes
        (--mute)
            mute_redirect=">/dev/null"
            ;;

        # pass all options and variable definitions to make
        (-*|*=*)
            make_cmd="${make_cmd} ${arg}"
            ;;

        # pass any argument beginning with a digit to make
        ([0-9]*)
            make_cmd="${make_cmd} ${arg}"
            ;;

        # save list of make clean targets
        (*clean*)
            any_targets=yes
            make_clean_targets="${make_clean_targets} ${arg}"
            ;;

        # save list of other make targets
        (*)
            any_targets=yes
            make_targets="${make_targets} ${arg}"
            ;;

    esac
done

# if no targets were given, use 'all'
if [ ${any_targets} = no ]; then
    make_targets="all"
fi

# always add 'all' and 'install' as make targets
if [ -n "${make_targets}" ]; then
    make_targets="all ${make_targets} install"
fi

# remove duplicates from lists of make targets
uniquify make_targets
uniquify make_clean_targets

# save current directory
oldpwd="${PWD}"

# change to top-level build directory
cd "${builddir}"

# rebuild top-level ./configure, if out of date
if outofdate "${srcdir}/configure" "${srcdir}/configure.ac"; then
    run "cd ${srcdir} && ./00boot"
fi

# rebuild top-level ./config.status, if out of date
if outofdate "./config.status" "${srcdir}/configure"; then
    run "./config.status --recheck"
fi

# rebuild ./build and reload this script, if out of date
if outofdate "./build" "${srcdir}/build.in" || outofdate "./build" "./config.status"; then
    run "./config.status"
    msg "reloading ..."
    cd "${oldpwd}"
    exec "${SHELL}" "$0" "$@"
fi

# build make targets in subdirectories
if [ -n "${make_targets}" ]; then
    for subdir in ${subdirs}; do

        # build and source subdirectories
        buildsubdir="${builddir}/${subdir}"
        srcsubdir="${srcdir}/${subdir}"

        # create build subdirectory, if it does not exist
        if [ ! -d "${buildsubdir}" ]; then
            run "${MKDIR_P} ${buildsubdir}"
        fi

        # change to build subdirectory
        cd "${buildsubdir}"

        # rebuild subdirectory ./configure, if out of date
        if outofdate "${srcsubdir}/configure" "${srcsubdir}/configure.ac"; then
            run "cd ${srcsubdir} && ./00boot"
        fi

        # rebuild subdirectory ./config.status, if out of date
        if outofdate "./config.status" "${srcsubdir}/configure"; then
            cleanup_files="${buildsubdir}/config.status"
            run "${srcsubdir}/configure --disable-option-checking ${configure_args}"
            cleanup_files=""
        fi

        # build each target
        for target in ${make_targets}; do
            run "${make_cmd} ${target}"
        done

        # change to top-level build directory
        cd "${builddir}"

        # source environment script for this subdirectory, if it exists
        userenv="${prefix}/etc/${subdir}-user-env.sh"
        if [ -f "${userenv}" ]; then
            msg "sourcing ${userenv}"
            source "${userenv}"
        fi

    done
fi

# perform top-level tasks for specific targets
for target in ${make_targets}; do
    case ${target} in

        # make top-level tags file
        (tags)
            msg "generating ${builddir}/TAGS"
            rm -f "${builddir}/TAGS"
            for subdir in ${subdirs}; do
                buildsubdir="${builddir}/${subdir}"
                if [ -f "${buildsubdir}/TAGS" ]; then
                    cat "${buildsubdir}/TAGS" >> "${builddir}/TAGS"
                fi
            done
            ;;

    esac
done

# reverse list of subdirectories
reverse_subdirs=""
for subdir in ${subdirs}; do
    reverse_subdirs="${subdir} ${reverse_subdirs}"
done

# iterate over subdirectories and make clean targets
if [ -n "${make_clean_targets}" ]; then
    for subdir in ${reverse_subdirs}; do

        # build and source subdirectories
        buildsubdir="${builddir}/${subdir}"
        srcsubdir="${srcdir}/${subdir}"

        # change to build subdirectory
        cd "${buildsubdir}"

        # build each clean target
        for target in ${make_clean_targets}; do
            run "${make_cmd} ${target}"
        done

        # change to top-level build directory
        cd "${builddir}"

    done
fi