From 050b97c308f4aeb96cdc1317114768517ef18944 Mon Sep 17 00:00:00 2001 From: meep-eep Date: Mon, 30 May 2005 02:47:28 +0000 Subject: [PATCH] Improved dependency tracking and cleaner make output. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1820 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/Makefile.build | 86 ++++++++++-------- sc2/Makeinfo | 36 -------- sc2/Makeproject | 36 ++++++++ sc2/build/unix/build.sh | 16 ++-- sc2/build/unix/build_clean | 56 ++++++++++++ sc2/build/unix/build_collect | 53 +++++++++++ sc2/build/unix/build_functions | 158 +++++++++------------------------ 7 files changed, 243 insertions(+), 198 deletions(-) create mode 100644 sc2/Makeproject create mode 100644 sc2/build/unix/build_clean create mode 100644 sc2/build/unix/build_collect diff --git a/sc2/Makefile.build b/sc2/Makefile.build index 854634226..18208fdcb 100644 --- a/sc2/Makefile.build +++ b/sc2/Makefile.build @@ -1,49 +1,63 @@ # Make file for the uqm build system. Invoked from build/unix/build_functions # By Serge van den Boom -default: - ./build.sh sc2 +SOURCES := $(shell cat "$(DEPEND_FILE)") +-include $(SOURCES:=.d) -%.rc.o: - @DIR=$(dir $@); \ - if [ ! -d $$DIR ]; then \ - mkdir -p "$$DIR"; \ - fi +ifeq ($(MAKE_VERBOSE),1) +define act + $(call $(1)) +endef +else +define act + @echo " $(2) $(3)" + @$(call $(1)) +endef +endif + +define act_mkdep_c + $(MKDEPEND) -o - $(CFLAGS) "$<" | \ + $(SED) -e 's,^\(.*\).o:,'"$(@D)"'/\1.c.o:,' > "$@" +endef + +define act_windres $(WINDRES) --include-dir $(dir $<) -o "$@" "$<" +endef -%.o: +define act_cc + $(COMPILE) -o "$@" -c $(CFLAGS) "$<" +endef + +define act_link + $(COMPILE) -o "$@" $^ $(LDFLAGS) +endef + + +default: + ./build.sh uqm + +$(OBJDIR)%.c.d: $(BUILD_ROOT)%.c @DIR=$(dir $@); \ if [ ! -d $$DIR ]; then \ mkdir -p "$$DIR"; \ fi - $(COMPILE) -o "$@" -c $(CFLAGS) "$<" + $(call act,act_mkdep_c,MKDEP ,$@) -target-%: - $(COMPILE) -o "$*" $^ $(LDFLAGS) +%.rc.o: %.rc + @DIR=$(dir $@); \ + if [ ! -d $$DIR ]; then \ + mkdir -p "$$DIR"; \ + fi + $(call act,act_windres,WINDRES,$@) + +%.c.o: + @DIR=$(dir $@); \ + if [ ! -d $$DIR ]; then \ + mkdir -p "$$DIR"; \ + fi + $(call act,act_cc,CC ,$@) + +$(TARGET_FILE): $(SOURCES:=.o) + $(call act,act_link,LINK ,$@) -## The following kludge is necessary because the GNU make 'include' -## statement does not accept spaces etc in the argument. -#define ESCAPE_DEPEND -#sed -e 's/["$$ #\*\?\\]/\\&/g' << EOF -#$${DEPEND_FILE} -#EOF -#endef -#export ESCAPE_DEPEND -#.PHONY: escape_depend -#.INTERMEDIATE: escape_depend -#escape_depend: -## @set > set.out -# @sh -x -v -c "$$ESCAPE_DEPEND" -#ifneq ($(MAKECMDGOALS),escape_depend) -#include $(shell $(MAKE) -f Makefile.build escape_depend) -#endif - -include $(DEPEND_FILE) - -# Temporary: -$(BUILD_WORK)/obj/release/./src/res/UrQuanMasters.rc.o: \ - ./src/res/UrQuanMasters.rc -$(BUILD_WORK)/obj/debug/./src/res/UrQuanMasters.rc.o: \ - ./src/res/UrQuanMasters.rc - diff --git a/sc2/Makeinfo b/sc2/Makeinfo index b2f23dd04..103277c2b 100644 --- a/sc2/Makeinfo +++ b/sc2/Makeinfo @@ -1,37 +1 @@ -TARGETS="uqm" - -# For the 'uqm' target: uqm_SUBDIRS=src -if [ "$DEBUG" = "1" ]; then - uqm_OBJS=obj/debug/ # Directory for object files - uqm_NAME=uqm-debug # File name of executable -else - uqm_OBJS=obj/release/ # Directory for object files - uqm_NAME=uqm # File name of executable -fi -uqm_CFLAGS="$uqm_CFLAGS -I src -I src/sc2code -I src/sc2code/libs" -if [ "$uqm_HAVE_REGEX" = 0 ]; then - uqm_CFLAGS="$uqm_CFLAGS -I src/regex" -fi - -# Stuff to install under the directory for libraries, as specified during -# config. -uqm_INSTALL_LIBS="executable" -uqm_INSTALL_LIB_executable_SRC="$BUILD_WORK/$uqm_NAME" -uqm_INSTALL_LIB_executable_DEST=uqm/uqm -uqm_INSTALL_LIB_executable_MODE="0755" - -# Stuff to install under the directory for system-independant data, as -# specified during config. -uqm_INSTALL_SHARED="content" -uqm_INSTALL_SHARED_content_SRC=content -uqm_INSTALL_SHARED_content_DEST=uqm/ -uqm_INSTALL_SHARED_content_MODE="go+rX" - -# Stuff to install under the directory for binaries, as specified during -# config. -uqm_INSTALL_BINS=wrapper -uqm_INSTALL_BIN_wrapper_SRC="$BUILD_WORK/uqm-wrapper" -uqm_INSTALL_BIN_wrapper_DEST="uqm" -uqm_INSTALL_BIN_wrapper_MODE="0755" - diff --git a/sc2/Makeproject b/sc2/Makeproject new file mode 100644 index 000000000..6b43d3032 --- /dev/null +++ b/sc2/Makeproject @@ -0,0 +1,36 @@ +TARGETS="uqm" + +# For the 'uqm' target: +if [ "$DEBUG" = "1" ]; then + uqm_OBJS=obj/debug/ # Directory for object files + uqm_NAME=uqm-debug # File name of executable +else + uqm_OBJS=obj/release/ # Directory for object files + uqm_NAME=uqm # File name of executable +fi +uqm_CFLAGS="$uqm_CFLAGS -I src -I src/sc2code -I src/sc2code/libs" +if [ "$uqm_HAVE_REGEX" = 0 ]; then + uqm_CFLAGS="$uqm_CFLAGS -I src/regex" +fi + +# Stuff to install under the directory for libraries, as specified during +# config. +uqm_INSTALL_LIBS="executable" +uqm_INSTALL_LIB_executable_SRC="$BUILD_WORK/$uqm_NAME" +uqm_INSTALL_LIB_executable_DEST=uqm/uqm +uqm_INSTALL_LIB_executable_MODE="0755" + +# Stuff to install under the directory for system-independant data, as +# specified during config. +uqm_INSTALL_SHARED="content" +uqm_INSTALL_SHARED_content_SRC=content +uqm_INSTALL_SHARED_content_DEST=uqm/ +uqm_INSTALL_SHARED_content_MODE="go+rX" + +# Stuff to install under the directory for binaries, as specified during +# config. +uqm_INSTALL_BINS=wrapper +uqm_INSTALL_BIN_wrapper_SRC="$BUILD_WORK/uqm-wrapper" +uqm_INSTALL_BIN_wrapper_DEST="uqm" +uqm_INSTALL_BIN_wrapper_MODE="0755" + diff --git a/sc2/build/unix/build.sh b/sc2/build/unix/build.sh index 091a192d1..4d19798b6 100644 --- a/sc2/build/unix/build.sh +++ b/sc2/build/unix/build.sh @@ -29,23 +29,17 @@ fi # Read in the config settings that affect the build, if present. # Don't reread for every dir when recursing. -if [ -r "$BUILD_WORK/build.vars" -a -z "$BUILD_COMMAND" ]; then +if [ -r "$BUILD_WORK/build.vars" ]; then . "$BUILD_WORK/build.vars" fi -# Read in the Makeinfo file for the dir currently being processed -. "${BUILD_REC_PATH:=./}Makeinfo" - -# If we're recursing, go on. -if [ -n "$BUILD_COMMAND" ]; then - $BUILD_COMMAND - exit $? -fi +# Read in the Makeproject file +. ./Makeproject for VAR in TARGETS "$BUILD_PROJECT_NAME" "$BUILD_PROJECT_OBJS"; do eval VALUE="\$$VAR" if [ -z "$VALUE" ]; then - echo "$VAR needs to be defined in the top Makeinfo file" + echo "$VAR needs to be defined in the top Makeproject file" exit 1 fi done @@ -115,7 +109,7 @@ case "$2" in ;; depend) build_check_config - build_rec_dependencies + build_depend ;; install) build_check_config diff --git a/sc2/build/unix/build_clean b/sc2/build/unix/build_clean new file mode 100644 index 000000000..51ed1231e --- /dev/null +++ b/sc2/build/unix/build_clean @@ -0,0 +1,56 @@ +#!/bin/sh + +# Expected to be passed from the environment: +# BUILD_PROJECT - the name of the project +# BUILD_ROOT - The root of the source files. +# BUILD_WORK - The root of the work directory. + +BUILD_ROOT=${BUILD_ROOT%/}/ +BUILD_WORK=${BUILD_WORK%/}/ +eval OBJDIR=\"${BUILD_WORK}\${${BUILD_PROJECT}_OBJS}\" + + +# $1 - The prefix up to this point +# $2 - The name of the current subdir +recurse_subdir() { + local REC_PREFIX SUBDIRS SUBDIR CFILES CXXFILES MFILES RCFILES FILE + eval local ${BUILD_PROJECT}_CFILES ${BUILD_PROJECT}_CXXFILES \ + ${BUILD_PROJECT}_MFILES ${BUILD_PROJECT}_RCFILES \ + ${BUILD_PROJECT}_SUBDIRS + + REC_PREFIX="$1$2/" + if [ "$REC_PREFIX" = "/" ]; then + REC_PREFIX= + fi + + eval ${BUILD_PROJECT}_CFILES= + eval ${BUILD_PROJECT}_CXXFILES= + eval ${BUILD_PROJECT}_MFILES= + eval ${BUILD_PROJECT}_RCFILES= + eval ${BUILD_PROJECT}_SUBDIRS= + + . "${BUILD_ROOT}${REC_PREFIX}Makeinfo" + + eval CFILES=\$${BUILD_PROJECT}_CFILES + eval CXXFILES=\$${BUILD_PROJECT}_CXXFILES + eval MFILES=\$${BUILD_PROJECT}_MFILES + eval RCFILES=\$${BUILD_PROJECT}_RCFILES + for FILE in $CFILES $CXXFILES $MFILES $RCFILES; do + rm -f -- "${OBJDIR}${REC_PREFIX}$FILE.d" \ + "${OBJDIR}${REC_PREFIX}$FILE.o" + done + + eval SUBDIRS=\$${BUILD_PROJECT}_SUBDIRS + for SUBDIR in $SUBDIRS; do + recurse_subdir "$REC_PREFIX" "$SUBDIR" + done + + rmdir -- "${OBJDIR}${REC_PREFIX%/}" 2> /dev/null +} + + +. "${BUILD_ROOT}Makeproject" + +recurse_subdir "" "" + + diff --git a/sc2/build/unix/build_collect b/sc2/build/unix/build_collect new file mode 100644 index 000000000..5e9612e7f --- /dev/null +++ b/sc2/build/unix/build_collect @@ -0,0 +1,53 @@ +#!/bin/sh + +# Expected to be passed from the environment: +# BUILD_PROJECT - the name of the project +# BUILD_ROOT - The root of the source files. +# BUILD_WORK - The root of the work directory. + +BUILD_ROOT=${BUILD_ROOT%/}/ +BUILD_WORK=${BUILD_WORK%/}/ +eval OBJDIR=\"${BUILD_WORK}\${${BUILD_PROJECT}_OBJS}\" + + +# $1 - The prefix up to this point +# $2 - The name of the current subdir +recurse_subdir() { + local REC_PREFIX SUBDIRS SUBDIR CFILES CXXFILES MFILES RCFILES FILE + eval local ${BUILD_PROJECT}_CFILES ${BUILD_PROJECT}_CXXFILES \ + ${BUILD_PROJECT}_MFILES ${BUILD_PROJECT}_RCFILES \ + ${BUILD_PROJECT}_SUBDIRS + + REC_PREFIX="$1$2/" + if [ "$REC_PREFIX" = "/" ]; then + REC_PREFIX= + fi + + eval ${BUILD_PROJECT}_CFILES= + eval ${BUILD_PROJECT}_CXXFILES= + eval ${BUILD_PROJECT}_MFILES= + eval ${BUILD_PROJECT}_RCFILES= + eval ${BUILD_PROJECT}_SUBDIRS= + + . "${BUILD_ROOT}${REC_PREFIX}Makeinfo" + + eval CFILES=\$${BUILD_PROJECT}_CFILES + eval CXXFILES=\$${BUILD_PROJECT}_CXXFILES + eval MFILES=\$${BUILD_PROJECT}_MFILES + eval RCFILES=\$${BUILD_PROJECT}_RCFILES + for FILE in $CFILES $CXXFILES $MFILES $RCFILES; do + echo "${OBJDIR}${REC_PREFIX}$FILE" + done + + eval SUBDIRS=\$${BUILD_PROJECT}_SUBDIRS + for SUBDIR in $SUBDIRS; do + recurse_subdir "$REC_PREFIX" "$SUBDIR" + done +} + + +. "${BUILD_ROOT}Makeproject" +. "${BUILD_WORK}build.vars" + +recurse_subdir "" "" + diff --git a/sc2/build/unix/build_functions b/sc2/build/unix/build_functions index 438bb53ff..732278029 100644 --- a/sc2/build/unix/build_functions +++ b/sc2/build/unix/build_functions @@ -15,6 +15,8 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +DEPEND_NAME=make.depend + # Show usage information usage() { echo "Main build script" @@ -41,98 +43,6 @@ $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() { @@ -173,36 +83,54 @@ build_process_config() { eval "${TARGET}_process_config" } +# Recursively build dependency index +build_depend() { + local DEPEND_FILE EXTRA_OFILES + + echo "Building file dependency index..." >&2 + + eval mkdir -p "\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}" + eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}\$DEPEND_NAME" + + # 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_ROOT=./ $SH ./build/unix/build_collect > "$DEPEND_FILE".tmp + mv -f -- "$DEPEND_FILE".tmp "$DEPEND_FILE" +} + # Compile the lot. # With the depend info set up, we can leave everything to make. build_compile() { + local CFLAGS LDFLAGS TARGET_FILE DEPEND_FILE OBJDIR + + eval CFLAGS="\${${BUILD_PROJECT}_CFLAGS}" + eval LDFLAGS="\${${BUILD_PROJECT}_LDFLAGS}" + eval OBJDIR=\""\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}"\" + eval TARGET_FILE=\""\$BUILD_WORK/\${${BUILD_PROJECT}_NAME}"\" + DEPEND_FILE=$OBJDIR$DEPEND_NAME + 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}\" + + CFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \ + OBJDIR=$OBJDIR \ + BUILD_ROOT= \ + TARGET_FILE=$TARGET_FILE DEPEND_FILE=$DEPEND_FILE \ + SED=$SED \ + $MAKE -f Makefile.build "$TARGET_FILE" + 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" + + BUILD_ROOT=./ $SH ./build/unix/build_clean + + eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}${DEPEND_NAME}" 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() { @@ -227,16 +155,16 @@ build_check_config() { build_process_config fi . "$BUILD_WORK/build.vars" - . "${BUILD_REC_PATH:=./}Makeinfo" + . "${BUILD_REC_PATH:=./}Makeproject" } -# Description: check if the necessary .depend file is present, +# 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" + eval DEPEND_FILE="\$BUILD_WORK/\${${BUILD_PROJECT}_OBJS}${DEPEND_NAME}" [ ! -e "$DEPEND_FILE" -o -n "$BUILD_RUN_DEPEND" ] || return - build_rec_dependencies || exit $? + build_depend || exit $? } # Description: check if the program is compiled, and otherwise compile