# Auxiliary functions for build.sh # Copyright (c) 2002 Serge van den Boom # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Show usage information usage() { echo "Main build script" echo echo "Syntax:" echo " ./build.sh " echo " ./build.sh config" echo " ./build.sh depend" echo " ./build.sh clean" echo " ./build.sh install" echo " ./build.sh cleanall" echo " ./build.sh distclean" echo echo "Valid targets:" for TARGET in $TARGETS; do echo " $TARGET" done echo } escape_string() { $SED -e s,[\\\'\"\`\ \ \$\&\\\*\\\?\#\!],\\\\\&,g << EOF $1 EOF } # The actual recursing function build_recurse() { local FILES SUBDIRS # Perform an action for this dir eval FILES="\${$BUILD_FILES_VAR}" for FILE in $FILES; do $BUILD_REC_COMMAND "$BUILD_REC_PATH$FILE" done # Recurse for all subdirs eval SUBDIRS="\$${BUILD_PROJECT}_SUBDIRS" for DIR in $SUBDIRS; do BUILD_REC_PATH="$BUILD_REC_PATH$DIR/" $SH "$0" $BUILD_REC_DIR_COMMAND "$BUILD_REC_PATH$DIR" done } # Start the recursion build_do_recursive() { BUILD_COMMAND=build_recurse BUILD_REC_COMMAND="$1" BUILD_REC_DIR_COMMAND="$2" export BUILD_COMMAND BUILD_REC_COMMAND BUILD_REC_DIR_COMMAND build_recurse } # Build dependency information for one file build_dependencies() { eval $ECHON \$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}\$BUILD_REC_PATH eval eval \\\$MKDEPEND \"\${${BUILD_PROJECT}_CFLAGS}\" \"\\\$1\" | \ grep -v '#' } # Recursively build dependency information build_rec_dependencies() { local DEPEND_FILE EXTRA_OFILES echo "Building dependency information..." >&2 BUILD_WORK_ESC=`escape_string "$BUILD_WORK"` export BUILD_WORK_ESC eval mkdir -p "\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}" eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}.depend" # Remove the old dependency file, if it exists. # The .tmp file is used to detect interrupted dependency builds. rm -f -- "$DEPEND_FILE".tmp "$DEPEND_FILE" BUILD_FILES_VAR=${BUILD_PROJECT}_EXTRA_OFILES export BUILD_FILES_VAR EXTRA_OFILES=`build_do_recursive build_collect_extra_o_files :` BUILD_FILES_VAR=${BUILD_PROJECT}_CFILES OFILES=`build_do_recursive build_collect_o_files :` { eval $ECHON "\$BUILD_WORK_ESC/target-\${${BUILD_PROJECT}_NAME}:" for OFILE in $OFILES $EXTRA_OFILES; do $ECHON " $OFILE" done echo build_do_recursive build_dependencies : } > "$DEPEND_FILE".tmp mv -f -- "$DEPEND_FILE".tmp "$DEPEND_FILE" } # Output the .o file for a given .c or .m (Objective-C) file build_collect_o_files() { eval echo "\$BUILD_WORK_ESC/\${${BUILD_PROJECT}_OBJS}\${1%.[cm]}.o" } # Output the extra .o file with the complete path build_collect_extra_o_files() { eval echo "\$BUILD_WORK_ESC/\${${BUILD_PROJECT}_OBJS}\$1" } # Recursively collect .o-files build_rec_collect_o_files() { local EXTRA_OFILES BUILD_WORK_ESC=`escape_string "$BUILD_WORK"` export BUILD_WORK_ESC BUILD_FILES_VAR=${BUILD_PROJECT}_CFILES export BUILD_FILES_VAR build_do_recursive build_collect_o_files : BUILD_FILES_VAR=${BUILD_PROJECT}_EXTRA_OFILES build_do_recursive build_collect_extra_o_files : } # Start the configure program. # $1 = target build_config() { prepare_build_system config_requirements prepare_host_system if [ "$BUILD_SYSTEM" '!=' "$HOST_SYSTEM" ]; then build_message "Cross-compiling to $HOST_SYSTEM." fi eval "${TARGET}_requirements" eval "${TARGET}_prepare_config" eval "${TARGET}_load_config" eval "${TARGET}_do_config" eval "${TARGET}_save_config" } build_reconfig() { if [ ! -e "$BUILD_WORK/config.state" ]; then echo "*** Warning: file 'config.state' not found - using defaults." fi prepare_build_system config_requirements prepare_host_system if [ "$BUILD_SYSTEM" '!=' "$HOST_SYSTEM" ]; then build_message "Cross-compiling to $HOST_SYSTEM." fi eval "${TARGET}_requirements" eval "${TARGET}_prepare_config" eval "${TARGET}_load_config" build_process_config echo "Reconfiguring complete..." >&2 } # Process the configuration information build_process_config() { eval "${TARGET}_process_config" } # Compile the lot. # With the depend info set up, we can leave everything to make. build_compile() { eval "${TARGET}_pre_build" eval CFLAGS="\${${BUILD_PROJECT}_CFLAGS}" \ LDFLAGS="\${${BUILD_PROJECT}_LDFLAGS}" \ DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}.depend" \ \$MAKE -f Makefile.build \"\$BUILD_WORK/target-\${${BUILD_PROJECT}_NAME}\" eval "${TARGET}_post_build" } # Description: Remove the .o file for one .c file # Arguments: $1 - the .c file build_clean_file() { eval rm -f -- "\"\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}\${1%.c}.o\"" } build_clean_dir() { eval rmdir -- "\"\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}\${1}\"" 2> /dev/null return 0 } build_clean() { local DEPEND_FILE eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}.depend" rm -f "$DEPEND_FILE" "$BUILD_WORK/build.vars" \ "$BUILD_WORK/config.state" "$BUILD_WORK/config_unix.h" BUILD_FILES_VAR=${BUILD_PROJECT}_CFILES export BUILD_FILES_VAR build_do_recursive build_clean_file build_clean_dir } build_cleanall() { export BUILD_PROJECT for TARGET in $TARGETS; do BUILD_PROJECT="$TARGET" build_clean done BUILD_PROJECT="" } build_distclean() { build_cleanall } # Description: check if the config files are present and load them. # If they're not present, remake them. build_check_config() { if [ ! -e "$BUILD_WORK/build.vars" ]; then build_config || exit $? build_process_config fi . "$BUILD_WORK/build.vars" . "${BUILD_REC_PATH:=./}Makeinfo" } # Description: check if the necessary .depend file is present, # if not, build it. build_check_dependencies() { eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}.depend" [ ! -e "$DEPEND_FILE" -o -n "$BUILD_RUN_DEPEND" ] || return build_rec_dependencies || exit $? } # Description: check if the program is compiled, and otherwise compile build_check_compile() { local NAME eval NAME="\${${BUILD_PROJECT}_NAME}" [ ! -e "$NAME" ] || return build_compile || exit $? } # Make a directory path, with mode and owner specified. # $1 - name of directory path # $2 - mode of the directories (may be empty) # $3 - owner of the directories (may be empty) mkdirhier() { local REST DIR MODE OWNER REST="$1" MODE="$2" OWNER="$3" case "$REST" in /*) REST="${REST%/}" DIR="/" ;; *) DIR="" ;; esac case "$REST" in */) ;; *) REST="${REST}/" ;; esac while [ -n "$REST" ]; do DIR="$DIR${REST%%/*}" REST="${REST#*/}" if [ ! -d "$DIR" ]; then mkdir "$DIR" [ -n "$MODE" ] && chmod "$MODE" "$DIR" [ -n "$OWNER" ] && chown "$OWNER" "$DIR" fi DIR="${DIR}/" done } # Install a file or directory # $1 - Source file/directory # $2 - Destination directory/file # $3 - Mode of destination file/directory # $4 - Owner of destination file/directory installsome() { local SRC DEST MODE OWNDER DESTDIR SRCNAME SRC="$1" DEST="$2" MODE="$3" OWNDER="$4" DESTDIR="${DEST%/*}" if [ ! -d "$DESTDIR" ]; then mkdirhier "$DESTDIR" 0755 fi SRCNAME="${SRC##*/}" cp -pr -- "$SRC" "$DEST" if [ -n "$MODE" ]; then if [ -d "$DEST" ]; then chmod -R "$MODE" "${DEST}${SRCNAME}" else chmod "$MODE" "$DEST" fi fi if [ -n "$OWNER" ]; then if [ -d "$DEST" ]; then chown -R "$OWNER" "${DEST}${SRCNAME}" else chown "$OWNER" "$DEST" fi fi } # Install the program build_install() { eval "${TARGET}_install" } # Generic installation routine generic_install() { local SRC DEST MODE OWNER eval "${TARGET}_pre_install" local LIB LIBS LIBDIR echo "Installing system-dependent data..." >&2 eval LIBS="\${${BUILD_PROJECT}_INSTALL_LIBS}" eval LIBDIR="\${${BUILD_PROJECT}_INSTALL_LIBDIR%/}/" mkdirhier "$LIBDIR" 0755 for LIB in $LIBS; do eval SRC="\${${BUILD_PROJECT}_INSTALL_LIB_${LIB}_SRC%/}" eval DEST="\$LIBDIR\${${BUILD_PROJECT}_INSTALL_LIB_${LIB}_DEST}" eval MODE="\${${BUILD_PROJECT}_INSTALL_LIB_${LIB}_MODE}" eval OWNER="\${${BUILD_PROJECT}_INSTALL_LIB_${LIB}_OWNER}" installsome "$SRC" "$DEST" "$MODE" "$OWNER" done local SHARE SHARED SHAREDIR echo "Installing system-independent data..." >&2 eval SHARED="\${${BUILD_PROJECT}_INSTALL_SHARED}" eval SHAREDIR="\${${BUILD_PROJECT}_INSTALL_SHAREDIR%/}/" mkdirhier "$SHAREDIR" 0755 for SHARE in $SHARED; do eval SRC="\${${BUILD_PROJECT}_INSTALL_SHARED_${SHARE}_SRC%/}" eval DEST="\$SHAREDIR\${${BUILD_PROJECT}_INSTALL_SHARED_${SHARE}_DEST}" eval MODE="\${${BUILD_PROJECT}_INSTALL_SHARED_${SHARE}_MODE}" eval OWNER="\${${BUILD_PROJECT}_INSTALL_SHARED_${SHARE}_OWNER}" installsome "$SRC" "$DEST" "$MODE" "$OWNER" done local BINS BINDIR echo "Installing binaries..." >&2 eval BINS="\${${BUILD_PROJECT}_INSTALL_BINS}" eval BINDIR="\${${BUILD_PROJECT}_INSTALL_BINDIR%/}/" mkdirhier "$BINDIR" 0755 for BIN in $BINS; do eval SRC="\${${BUILD_PROJECT}_INSTALL_BIN_${BIN}_SRC%/}" eval DEST="\$BINDIR\${${BUILD_PROJECT}_INSTALL_BIN_${BIN}_DEST}" eval MODE="\${${BUILD_PROJECT}_INSTALL_BIN_${BIN}_MODE}" eval OWNER="\${${BUILD_PROJECT}_INSTALL_BIN_${BIN}_OWNER}" installsome "$SRC" "$DEST" "$MODE" "$OWNER" done eval "${TARGET}_post_install" }