restructure building process

Right now, we do three build passes: one to build the original tree
(full) build, one to build the patch tree (diff build), then one to
rebuild original objects that where changed by the patch (diff build).

This is going to be a problem when we try to support (near) full tree
rebuilds due to changes in commonly included header files.

This commit changes the build process to intercept calls to gcc by make
using the CROSS_COMPILE environment variable and, during the patched
build phase, copies the original object for any object that is about to
rebuilt due to a change.

This reduces the number of build passes to the minimum possible (two).

Signed-off-by: Seth Jennings <sjenning@redhat.com>
This commit is contained in:
Seth Jennings 2014-08-07 15:33:31 -05:00
parent 191e389b43
commit b98fafcfb2
3 changed files with 44 additions and 34 deletions

View File

@ -14,7 +14,7 @@ create-diff-object: create-diff-object.c list.h lookup.c lookup.h insn/insn.c \
install: all
$(INSTALL) -d $(LIBEXECDIR)
$(INSTALL) $(TARGETS) $(LIBEXECDIR)
$(INSTALL) $(TARGETS) kpatch-gcc $(LIBEXECDIR)
$(INSTALL) -d $(BINDIR)
$(INSTALL) kpatch-build $(BINDIR)

View File

@ -392,48 +392,25 @@ export KCFLAGS="-I$DATADIR/patch -ffunction-sections -fdata-sections"
echo "Building original kernel"
make mrproper >> "$LOGFILE" 2>&1 || die
make "-j$CPUS" $TARGETS "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
echo "Building patched kernel"
patch -N -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1 || die
make "-j$CPUS" $TARGETS "O=$OBJDIR" 2>&1 | tee -a "$TEMPDIR/patched_build.log" >> "$LOGFILE"
mkdir -p "$TEMPDIR/orig" "$TEMPDIR/patched"
export TEMPDIR
CROSS_COMPILE="$TOOLSDIR/kpatch-gcc " make "-j$CPUS" $TARGETS "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
[[ "${PIPESTATUS[0]}" -eq 0 ]] || die
echo "Detecting changed objects"
while read line; do
[[ "$line" =~ CC ]] || continue
eval set -- "$line"
case $2 in
init/version.o) continue ;;
scripts/mod/devicetable-offsets.s) continue ;;
scripts/mod/file2alias.o) continue ;;
*.mod.o) continue ;;
arch/x86/kernel/asm-offsets.s) die "a struct definition change was detected" ;;
\[M\]) obj=$3 ;;
*) obj=$2 ;;
esac
if [[ ! -e "$TEMPDIR/changed_objs" ]]; then
die "no changed objects found"
fi
echo $obj >> $TEMPDIR/changed_objs
done < "$TEMPDIR/patched_build.log"
[[ ! -s "$TEMPDIR/changed_objs" ]] && die "no changed objects were detected"
mkdir "$TEMPDIR/patched"
for i in $(cat $TEMPDIR/changed_objs); do
mkdir -p "$TEMPDIR/patched/$(dirname $i)"
for i in $(cat "$TEMPDIR/changed_objs")
do
mkdir -p "$TEMPDIR/patched/$(dirname $i)" || die
cp -f "$OBJDIR/$i" "$TEMPDIR/patched/$i" || die
done
echo "Rebuilding original objects"
patch -R -p1 < "$APPLIEDPATCHFILE" >> "$LOGFILE" 2>&1
rm -f "$APPLIEDPATCHFILE"
make "-j$CPUS" $TARGETS "O=$OBJDIR" >> "$LOGFILE" 2>&1 || die
mkdir "$TEMPDIR/orig"
for i in $(cat $TEMPDIR/changed_objs); do
mkdir -p "$TEMPDIR/orig/$(dirname $i)"
cp -f "$OBJDIR/$i" "$TEMPDIR/orig/$i" || die
done
echo "Extracting new and modified ELF sections"
cd "$TEMPDIR/orig"
FILES="$(find * -type f)"

33
kpatch-build/kpatch-gcc Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
set -x
TOOLCHAINCMD="$1"
shift
if [[ "$TOOLCHAINCMD" != "gcc" ]] || [[ -z "$TEMPDIR" ]]; then
exec "$TOOLCHAINCMD" "$@"
fi
declare -a args=($@)
while [ "$#" -gt 0 ]; do
if [ "$1" = "-o" ]; then
case "$2" in
*.mod.o|*built-in.o|vmlinux.o|.tmp_kallsyms1.o|.tmp_kallsyms2.o|init/version.o|arch/x86/boot/version.o|arch/x86/boot/compressed/eboot.o|arch/x86/boot/header.o|arch/x86/boot/compressed/efi_stub_64.o|arch/x86/boot/compressed/piggy.o|.*.o)
break;
;;
*.o)
mkdir -p "$TEMPDIR/orig/$(dirname $2)"
cp -f "$2" "$TEMPDIR/orig/$2"
echo "$2" >> "$TEMPDIR/changed_objs"
;;
*)
break
;;
esac
fi
shift
done
exec "$TOOLCHAINCMD" "${args[@]}"