Hello World

File build-recipe-spec of Package build

#
# spec specific functions.
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
# Copyright (c) 2022 Andreas Stieger <Andreas.Stieger@gmx.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################

recipe_setup_spec() {
    spec_setup_stages "$BUILD_RPM_BUILD_STAGE"
    TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER`
    if test -z "$TOPDIR"; then
	cleanup_and_exit 1 "Error: TOPDIR empty"
    fi
    test "$DO_INIT_TOPDIR" = false || spec_init_topdir
    mkdir -p $BUILD_ROOT$TOPDIR/{BUILD,SOURCES,SPECS,SRPMS,BUILDROOT,OTHER,RPMS/noarch,RPMS/i386,RPMS/$(uname -m)}
    copy_sources "$MYSRCDIR" "$BUILD_ROOT$TOPDIR/SOURCES/"
    chown -hR "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
}

spec_get_buildtarget() {
    local args=()
    if test -n "$BUILD_FLAVOR" ; then
	args[${#args[@]}]="--buildflavor"
	args[${#args[@]}]="$BUILD_FLAVOR"
    fi
    if test -n "$OBS_PACKAGE" ; then
	args[${#args[@]}]="--obspackage"
	args[${#args[@]}]="$OBS_PACKAGE"
    fi
    queryrecipe "${args[@]}" --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" buildtarget
}

recipe_prepare_spec() {
    # fixup specfile
    args=()
    if test -n "$RELEASE" ; then
	args[${#args[@]}]="--release"
	args[${#args[@]}]="$RELEASE"
    fi
    if test -n "$BUILD_FLAVOR" ; then
	args[${#args[@]}]="--buildflavor"
	args[${#args[@]}]="$BUILD_FLAVOR"
    fi
    if test -n "$OBS_PACKAGE" ; then
	args[${#args[@]}]="--obspackage"
	args[${#args[@]}]="$OBS_PACKAGE"
    fi
    if test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" ; then
	args[${#args[@]}]="--changelog"
	args[${#args[@]}]="$BUILD_ROOT/.build-changelog"
    fi

    substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1

    # report specfile changes
    if test -f $BUILD_ROOT/.spec.new ; then
	if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT/.spec.new ; then
	    echo -----------------------------------------------------------------
	    echo "I have the following modifications for $RECIPEFILE:"
	    sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE > $BUILD_ROOT/.spec.t1
	    sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2
	    diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
	    rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
	    mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE
	else
	    rm -f $BUILD_ROOT/.spec.new
	fi
    fi

    # fix rpmrc if we are compiling for i686
    test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc
    if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
	mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586
	sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc
    fi

    # extract optflags from configuration
    queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" optflags ${BUILD_DEBUG:+debug} > $BUILD_ROOT/root/.rpmrc
    test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc

    if test -z "$ABUILD_TARGET"; then
	ABUILD_TARGET=$(spec_get_buildtarget)
	test -z "$ABUILD_TARGET" && ABUILD_TARGET=$(queryconfig target --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" )
	test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET"
    fi
}

spec_is_empty_dir() {
    local d
    for d in "$1"/* ; do
	test -e "$d" && return 1
    done
    return 0
}

spec_init_topdir() {
    local d keepbuild keepbuildroot
    case "${rpmstages[0]}" in
	-b[ci]\ --short-circuit) keepbuild=BUILD ;;
	-bb\ --short-circuit | -bl) keepbuild=BUILD keepbuildroot=BUILDROOT ;;
    esac
    test -n "$RPM_BUILD_IN_PLACE" && unset keepbuild
    if test -n "$keepbuild$keepbuildroot" ; then
	for d in $keepbuild $keepbuildroot ; do
	    spec_is_empty_dir "$BUILD_ROOT$TOPDIR/$d" && cleanup_and_exit 1 "need files in $TOPDIR/$d for '${rpmstages[0]}'"
	done
	for d in "$BUILD_ROOT$TOPDIR"/* "$BUILD_ROOT$TOPDIR"/.[^.]* ; do
	    test "$d" = "$BUILD_ROOT$TOPDIR/$keepbuild" -o "$d" = "$BUILD_ROOT$TOPDIR/$keepbuildroot" && continue
	    rm -rf "$d"
	done
    else
	rm -rf "$BUILD_ROOT$TOPDIR"
    fi
}

spec_setup_stages() {
    local stage="$1"
    test "$stage#-b[a-z]" != "$stage" && stage="${stage#-b}"        # compat
    local xstage=pciba origstage="$stage"
    case $stage in
	"")	     stage=pciba ;;
	[lr])        ;;
	[pciba])     stage="${xstage%$stage*}$stage" ;;
	[pcibalr]=)  stage="${stage%=}" ;;
	[pciba]+)    stage="${stage%+}${xstage#*${stage%+}}" ;;
	s+ | s= | s) stage=s ;;
	*)           cleanup_and_exit 1 "unknown stage '$stage'" ;;
    esac
    stage=${stage//s/a}
    # drop p/a stages in build-in-place mode unless requested
    test -n "$RPM_NOPREP" -a "$stage" != p -a "$origstage" = "${origstage/p/}" && stage="${stage#p}"
    test -n "$RPM_BUILD_IN_PLACE" -a "$stage" != a -a "$origstage" = "${origstage/[as]/}" && stage="${stage%a}"
    rpmstages=()
    case $stage in
	p | pc | pci | pcib | pciba) rpmstages[${#rpmstages[@]}]="-b${stage: -1}" ; stage= ;;
	c | ci | cib | ciba) rpmstages[${#rpmstages[@]}]="--noprep -b${stage: -1}" ; stage= ;;
    esac
    while test -n "$stage" ; do
	local opt="-b${stage:0:1}"
	case "${stage:0:1}" in
	    a)     opt="-bs" ;;
	    [cib]) opt="$opt --short-circuit" ;;
	esac
	rpmstages[${#rpmstages[@]}]="$opt"
	stage=${stage:1}
    done
}

recipe_build_spec() {
    rpmbuild=rpmbuild
    test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm
    test "$BUILDTYPE" = debbuild && rpmbuild=debbuild

    HAVE_DYNAMIC_BUILDREQUIRES=
    if grep -E '^%generate_buildrequires' "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" >/dev/null ; then
	HAVE_DYNAMIC_BUILDREQUIRES=true
    fi

    # XXX: move _srcdefattr to macro file?
    rpmbopts=("--define" "_srcdefattr (-,root,root)")
    if test "$DO_CHECKS" != true ; then
	if chroot "$BUILD_ROOT" "$rpmbuild" --nocheck --help >/dev/null 2>&1; then
	    rpmbopts[${#rpmbopts[@]}]="--nocheck"
	else
	    echo "warning: --nocheck is not supported by this $rpmbuild version"
	fi
    fi
    if test "$rpmbuild" == "debbuild" ; then
	rpmbopts[${#rpmbopts[@]}]="-vv"
    fi
    if test "$rpmbuild" == "rpmbuild" ; then
	    # use only --nosignature for rpm v4
	rpmbopts[${#rpmbopts[@]}]="--nosignature"
    fi
    if test -n "$RPM_BUILD_IN_PLACE" ; then
	rpmbopts[${#rpmbopts[@]}]="--build-in-place"
    fi
    if test -n "$ABUILD_TARGET" ; then
	rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET"
    fi
    # sysroot packages are not in the database
    if test -n "$ABUILD_TARGET" -a -d "$BUILD_ROOT/.build.sysroot" ; then
	rpmbopts[${#rpmbopts[@]}]="--nocheck"
	rpmbopts[${#rpmbopts[@]}]="--nodeps"
    fi
    if test -n "$BUILD_DEBUG" ; then
	rpmbopts[${#rpmbopts[@]}]='--define'
	rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1"
    fi
    # OBS Debuginfo flag support for Red Hat family
    if test -z "$BUILD_DEBUG" ; then
        # only when rpmbuild knows --undefine
        if chroot $BUILD_ROOT $rpmbuild --undefine --help >& /dev/null; then
            rpmbopts[${#rpmbopts[@]}]='--undefine'
            rpmbopts[${#rpmbopts[@]}]="_enable_debug_packages"
        fi
    fi
    if test -n "$DISTURL" ; then
	rpmbopts[${#rpmbopts[@]}]='--define'
	rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL"
    fi
    if test -n "$RSYNCDONE" ; then
	rpmbopts[${#rpmbopts[@]}]='--define'
	rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1"
    fi

    buildrootoverride=$(queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags rpm-buildroot-override)
    if test -n "$buildrootoverride" ; then
	rpmbopts[${#rpmbopts[@]}]='--buildroot'
	rpmbopts[${#rpmbopts[@]}]="$buildrootoverride"
    fi

    GEN_BUILDREQS_PACKS=()
    if test -n "$HAVE_DYNAMIC_BUILDREQUIRES" ; then
	# query dynamic build requires
	rm -f "$BUILD_ROOT$TOPDIR/SRPMS/"*.buildreqs.nosrc.rpm
	toshellscript $rpmbuild \
		--nodeps \
		"${definesnstuff[@]}" \
		-br \
		"${rpmbopts[@]}" \
		"$TOPDIR/SOURCES/$RECIPEFILE" \
		> $BUILD_ROOT/.build.command
	chmod 755 $BUILD_ROOT/.build.command
	chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null
	st=$?
	if test "$st" != 0 -a "$st" != 11 ; then
	    return
	fi
	: > $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs
	if test "$st" = 11 ; then
	    reqsfile=
	    for i in "$BUILD_ROOT$TOPDIR/SRPMS/"*.buildreqs.nosrc.rpm ; do
		test -f "$i" && reqsfile=${i##*/}
	    done
	    test -n "$reqsfile" || cleanup_and_exit 1 "no buildreqs.nosrc.rpm file?"
	    chroot $BUILD_ROOT rpm -qp --requires "$TOPDIR/SRPMS/$reqsfile" | grep -v '^rpmlib(' | sort -u > $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp
	    chroot $BUILD_ROOT rpmspec -q --srpm --requires "$TOPDIR/SOURCES/$RECIPEFILE" >> $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp || cleanup_and_exit 1 "rpm -q --spec failed"
	    sort < $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp | uniq -u > $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs
	    rm -f $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp
	    while read db ; do
		GEN_BUILDREQS_PACKS[${#GEN_BUILDREQS_PACKS[@]}]="$db"
	    done < $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs
	fi
	rm -f "$BUILD_ROOT$TOPDIR/SRPMS/"*.buildreqs.nosrc.rpm
    fi

    for rpmstage in "${rpmstages[@]}" ; do
	# su involves a shell which would require even more
	# complicated quoting to bypass than this
	toshellscript $rpmbuild \
		"${definesnstuff[@]}" \
		$rpmstage \
		"${rpmbopts[@]}" \
		"$TOPDIR/SOURCES/$RECIPEFILE" \
		> $BUILD_ROOT/.build.command
	chmod 755 $BUILD_ROOT/.build.command
	check_exit
	local build_command="/.build.command"
	test -n "$RPM_BUILD_IN_PLACE" && build_command="cd /.build.packages/SOURCES && $build_command"
	chroot $BUILD_ROOT su -c "$build_command" - $BUILD_USER < /dev/null
	st=$?
	test "$st" = 0 || break
    done
    test "$st" = 0 && BUILD_SUCCEEDED=true
    test "$st" = 11 -a -n "$HAVE_DYNAMIC_BUILDREQUIRES" && BUILD_SUCCEEDED=genbuildreqs
}

recipe_resultdirs_spec() {
    echo RPMS SRPMS
}

recipe_cleanup_spec() {
    :
}

recipe_unpack_srcrpm() {
    local srpm="$1"
    test -n "$LIST_STATE" || echo "processing src rpm $srpm ..."
    MYSRCDIR="$BUILD_ROOT/.build-srcdir"
    rm -rf "$MYSRCDIR"
    mkdir -p "$MYSRCDIR"
    cd "$MYSRCDIR" || cleanup_and_exit 1
    $BUILD_DIR/unrpm -q "$srpm" || cleanup_and_exit 1 "Could not unpack $srpm."
    for RECIPEFILE in *.spec ; do : ; done
    RECIPEPATH="$MYSRCDIR/$RECIPEFILE"
}

# post build functions... move somewhere else?

recipe_check_file_owners() {
    echo "... checking for files with abuild user/group"
    BADFILE=
    while read un gn fn ; do
        if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then
            echo "  $un $gn $fn"
            BADFILE=true
        fi
    done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS)
    if test -n "$BADFILE" ; then
        cleanup_and_exit 1 "please fix your filelist (e.g. add defattr)"
    fi
}

recipe_run_rpmlint() {
    # SUSE builds are using a special rpmlint binary which is not
    # pulling in additional dependencies
    local rpmlint="/opt/testing/bin/rpmlint"
    if ! test -x "$BUILD_ROOT$rpmlint" ; then
        # default rpmlint place as fallback
        rpmlint="/usr/bin/rpmlint"
    fi
    if ! test -x "$BUILD_ROOT$rpmlint" ; then
	return
    fi
    LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \
	\( -name "*-debuginfo-*" -o -name "*-debugsource-*" \
	-o -name "*-32bit-*" -o -name "*-64bit-*" \
	-o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \
	-o -type f -name '*.rpm' -print))
    SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm"))
    echo 
    echo "RPMLINT report:"
    echo "==============="
    rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log
    rm -f "$BUILD_ROOT$rpmlint_logfile"
    ret=0
    chroot $BUILD_ROOT su -s $rpmlint "$BUILD_USER" -- \
	    --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
	    ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > >(tee "$BUILD_ROOT$rpmlint_logfile") 2>&1 || ret=1
    echo
    if test "$ret" = 1 ; then 
	cleanup_and_exit 1
    fi   
}

recipe_compare_oldpackages() {
    if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then 
	echo "... comparing built packages with the former built"
	if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then 
	    chroot $BUILD_ROOT touch /.build/.same_result_marker
	    # XXX: dirty build service hack. fix bs_worker. Search for
	    # 'same_result_marker' for traces of a first try to get rid of this
	    if test -n "$REASON" -a -n "$DISTURL" ; then 
		exitcode=2
	    fi
	fi
    fi   
}

recipe_create_deltarpms() {
    if test -x "$BUILD_ROOT/usr/bin/makedeltarpm" -a -x $BUILD_ROOT/usr/lib/build/mkdrpms ; then
	echo "... creating delta rpms"
	ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS")
	chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}"
    fi
}