From 0c414638168e0c1a006827daaae10c2ea4a8fc08 Mon Sep 17 00:00:00 2001 From: wangcichen Date: Mon, 9 May 2022 16:27:09 +0800 Subject: [PATCH] modify scripts/pkgbuild to make kpatch'es for the RPM-based packages 1.support specify patch-id, build-id and sanity check 2.simplify script and put it into libcare devel package --- scripts/example_info | 59 ++++++++++++++ scripts/pkgbuild | 179 ++++++++++++++++++++++++------------------- 2 files changed, 161 insertions(+), 77 deletions(-) create mode 100644 scripts/example_info diff --git a/scripts/example_info b/scripts/example_info new file mode 100644 index 0000000..d848e33 --- /dev/null +++ b/scripts/example_info @@ -0,0 +1,59 @@ +#!/bin/bash + +KP_PROJECT=qemu +KP_PROJECT_FORMAT=rpm +KP_PROJECT_BUILD_ROOT=/var/libcareplus/qemu/rpmbuild +KP_PROJECT_ORIG_RPMS=/var/libcareplus/qemu/qemu-6.2.0-29.oe2203 +KP_PROJECT_SPEC=qemu.spec + +# we choose plist filename as patch-id, eg: 220411 here +KP_PROJECT_PLIST_FILE=/var/libcareplus/qemu/patch001/220506.plist +KP_PROJECT_DIR=$KP_PROJECT_BUILD_ROOT/BUILD/qemu-6.2.0 +KP_PROJECT_BUILD_DIR=$KP_PROJECT_DIR/build/x86_64-softmmu +KP_PROJECT_BUILD_ID=61fcf129b23f05a623e0bf696a03d3348f366348 +KP_SANITY_CHECK_STRICTLY=no +KP_PROJECT_SOURCE_URL= +KP_PROJECT_SOURCE=qemu-6.2.0-29.oe2203.src.rpm +KP_PROJECT_BINARY=qemu-6.2.0-29.oe2203.x86_64.rpm + +KP_PROJECT_PREBUILT=build.orig-$KP_PROJECT_BINARY.tgz +KP_PROJECT_PATCH=kpatch-${KP_PROJECT_BINARY%.*}.tgz +KP_RPMBUILD_FLAGS="'--define=dist .oe2203'" +#KP_RPM_REPOS="--enablerepo=base" + + +KP_INSTALL_FILES=" +/qemu-system-x86_64 /usr/libexec/qemu-kvm +" + +KPATCH_ASM_DIR=$KP_PROJECT_BUILD_ROOT/asmdir +export KPATCH_ASM_DIR + +KPCC_PATCH_ARGS="--force-gotpcrel;--os=rhel6;--ignore-changes=banner,compilation" +export KPCC_PATCH_ARGS + +KPCC_DBGFILTER_ARGS="--dbg-filter;--dbg-filter-eh-frame;--dbg-filter-gcc-except-table;--os=rhel6" +export KPCC_DBGFILTER_ARGS + +kp_prebuild_hook() { + if test -z "$(command -v tar)"; then + echo "No tar command, Please install it first" + exit 1 + fi + if test -z "$(command -v rpmbuild)"; then + echo "No rpmbuild command, Please install it first" + exit 1 + fi +} + +kp_build_hook() { + : +} + +kp_prepare_test_binaries() { + : +} + +kp_patch_test() { + : +} diff --git a/scripts/pkgbuild b/scripts/pkgbuild index f91af57..1185cd9 100755 --- a/scripts/pkgbuild +++ b/scripts/pkgbuild @@ -1,4 +1,8 @@ #!/bin/bash +# make kpatch'es for the RPM-based packages using spec file. +# Each package contains the config file: info in their project directory, +# like /var/libcareplus/qemu/info +# echo '+ set -x' set -x @@ -15,10 +19,10 @@ die() { } usage() { - echo "Usage: build [--prebuild] [--help] [--arch ARCH] DIR" + echo "Makes kpatch'es for the RPM-based packages using spec file." + echo "Usage: libcare-pkgbuild [--prebuild] [--test] [--help] DIR" echo " -p|--prebuild prebuild project for further use" echo " -t|--test run unit and stress tests" - echo " -a|--arch ARCH target architecture(x86_64 by default)" echo " -h|--help print this message" echo " DIR directory with project's info file and other resources" } @@ -26,7 +30,6 @@ usage() { prepare() { # Parse cmdline args ACTION=build - ARCH=x86_64 PDIR= while [ "$1" != "" ]; do case $1 in @@ -36,10 +39,6 @@ prepare() { -t|--test) ACTION=test ;; - -a|--arch) - shift - ARCH=$1 - ;; -h|--help) usage exit 0 @@ -56,11 +55,8 @@ prepare() { shift done - # Export env vars that are needed during the build - SCRIPTS="$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd)" - LIBCARE_DIR="${LIBCARE_DIR:-$SCRIPTS/..}" - KPATCH_PATH="${KPATCH_PATH:-$LIBCARE_DIR/src}" - export LIBCARE_DIR KPATCH_PATH + KPATCH_PATH="$(dirname "$( which libcare-cc )" )" + export KPATCH_PATH export OLDPATH=$PATH export KPATCH_PASSTHROUGH_ASM=1 CPUS=`cat /proc/cpuinfo | grep ^processor | wc -l` @@ -70,12 +66,13 @@ prepare() { # Obtain information about the project source $PDIR/info - mkdir -p /kcdata + ROOT_ORIGINAL=$PDIR/root.original + ROOT_PATCHED=$PDIR/root.patched } clean_dirs() { echo " cleaning up" - rm -rf $KP_PROJECT_BUILD_ROOT /root/root.original /root/root.patched + rm -rf $KP_PROJECT_BUILD_ROOT $ROOT_ORIGINAL $ROOT_PATCHED } kp_prepare_env_hook() { @@ -86,17 +83,15 @@ kp_prepare_env_hook() { kp_pack_prebuilt() { echo " packing prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT" pushd $KP_PROJECT_BUILD_ROOT - tar -zcf /kcdata/$KP_PROJECT_PREBUILT \ + tar -zcf $PDIR/$KP_PROJECT_PREBUILT \ $KP_PROJECT_BUILD_ROOT \ - /root/root.original + $ROOT_ORIGINAL popd } kp_unpack_prebuilt() { echo " unpacking prebuilt $KP_PROJECT into $KP_PROJECT_PREBUILT" - tar -xf /kcdata/$KP_PROJECT_PREBUILT -C / - - yum-builddep -d 1 -y $KP_PROJECT_BUILD_ROOT/SPECS/$KP_PROJECT_SPEC + tar -xf $PDIR/$KP_PROJECT_PREBUILT -C / } kp_prepare_source_raw() { @@ -108,38 +103,32 @@ kp_prepare_source_raw() { } kp_download_source_rpm() { - mkdir -p /kcdata if test -n "$KP_PROJECT_SOURCE_URL"; then - curl $KP_PROJECT_SOURCE_URL -o /kcdata/$KP_PROJECT_SOURCE + curl $KP_PROJECT_SOURCE_URL -o $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE else - yumdownloader --source --destdir /kcdata ${KP_PROJECT_SOURCE%.src.rpm} + yumdownloader --source --destdir $KP_PROJECT_ORIG_RPMS ${KP_PROJECT_SOURCE%.src.rpm} fi } kp_prepare_source_rpm() { - rm -rf $HOME/deps + rm -rf $PDIR/deps eval yum-builddep -d 1 -y $KP_RPM_REPOS \ - --downloadonly --downloaddir=$HOME/deps \ - /kcdata/$KP_PROJECT_SOURCE + --downloadonly --downloaddir=$PDIR/deps \ + $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE mkdir -p $KP_PROJECT_BUILD_ROOT rpm -qa > $KP_PROJECT_BUILD_ROOT/all-packages.txt - ls $HOME/deps > $KP_PROJECT_BUILD_ROOT/dependencies.txt - eval yum-builddep -d 1 -y $KP_RPM_REPOS \ - /kcdata/$KP_PROJECT_SOURCE + ls $PDIR/deps > $KP_PROJECT_BUILD_ROOT/dependencies.txt + eval yum-builddep -d 1 -y $KP_RPM_REPOS \ + $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE sed -i 's/.rpm$//g' $KP_PROJECT_BUILD_ROOT/dependencies.txt - rpm -ivh /kcdata/$KP_PROJECT_SOURCE \ + rpm -ivh $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE \ --define "_topdir $KP_PROJECT_BUILD_ROOT" } -kp_prepare_source_deb() { - echo "deb support is not implemented yet" - exit 1 -} - kp_prepare_source() { - if ! test -f /kcdata/$KP_PROJECT_SOURCE; then + if ! test -f $KP_PROJECT_ORIG_RPMS/$KP_PROJECT_SOURCE; then echo " downloading source for $KP_PROJECT" kp_download_source_$KP_PROJECT_FORMAT fi @@ -147,12 +136,60 @@ kp_prepare_source() { kp_prepare_source_$KP_PROJECT_FORMAT } +patch_list_apply() { + SRC_DIR=$(cd "$(dirname "$1")" && pwd)/$(basename "$1") + PATCH_DIR=$(cd "$(dirname "$KP_PROJECT_PLIST_FILE")" && pwd) + PLIST=$PATCH_DIR/$(basename "$KP_PROJECT_PLIST_FILE") + PATCH_ID=$(echo $(basename "$KP_PROJECT_PLIST_FILE") | awk -F. '{print $1}') + if test -z "$PATCH_ID"; then + echo "Failed to get patch-id. Please check plist filename: $KP_PROJECT_PLIST_FILE" + exit 1 + fi + TEMP_PLIST=/tmp/build.kpatch/tmpplist + + if [ ! -f $PLIST ]; then + echo "File $PLIST not found" + exit 1; + fi + + echo "patching $PWD with patches from $PLIST" + + pushd $SRC_DIR # go to the directory with sources to be patched + + #in case we don't have a newline in plist + cat $PLIST > $TEMP_PLIST + echo -e "\n" >> $TEMP_PLIST + + # iterate through patches in PLIST + while read NAME + do + COMMENT=`echo $NAME | cut -c1` + if [ "$COMMENT" == "#" ]; then + continue; + fi + + if [ -z "${NAME}" ]; then + continue; + fi + + echo "Applying patch $NAME" + patch -p1 -u --fuzz=0 --batch < $PATCH_DIR/$NAME + if [ $? != 0 ]; then + echo "Failed applying patch $NAME"; popd; rm $TEMP_PLIST; exit 1 + else + echo "Successfully applied patch $NAME" + fi + done < $TEMP_PLIST + rm $TEMP_PLIST + + popd +} + kp_patch_source() { echo " patching project" - PATCH_DIR=$LIBCARE_DIR/patches #patch_list_apply requires this dir mkdir -p /tmp/build.kpatch - $SCRIPTS/patch_list_apply $KP_PROJECT_DIR $PDIR/plist $PATCH_DIR + patch_list_apply $KP_PROJECT_DIR } kp_prebuild_rpm() { @@ -170,25 +207,17 @@ kp_prebuild_rpm() { } _kp_install_orig_rpm() { - for rpmfile in $KP_ORIG_RPMS; do - pkgname="$(basename $rpmfile)" - pkgname="${pkgname%%.rpm}" - eval yumdownloader --enablerepo=base-debuginfo $KP_RPM_REPOS \ - --destdir=$HOME/rpms.orig $pkgname - done - - rpm --force -i $HOME/rpms.orig/*.rpm \ - --root=$HOME/root.original \ + rpm --force -i $1 \ + --root=$ROOT_ORIGINAL \ --nodeps --noscripts } kp_install_orig_rpm() { - _kp_install_orig_rpm + for orig_rpm in $(ls $KP_PROJECT_ORIG_RPMS | grep -v $KP_PROJECT_SOURCE); do + _kp_install_orig_rpm $KP_PROJECT_ORIG_RPMS/$orig_rpm + done } -kp_prebuild_hook() { - : -} kp_prebuild() { echo " prebuilding $KP_PROJECT" @@ -200,25 +229,25 @@ de_offset_syms() { local binary=$1 readelf -WSs $binary > $binary.symlist 2>/dev/null - $SCRIPTS/de-offset-syms.awk $binary.symlist > $binary.symlist.tmp + de-offset-syms.awk $binary.symlist > $binary.symlist.tmp sort $binary.symlist.tmp > $binary.symlist rm -f $binary.symlist.tmp } kp_sanity_check() { - pushd $HOME/root.patched + pushd $ROOT_PATCHED local targets="$(find . -perm /0111 -type f)" popd local failed="" for target in $targets; do - local original="$HOME/root.original/usr/lib/debug/$target.debug" - local patched="$HOME/root.patched/$target" + local original=`ls $ROOT_ORIGINAL/usr/lib/debug/${target}*.debug` + local patched="$ROOT_PATCHED/$target" local alloweddiff="$PDIR/$(basename "$target").symlist.diff" de_offset_syms $original if test ! -s $original.symlist; then - original="$HOME/root.original/$target" + original="$ROOT_ORIGINAL/$target" de_offset_syms $original fi @@ -241,7 +270,11 @@ kp_sanity_check() { done if test -n "$failed"; then - die "Failed sanity check for $failed" + if test "$KP_SANITY_CHECK_STRICTLY" == "yes"; then + die "Failed sanity check for $failed" + else + echo "[Warning] Failed sanity check for $failed" + fi fi } @@ -308,7 +341,7 @@ kp_check_missing_files() { } kp_install_generic() { - local root_patched="$HOME/root.patched" + local root_patched="$ROOT_PATCHED" kp_install_files $KP_PROJECT_BUILD_DIR \ $root_patched \ @@ -318,13 +351,9 @@ kp_install_generic() { } kp_install_rpm() { - kp_install_orig_rpm kp_install_generic } -kp_build_hook() { - : -} kp_build() { echo " building $KP_PROJECT" @@ -340,19 +369,22 @@ kp_build() { kp_gen_kpatch() { echo " generating kpatches" - pushd $HOME/root.patched + pushd $ROOT_PATCHED targets=$(find . -perm /0111 -type f) popd - rm -rf $HOME/${KP_PROJECT_PATCH%.*} - mkdir $HOME/${KP_PROJECT_PATCH%.*} + rm -rf $PDIR/${KP_PROJECT_PATCH%.*} + mkdir $PDIR/${KP_PROJECT_PATCH%.*} local no_patches=1 for t in $targets; do - local debug="$HOME/root.original/usr/lib/debug/$t.debug" - local patched="$HOME/root.patched/$t" + local debug=`ls $ROOT_ORIGINAL/usr/lib/debug/${t}*.debug` + local patched="$ROOT_PATCHED/$t" local buildid=$(eu-readelf -n $debug | sed -n '/Build ID:/ { s/.* //; p }') + if test -n "$KP_PROJECT_BUILD_ID"; then + buildid=$KP_PROJECT_BUILD_ID + fi if test -z "$buildid"; then continue fi @@ -363,7 +395,7 @@ kp_gen_kpatch() { chmod u+w $debug $patched - eu-unstrip "$HOME/root.original/$t" "$debug" + eu-unstrip "$ROOT_ORIGINAL/$t" "$debug" $KPATCH_PATH/kpatch_strip --strip $patched $patched.kpstripped cp $patched.kpstripped $patched.relfixup @@ -372,8 +404,8 @@ kp_gen_kpatch() { /usr/bin/strip --strip-unneeded $patched.stripped cp $patched.stripped $patched.undolink $KPATCH_PATH/kpatch_strip --undo-link $debug $patched.undolink - $KPATCH_PATH/kpatch_make -b "$buildid" $patched.undolink -o $patched.kpatch - cp $patched.kpatch $HOME/${KP_PROJECT_PATCH%.*}/$buildid.kpatch + $KPATCH_PATH/kpatch_make -b "$buildid" -i "$PATCH_ID" $patched.undolink -o $patched.kpatch + cp $patched.kpatch $PDIR/${KP_PROJECT_PATCH%.*}/$buildid.kpatch no_patches=0 done @@ -384,9 +416,7 @@ kp_gen_kpatch() { kp_pack_patch() { echo " packing patch for $KP_PROJECT into $KP_PROJECT_PATCH" - pushd $KP_PROJECT_BUILD_DIR - tar -zcf /kcdata/$KP_PROJECT_PATCH $HOME/${KP_PROJECT_PATCH%.*} - popd + tar -zcf $PDIR/$KP_PROJECT_PATCH $PDIR/${KP_PROJECT_PATCH%.*} } kp_unpack_patch() { @@ -411,11 +441,6 @@ kp_unpack_patch() { rm -fr $tmpdir } - -kp_mark_tests_fail() { - touch /kcdata/Tests-FAIL -} - overwrite_utils() { TMPBIN=$(mktemp -d --tmpdir) -- 2.24.1.windows.2