296 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			7.3 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
#!/bin/bash
 | 
						|
# fir-tools/make.sh
 | 
						|
# 
 | 
						|
#  Copyright: ©2014, Laurence Withers
 | 
						|
#  Author: Laurence Withers <l@lwithers.me.uk>
 | 
						|
#  License: GPLv3
 | 
						|
#
 | 
						|
 | 
						|
 | 
						|
# This file is the script used to build fir-tools. There are some
 | 
						|
# options that can be edited; these are set in the file 'config' (or you
 | 
						|
# can pass them in as environment variables).
 | 
						|
if [ ! -e "config" ]
 | 
						|
then
 | 
						|
    echo "Configuration file not found???"
 | 
						|
    exit 1
 | 
						|
fi
 | 
						|
source "./config" # don't fail on error, since last command in config might return false
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# Get version information
 | 
						|
source "./version" || exit 1
 | 
						|
VERSION="${VERMAJOR}.${VERMINOR}.${VERMICRO}"
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# Get standard functions
 | 
						|
[ -z "${VERBOSE}" ] && VERBOSE="0"
 | 
						|
source "./scripts/functions.sh" || exit 1
 | 
						|
 | 
						|
 | 
						|
# List of directories which will be emptied by clean.
 | 
						|
OUTPUT_DIRS="obj html"
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# This function makes a monolithic file out of several source files. Its
 | 
						|
# first argument is the name of the output file, and the second is the
 | 
						|
# format of monolithic file to create (for example, "C" will cause the
 | 
						|
# inclusion of "#line" directives at the top of each included file).
 | 
						|
#
 | 
						|
# It also examines the following variables:
 | 
						|
#  MONOLITHIC_TESTS       if any file mentioned in this list is newer
 | 
						|
#                         than the output file, then we recreate it
 | 
						|
#  MONOLITHIC_SOURCE      a list (in order) of the source files
 | 
						|
#  MONOLITHIC_OPTIONS     will #define the options to match the respective
 | 
						|
#                         environment variables.
 | 
						|
#
 | 
						|
# Recognised formats are:
 | 
						|
#  none                   no special processing happens before each file
 | 
						|
#  C                      #line directives are inserted before each file
 | 
						|
#                         and VERSION, VERMAJOR etc. are #defined
 | 
						|
#  Ch                     Like C, but for header files (no VERSION #defines)
 | 
						|
#
 | 
						|
make_monolithic() {
 | 
						|
    if [ $# -ne 2 ]
 | 
						|
    then
 | 
						|
        print_failure "make_monolithic() called with wrong number of arguments"
 | 
						|
        print_failure "(expecting 2, got $#)"
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    MONOLITHIC_OUT=$1
 | 
						|
    
 | 
						|
    # extract options
 | 
						|
    HASHLINE=0
 | 
						|
    VERDEFINE=0
 | 
						|
    HASHDEFINE=0
 | 
						|
    if [ "$2" == "C" ]
 | 
						|
    then
 | 
						|
        HASHLINE=1
 | 
						|
        VERDEFINE=1
 | 
						|
        HASHDEFINE=1
 | 
						|
    elif [ "$2" == "Ch" ]
 | 
						|
    then
 | 
						|
        HASHLINE=1
 | 
						|
        HASHDEFINE=1
 | 
						|
    elif [ "$2" == "none" ]
 | 
						|
    then
 | 
						|
        HASHLINE=0 # dummy command
 | 
						|
    else
 | 
						|
        print_failure "make_monolithic() called with unknown format $2"
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    echo " Building monolithic file '${MONOLITHIC_OUT}'..."
 | 
						|
 | 
						|
    MODIFIED=0
 | 
						|
    for FILE in ${MONOLITHIC_TESTS} ${MONOLITHIC_SOURCE}
 | 
						|
    do
 | 
						|
        if [ ! -e "${FILE}" ]
 | 
						|
        then
 | 
						|
            print_failure "'${FILE}' does not exist"
 | 
						|
            return 1
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ "${FILE}" -nt ${MONOLITHIC_OUT} ]
 | 
						|
        then
 | 
						|
            MODIFIED=1
 | 
						|
            break
 | 
						|
        fi
 | 
						|
    done
 | 
						|
 | 
						|
    if [ ${MODIFIED} -ne 0 ]
 | 
						|
    then
 | 
						|
        do_cmd mkdir -p $(dirname ${MONOLITHIC_OUT})
 | 
						|
        do_cmd rm -f ${MONOLITHIC_OUT} || exit 1
 | 
						|
        
 | 
						|
        if [ ${VERDEFINE} -ne 0 ]
 | 
						|
        then
 | 
						|
            do_cmd_redir ${MONOLITHIC_OUT} echo "#define VERSION \"${VERSION}\"" || return 1
 | 
						|
            do_cmd_redir ${MONOLITHIC_OUT} echo "#define VERMAJOR ${VERMAJOR}" || return 1
 | 
						|
            do_cmd_redir ${MONOLITHIC_OUT} echo "#define VERMINOR ${VERMINOR}" || return 1
 | 
						|
            do_cmd_redir ${MONOLITHIC_OUT} echo "#define VERMICRO ${VERMICRO}" || return 1
 | 
						|
            do_cmd_redir ${MONOLITHIC_OUT} echo "#define VEREXTRA \"${VEREXTRA}\"" || return 1
 | 
						|
        fi
 | 
						|
 | 
						|
        if [ ${HASHDEFINE} -ne 0 ]
 | 
						|
        then
 | 
						|
            for opt in ${MONOLITHIC_OPTIONS}
 | 
						|
            do
 | 
						|
                do_cmd_redir ${MONOLITHIC_OUT} echo "#define ${opt} ${!opt}" || return 1
 | 
						|
            done
 | 
						|
        fi
 | 
						|
 | 
						|
        for FILE in ${MONOLITHIC_SOURCE}
 | 
						|
        do
 | 
						|
            if [ ${HASHLINE} -ne 0 ]
 | 
						|
            then
 | 
						|
                do_cmd_redir ${MONOLITHIC_OUT} echo "#line 1 \"${FILE}\"" || return 1
 | 
						|
            fi
 | 
						|
            do_cmd_redir ${MONOLITHIC_OUT} cat "${FILE}" || return 1
 | 
						|
        done
 | 
						|
        print_success "Done"
 | 
						|
    else
 | 
						|
        print_success "Up to date"
 | 
						|
    fi
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# This will build a directory tree, if required, with mode 0755. The
 | 
						|
# argument is the directory to build.
 | 
						|
build_dir_tree() {
 | 
						|
    # sanity check
 | 
						|
    if [ $# -ne 1 ]
 | 
						|
    then
 | 
						|
        print_failure "build_dir_tree() called with wrong number of arguments"
 | 
						|
        print_failure "(expecting 1, got $#)"
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    build_dir_tree_recurse "${INSTALL_PREFIX}$1"
 | 
						|
}
 | 
						|
 | 
						|
build_dir_tree_recurse() {
 | 
						|
    local DIR="$1"
 | 
						|
 | 
						|
    # if the directory already exists, return success
 | 
						|
    [ -d "${DIR}" ] && return 0
 | 
						|
 | 
						|
    # if something with this name already exists, but not a directory,
 | 
						|
    # then fail
 | 
						|
    if [ -e "${DIR}" ]
 | 
						|
    then
 | 
						|
        print_failure "Failed to create directory '${DIR}'"
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    # build the directory, but if it fails, recurse a level (and handle
 | 
						|
    # the case where recursion fails)
 | 
						|
    mkdir "${DIR}" >& /dev/null
 | 
						|
    if [ $? -ne 0 ]
 | 
						|
    then
 | 
						|
        build_dir_tree_recurse $(dirname "${DIR}") || return 1
 | 
						|
	echo " Creating directory '${DIR}'"
 | 
						|
        do_cmd mkdir "${DIR}"
 | 
						|
        if [ $? -ne 0 ]
 | 
						|
        then
 | 
						|
            print_failure "Failed to create directory '${DIR}'"
 | 
						|
            return 1
 | 
						|
        fi
 | 
						|
    fi
 | 
						|
 | 
						|
    # set permissions on newly-created dir and return
 | 
						|
    chmod 0755 "${DIR}"
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# This will install a file. The first parameter is the source, and the
 | 
						|
# second is the destination. The third is the octal mode.
 | 
						|
install_file() {
 | 
						|
    # figure out if $2 is a directory or not
 | 
						|
    DEST_FILE="${INSTALL_PREFIX}$2"
 | 
						|
    [ -d "${DEST_FILE}" ] && DEST_FILE="${INSTALL_PREFIX}$2/$(basename $1)"
 | 
						|
 | 
						|
    echo " Installing: '$1' -> '${DEST_FILE}'"
 | 
						|
    do_cmd cp -fP "$1" "${DEST_FILE}" || return 1
 | 
						|
    do_cmd chmod "$3" "${DEST_FILE}" || return 1
 | 
						|
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# This will install a header file. It is basically similar to 
 | 
						|
# install_file(), only we strip out the #line directives.
 | 
						|
install_header() {
 | 
						|
    DEST_FILE="${INSTALL_PREFIX}$2"
 | 
						|
    [ -d "${DEST_FILE}" ] && DEST_FILE="${INSTALL_PREFIX}$2/$(basename $1)"
 | 
						|
 | 
						|
    echo " Installing: '$1' -> '${DEST_FILE}'"
 | 
						|
    do_cmd rm -f ${DEST_FILE} || exit 1
 | 
						|
    do_cmd_redir ${DEST_FILE} sed -e "s,^#line.*,," $1 || exit 1
 | 
						|
    do_cmd chmod "$3" "${DEST_FILE}" || return 1
 | 
						|
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
# This installs a symlink. The first argument is the symlink's name; the
 | 
						|
# second the symlink's source filename, and the third is the directory
 | 
						|
# in which to create the symlink.
 | 
						|
install_symlink() {
 | 
						|
    echo " Installing symlink: '${INSTALL_PREFIX}$3/$1' -> '$2'"
 | 
						|
 | 
						|
    ( do_cmd ln -sf $2 ${INSTALL_PREFIX}$3/$1 ) || return 1
 | 
						|
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
build_target() {
 | 
						|
    ITEMS="src/$1/build.default"
 | 
						|
    if [ ! -e "${ITEMS}" ]
 | 
						|
    then
 | 
						|
        ITEMS="$(find src -type f -name build.$1)"
 | 
						|
    fi
 | 
						|
    
 | 
						|
    if [ -z "${ITEMS}" ]
 | 
						|
    then
 | 
						|
        print_failure "Unrecognised target '$1'"
 | 
						|
        return 1
 | 
						|
    fi
 | 
						|
 | 
						|
    for item in ${ITEMS}
 | 
						|
    do
 | 
						|
        do_cmd source ${item} || exit 1
 | 
						|
    done
 | 
						|
    return 0
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
 | 
						|
########################################################################
 | 
						|
# Main script
 | 
						|
########################################################################
 | 
						|
 | 
						|
if [ $# -eq 0 ]
 | 
						|
then
 | 
						|
    targets="default"
 | 
						|
else
 | 
						|
    targets="$@"
 | 
						|
fi
 | 
						|
 | 
						|
for func in ${targets}
 | 
						|
do
 | 
						|
    case ${func} in
 | 
						|
    clean)
 | 
						|
        echo "Cleaning..."
 | 
						|
        rm -rf ${OUTPUT_DIRS}
 | 
						|
        print_success "Done"
 | 
						|
        true
 | 
						|
    ;;
 | 
						|
 | 
						|
    # bad Kdevelop! bad!
 | 
						|
    -j1)
 | 
						|
    ;;
 | 
						|
    -k)
 | 
						|
    ;;
 | 
						|
 | 
						|
    *)
 | 
						|
        build_target ${func} || exit 1
 | 
						|
    ;;
 | 
						|
    esac
 | 
						|
done
 | 
						|
 | 
						|
exit 0
 | 
						|
 | 
						|
# vim: expandtab:ts=4:sw=4
 |