From 9cfdb48722cba8bfaafee9de61411618d66365f3 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Fri, 20 May 2016 07:32:51 -0500 Subject: Make build dependencies more granular. This should fix the problem where "make top; make ps" produces a ps that can't do -A because generated/obj/ps.o didn't get rebuilt. --- scripts/make.sh | 165 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 68 deletions(-) (limited to 'scripts') diff --git a/scripts/make.sh b/scripts/make.sh index d3dc8eb9..80d14849 100755 --- a/scripts/make.sh +++ b/scripts/make.sh @@ -27,7 +27,9 @@ do_loudly() # Is anything under directory $2 newer than file $1 isnewer() { - [ ! -z "$(find "$2" -newer "$1" 2>/dev/null || echo yes)" ] + CHECK="$1" + shift + [ ! -z "$(find "$@" -newer "$CHECK" 2>/dev/null || echo yes)" ] } echo "Generate headers from toys/*/*.c..." @@ -66,7 +68,8 @@ TOYFILES="$(sed -n 's/^CONFIG_\([^=]*\)=.*/\1/p' "$KCONFIG_CONFIG" | xargs | tr TOYFILES="$(egrep -l "TOY[(]($TOYFILES)[ ,]" toys/*/*.c)" CFLAGS="$CFLAGS $(cat generated/cflags)" BUILD="$(echo ${CROSS_COMPILE}${CC} $CFLAGS -I . $OPTIMIZE $GITHASH)" -FILES="$(echo lib/*.c main.c $TOYFILES)" +LIBFILES="$(ls lib/*.c | grep -v lib/help.c)" +TOYFILES="lib/help.c main.c $TOYFILES" if [ "${TOYFILES/pending//}" != "$TOYFILES" ] then @@ -81,7 +84,7 @@ genbuildsh() echo echo "BUILD=\"$BUILD\"" echo - echo "FILES=\"$FILES\"" + echo "FILES=\"$LIBFILES $TOYFILES\"" echo echo "LINK=\"$LINK\"" echo @@ -116,77 +119,88 @@ fi LINK="$(echo $LDOPTIMIZE $LDFLAGS -o "$UNSTRIPPED" -Wl,--as-needed $(cat generated/optlibs.dat))" genbuildsh > generated/build.sh && chmod +x generated/build.sh || exit 1 -echo "Make generated/config.h from $KCONFIG_CONFIG." - -# This long and roundabout sed invocation is to make old versions of sed happy. -# New ones have '\n' so can replace one line with two without all the branches -# and tedious mucking about with hold space. - -sed -n \ - -e 's/^# CONFIG_\(.*\) is not set.*/\1/' \ - -e 't notset' \ - -e 's/^CONFIG_\(.*\)=y.*/\1/' \ - -e 't isset' \ - -e 's/^CONFIG_\([^=]*\)=\(.*\)/#define CFG_\1 \2/p' \ - -e 'd' \ - -e ':notset' \ - -e 'h' \ - -e 's/.*/#define CFG_& 0/p' \ - -e 'g' \ - -e 's/.*/#define USE_&(...)/p' \ - -e 'd' \ - -e ':isset' \ - -e 'h' \ - -e 's/.*/#define CFG_& 1/p' \ - -e 'g' \ - -e 's/.*/#define USE_&(...) __VA_ARGS__/p' \ - $KCONFIG_CONFIG > generated/config.h || exit 1 +if isnewer generated/config.h "$KCONFIG_CONFIG" +then + echo "Make generated/config.h from $KCONFIG_CONFIG." + + # This long and roundabout sed invocation is to make old versions of sed + # happy. New ones have '\n' so can replace one line with two without all + # the branches and tedious mucking about with hold space. + + sed -n \ + -e 's/^# CONFIG_\(.*\) is not set.*/\1/' \ + -e 't notset' \ + -e 's/^CONFIG_\(.*\)=y.*/\1/' \ + -e 't isset' \ + -e 's/^CONFIG_\([^=]*\)=\(.*\)/#define CFG_\1 \2/p' \ + -e 'd' \ + -e ':notset' \ + -e 'h' \ + -e 's/.*/#define CFG_& 0/p' \ + -e 'g' \ + -e 's/.*/#define USE_&(...)/p' \ + -e 'd' \ + -e ':isset' \ + -e 'h' \ + -e 's/.*/#define CFG_& 1/p' \ + -e 'g' \ + -e 's/.*/#define USE_&(...) __VA_ARGS__/p' \ + $KCONFIG_CONFIG > generated/config.h || exit 1 +fi if [ generated/mkflags -ot scripts/mkflags.c ] then do_loudly $HOSTCC scripts/mkflags.c -o generated/mkflags || exit 1 fi -echo -n "generated/flags.h " - # Process config.h and newtoys.h to generate FLAG_x macros. Note we must # always #define the relevant macro, even when it's disabled, because we # allow multiple NEWTOY() in the same C file. (When disabled the FLAG is 0, # so flags&0 becomes a constant 0 allowing dead code elimination.) -# Parse files through C preprocessor twice, once to get flags for current -# .config and once to get flags for allyesconfig -for I in A B -do - ( - # define macros and select header files with option string data - - echo "#define NEWTOY(aa,bb,cc) aa $I bb" - echo '#define OLDTOY(...)' - if [ "$I" == A ] - then - cat generated/config.h - else - sed '/USE_.*([^)]*)$/s/$/ __VA_ARGS__/' generated/config.h - fi - cat generated/newtoys.h - - # Run result through preprocessor, glue together " " gaps leftover from USE - # macros, delete comment lines, print any line with a quoted optstring, - # turn any non-quoted opstring (NULL or 0) into " " (because fscanf can't - # handle "" with nothing in it, and mkflags uses that). - - ) | ${CROSS_COMPILE}${CC} -E - | \ +make_flagsh() +{ + # Parse files through C preprocessor twice, once to get flags for current + # .config and once to get flags for allyesconfig + for I in A B + do + ( + # define macros and select header files with option string data + + echo "#define NEWTOY(aa,bb,cc) aa $I bb" + echo '#define OLDTOY(...)' + if [ "$I" == A ] + then + cat generated/config.h + else + sed '/USE_.*([^)]*)$/s/$/ __VA_ARGS__/' generated/config.h + fi + cat generated/newtoys.h + + # Run result through preprocessor, glue together " " gaps leftover from USE + # macros, delete comment lines, print any line with a quoted optstring, + # turn any non-quoted opstring (NULL or 0) into " " (because fscanf can't + # handle "" with nothing in it, and mkflags uses that). + + ) | ${CROSS_COMPILE}${CC} -E - | \ sed -n -e 's/" *"//g;/^#/d;t clear;:clear;s/"/"/p;t;s/\( [AB] \).*/\1 " "/p' -# Sort resulting line pairs and glue them together into triplets of -# command "flags" "allflags" -# to feed into mkflags C program that outputs actual flag macros -# If no pair (because command's disabled in config), use " " for flags -# so allflags can define the appropriate zero macros. + # Sort resulting line pairs and glue them together into triplets of + # command "flags" "allflags" + # to feed into mkflags C program that outputs actual flag macros + # If no pair (because command's disabled in config), use " " for flags + # so allflags can define the appropriate zero macros. -done | sort -s | sed -n 's/ A / /;t pair;h;s/\([^ ]*\).*/\1 " "/;x;b single;:pair;h;n;:single;s/[^ ]* B //;H;g;s/\n/ /;p' | tee generated/flags.raw | \ -generated/mkflags > generated/flags.h || exit 1 + done | sort -s | sed -n -e 's/ A / /;t pair;h;s/\([^ ]*\).*/\1 " "/;x' \ + -e 'b single;:pair;h;n;:single;s/[^ ]* B //;H;g;s/\n/ /;p' | \ + tee generated/flags.raw | generated/mkflags > generated/flags.h || exit 1 +} + +if isnewer generated/flags.h toys "$KCONFIG_CONFIG" +then + echo -n "generated/flags.h " + make_flagsh +fi # Extract global structure definitions and flag definitions from toys/*/*.c @@ -230,13 +244,16 @@ then toys/*/*.c lib/*.c | generated/mktags > generated/tags.h fi -echo "generated/help.h" if [ generated/config2help -ot scripts/config2help.c ] then do_loudly $HOSTCC scripts/config2help.c -I . lib/xwrap.c lib/llist.c \ lib/lib.c lib/portability.c -o generated/config2help || exit 1 fi -generated/config2help Config.in $KCONFIG_CONFIG > generated/help.h || exit 1 +if isnewer generated/help.h generated/Config.in +then + echo "generated/help.h" + generated/config2help Config.in $KCONFIG_CONFIG > generated/help.h || exit 1 +fi [ ! -z "$NOBUILD" ] && exit 0 @@ -246,26 +263,38 @@ DOTPROG=. # This is a parallel version of: do_loudly $BUILD $FILES $LINK || exit 1 +# Any headers newer than the oldest generated/obj file? X="$(ls -1t generated/obj/* 2>/dev/null | tail -n 1)" +# TODO: redo this if [ ! -e "$X" ] || [ ! -z "$(find toys -name "*.h" -newer "$X")" ] then rm -rf generated/obj && mkdir -p generated/obj || exit 1 else rm -f generated/obj/{main,lib_help}.o || exit 1 fi + +# build each generated/obj/*.o file in parallel + PENDING= -LFILES= +LNKFILES= DONE=0 COUNT=0 -for i in $FILES +CLICK= + +for i in $LIBFILES click $TOYFILES do - # build each generated/obj/*.o file in parallel + [ "$i" == click ] && CLICK=1 && continue X=${i/lib\//lib_} X=${X##*/} OUT="generated/obj/${X%%.c}.o" - LFILES="$LFILES $OUT" - [ "$OUT" -nt "$i" ] && continue + LNKFILES="$LNKFILES $OUT" + + # $LIBFILES doesn't need to be rebuilt if newer than .config, $TOYFILES does + + [ "$OUT" -nt "$i" ] && [ -z "$CLICK" -o "$OUT" -nt "$KCONFIG_CONFIG" ] && + continue + do_loudly $BUILD -c $i -o $OUT & PENDING="$PENDING $!" COUNT=$(($COUNT+1)) @@ -294,7 +323,7 @@ done [ $DONE -ne 0 ] && exit 1 -do_loudly $BUILD $LFILES $LINK || exit 1 +do_loudly $BUILD $LNKFILES $LINK || exit 1 if [ ! -z "$NOSTRIP" ] || ! do_loudly ${CROSS_COMPILE}strip "$UNSTRIPPED" -o "$OUTNAME" then -- cgit v1.2.3