summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rwxr-xr-xbin/addbr92
-rwxr-xr-xbin/cleanbuild-docker.sh198
-rwxr-xr-xbin/cleanbuild-vserver.sh550
-rwxr-xr-xbin/cleanpoldekcache58
-rwxr-xr-xbin/cleanup-la6
-rwxr-xr-xbin/findbr748
-rw-r--r--bin/findbr-ac2br420
-rwxr-xr-xbin/findunusedbr101
-rwxr-xr-xbin/fixfreq54
-rwxr-xr-xbin/multibuild151
-rwxr-xr-xbin/teeboth67
11 files changed, 2445 insertions, 0 deletions
diff --git a/bin/addbr b/bin/addbr
new file mode 100755
index 0000000..6ab3dd4
--- /dev/null
+++ b/bin/addbr
@@ -0,0 +1,92 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+my $fname = shift @ARGV or die;
+my $add = shift @ARGV or die;
+my $msg = shift @ARGV || "requested";
+
+$SIG{__WARN__} = sub
+{
+ local $_ = shift;
+ chomp;
+ print STDERR "\033[32;1m" . $_ . "\033[0m\n"
+};
+
+warn "Adding: $add\n";
+
+my $file = $fname;
+$file = "$ENV{HOME}/rpm/packages/$fname/$fname.spec"
+ unless -r $file;
+-r $file or die "Can't read $file";
+
+open FILE, "<", $file;
+my @in = <FILE>;
+close FILE;
+
+my $brm = qr/#?(?:%\{!?\?with_\S+:)?\s*BuildRequires:\s*(\S+)\s*(?:(>|>=|==|<=|<).*)?\}?/i;
+foreach ( @in ) {
+ if ( /^$brm$/o ) {
+ if ( $1 eq $add ) {
+ warn "$add already on the list\n";
+ exit(1);
+ }
+ }
+
+}
+
+my @out;
+while ( $_ = shift @in ) {
+ if ( /^\s*(build(requires|root|conflicts|arch)|requires(\(.*\))?|provides|conflicts|obsoletes|excludearch):/i ) {
+ unshift @in, $_;
+ last;
+ }
+ push @out, $_;
+}
+
+my @buf;
+while ( $_ = shift @in ) {
+ if ( /^%if/ ) {
+ push @buf, $_;
+ my $i = 1;
+ while ( $_ = shift @in ) {
+ push @buf, $_;
+ if ( /^%if/ ) {
+ $i++;
+ } elsif ( /^%endif/ ) {
+ $i--;
+ last unless $i;
+ }
+ }
+
+ } elsif ( /^$brm$/o ) {
+ my $name = $1;
+ push @buf, $_;
+
+ if ( $add lt $name ) {
+ push @out, "# AUTO: $msg\n";
+ push @out, "BuildRequires:\t$add\n";
+ $add = undef;
+ }
+ push @out, @buf;
+ @buf = ();
+ } elsif ( /^\s*$/ or /^\s*#/ ) {
+ push @buf, $_;
+ } else {
+ push @buf, $_;
+ push @out, "# AUTO: $msg\n";
+ push @out, "BuildRequires:\t$add\n";
+ last;
+
+ }
+ last unless $add;
+}
+
+push @out, @buf;
+push @out, @in;
+
+
+open FILE, ">", $file;
+print FILE @out;
+close FILE;
diff --git a/bin/cleanbuild-docker.sh b/bin/cleanbuild-docker.sh
new file mode 100755
index 0000000..861c74d
--- /dev/null
+++ b/bin/cleanbuild-docker.sh
@@ -0,0 +1,198 @@
+#!/bin/sh
+set -eu
+
+PROGRAM=${0##*/}
+
+# defaults
+: ${PACKAGE_NAME=''}
+: ${NETWORKING=false}
+: ${TRACING=false}
+: ${WITH=}
+: ${WITHOUT=}
+: ${KEEP_CONTAINER=false}
+: ${TMPFS="4G"}
+
+dir=$(pwd)
+image=registry.gitlab.com/pld-linux/cleanbuild
+topdir=$dir/rpm
+home=/home/builder
+
+die() {
+ echo >&2 "$0: $*"
+ exit 1
+}
+
+is_no() {
+ # Test syntax
+ if [ $# = 0 ]; then
+ return 2
+ fi
+
+ case "$1" in
+ no|No|NO|false|False|FALSE|off|Off|OFF|N|n|0)
+ # true returns zero
+ return 0
+ ;;
+ *)
+ # false returns one
+ return 1
+ ;;
+ esac
+}
+
+tmpfs() {
+ if is_no "${TMPFS:-true}" || [ "$TMPFS" = "0" ]; then
+ return
+ fi
+
+ echo "--tmpfs $home/rpm/BUILD:rw,exec,nosuid,size=$TMPFS"
+}
+
+create_container() {
+ # cleanup first
+ docker kill $name >/dev/null 2>&1 || :
+ docker rm $name >/dev/null 2>&1 || :
+
+ install -d $topdir/logs
+
+ # start the container
+ docker run --name=$name -d \
+ -w $home \
+ -v $topdir:$home/rpm \
+ -v $dir:$home/cleanbuild \
+ -v $dir/cache/poldek:/var/cache/poldek \
+ -v $dir/cache/ccache/$PACKAGE_NAME:$home/.ccache \
+ --label=cleanbuild=$name \
+ $(tmpfs) \
+ $image >/dev/null
+
+ # set the homedir
+ docker exec --user=root -w / $name usermod -d $home builder
+
+ # these paths need to be accessible for builder
+ docker exec --user=root -w / $name sh -c "cd $home && chown builder:builder rpm rpm/logs rpm/BUILD .ccache"
+
+ if [ ! -d $topdir/rpm-build-tools ]; then
+ docker exec $name builder --init-rpm-dir
+ fi
+}
+
+package_prepare() {
+ # fetch sources and install deps
+ if [ -d $topdir/packages/$PACKAGE_NAME ]; then
+ # chown, as it might be different owner (root) modified outside container
+ docker exec --user=root -w / $name chown -R builder:builder $home/rpm/packages/$PACKAGE_NAME
+ fi
+ docker exec $name builder -g $PACKAGE_NAME
+
+ # prevent network access like pld builders do
+ $NETWORKING || docker exec --user=root -w / $name setfacl -m u:builder:--- /etc/resolv.conf
+
+ git_tag=$(GIT_DIR=$topdir/packages/$PACKAGE_NAME/.git git describe --tags --always)
+ buildlog=rpm/logs/${git_tag#auto/*/}.log
+}
+
+package_build() {
+ # create default args for builder
+ set -- -nn ${WITH:+--with "${WITH# }"} ${WITHOUT:+--without "${WITHOUT# }"} "$PACKAGE_NAME"
+
+ while true; do
+ # install deps
+ docker exec $name builder -g -R "$@"
+ # remove .la dependencies
+ docker exec --user=root -w / $name $home/cleanbuild/bin/cleanup-la
+ # reset findunusedbr state after deps install
+ docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec
+
+ # actual build
+ docker exec $name cleanbuild/bin/teeboth $buildlog builder -bb --define '__spec_clean_body %{nil}' "$@" && rc=$? || rc=$?
+
+ findbr=$PACKAGE_NAME.findbr.log
+ builddir=$(docker exec $name sh -c 'test ! -d rpm/BUILD/* || echo rpm/BUILD/*')
+ if [ -z "$builddir" ]; then
+ echo >&2 "No build dir. Build failed?"
+ exit 6
+ fi
+ # need root to run poldek
+ docker exec --user=root -w / $name sh -c "cd $home && cleanbuild/bin/findbr $builddir $buildlog" > $findbr
+
+ installed_something=false
+ while read pkg msg; do
+ ./addbr rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec "$pkg" "$msg" || continue
+ installed_something=true
+ done < $findbr
+ rm -f $findbr
+
+ # go for another try
+ $installed_something && continue
+
+ docker exec --user=root -w / $name $home/cleanbuild/bin/findunusedbr -c / $home/rpm/packages/$PACKAGE_NAME/$PACKAGE_NAME.spec
+
+ if [ $rc -eq 0 ] && ! $KEEP_CONTAINER; then
+ # finished ok, cleanup
+ docker kill $name >/dev/null && docker rm $name >/dev/null || :
+ fi
+
+ # propagate error
+ exit $rc
+ done
+}
+
+parse_options() {
+ local t
+ t=$(getopt -o 'x' --long 'network,no-tmpfs,notmpfs,tmpfs:,keep-container,with:,without:' -n "$PROGRAM" -- "$@")
+ [ $? != 0 ] && exit $?
+ eval set -- "$t"
+
+ while :; do
+ case "$1" in
+ -x)
+ TRACING=true
+ ;;
+ --network)
+ NETWORKING=true
+ ;;
+ --no-tmpfs|--notmpfs)
+ TMPFS=false
+ ;;
+ --tmpfs)
+ shift
+ TMPFS="$1"
+ ;;
+ --keep-container)
+ KEEP_CONTAINER=true
+ ;;
+ --with)
+ shift
+ WITH="$WITH $1"
+ ;;
+ --without)
+ shift
+ WITHOUT="$WITHOUT $1"
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ die "Internal error: [$1] not recognized!"
+ ;;
+ esac
+ shift
+ done
+
+ test "$#" -eq 1 || die "package not specified or excess arguments"
+ PACKAGE_NAME="${1%.spec}"
+}
+
+main() {
+ parse_options "$@"
+
+ $TRACING && set -x
+ local name="cleanbuild-$PACKAGE_NAME"
+ create_container
+ package_prepare
+ package_build
+}
+
+main "$@"
diff --git a/bin/cleanbuild-vserver.sh b/bin/cleanbuild-vserver.sh
new file mode 100755
index 0000000..5429a54
--- /dev/null
+++ b/bin/cleanbuild-vserver.sh
@@ -0,0 +1,550 @@
+#!/usr/bin/sudo /bin/sh
+
+RPMS_FROM="$HOME/rpm/cleanRPMS.repo"
+DEST="th"
+SRC="-n th-x86_64-test"
+SUFFIX=""
+CACHEDIR="$PWD/poldekcache"
+RPMMACROS=""
+BUILDERRC=""
+IGNORE=""
+CHROOTSIZE="4G"
+ignore() { IGNORE="$IGNORE $*"; }
+NODEBUG=true
+CLEANAFTER=false
+FORCE_UMOUNT=false
+NOREBUILDDB=true
+MULTILIB=false
+# Whatever you set here as value, consider that it may not be shorter than
+# /usr/lib/debug (or /usr/src/debug) for debuginfo to work.
+# You get "Only dest dir longer than base dir not supported" error otherwise.
+BUILDDIR=/usr/src/BUILD
+
+[ -r .cleanbuildrc ] && . ./.cleanbuildrc
+
+[ -z "$USER" ] && echo "USER not defined" && exit 1
+[ "$USER" = "root" ] && echo "USER must not be root" && exit 1
+
+export LC_ALL=C
+unset LANGUAGE
+unset LANG
+
+usage() {
+ [ $# -gt 0 ] && echo "$*"
+ echo "Usage:"
+ echo " ./cleanbuild [cleanbuild options] specname [builder options]"
+ echo " ./build [cleanbuild options] specname [builder options]"
+ echo " ./clean [cleanbuild options]"
+ echo " ./create [cleanbuild options]"
+ echo " ./install [cleanbuild options] packages"
+ echo ""
+ echo "cleanbuild options:"
+ echo " -32, -64, -th-i486 - select architecture"
+ echo " --cleanafter | -ca - clean after build"
+ echo " --forceumount | -fu - force umount tmpfs"
+ echo " --debug - enable debug"
+ echo " --network - allow build to use networking"
+ echo " -a, -b, -c, -d, -e - select alternative chroot directory"
+ exit 1
+}
+
+FETCH=false
+CLEAN=false
+CREATE=false
+BUILD=false
+NETWORK=false
+INSTALL=false
+
+case "$0" in
+ *clean)
+ CLEAN=exit_after
+ ;;
+ *cleanbuild)
+ FETCH=true
+ CLEAN=true
+ CREATE=true
+ BUILD=true
+ ;;
+ *build)
+ CREATE=true
+ BUILD=true
+ ;;
+ *create)
+ CLEAN=true
+ CREATE=exit_after
+ ;;
+ *install)
+ CREATE=true
+ INSTALL=exit_after
+ ;;
+ *)
+ usage
+ ;;
+esac
+
+while [ $# -gt 0 ]; do
+ OPT="${1}"
+ case "$OPT" in
+ -32) OPT="-th-i686" ;;
+ -64) OPT="-th-x86_64" ;;
+ -th-32) OPT="-th-i686" ;;
+ -th-64) OPT="-th-x86_64" ;;
+ -ti-32) OPT="-ti-i686" ;;
+ -ti-64) OPT="-ti-x86_64" ;;
+ -ac) OPT="-ac-amd64" ;;
+ -ac-32) OPT="-ac-i586" ;;
+ -ac-64) OPT="-ac-amd64" ;;
+ esac
+
+ V="${OPT#-}"
+ case "$OPT" in
+ -th-i[46]86 | -th-x86_64)
+ DEST="$V"
+ SRC="-n $V-ready"
+ ;;
+ -th-i[46]86-test | -th-x86_64-test)
+ DEST="$V"
+ SRC="-n $V"
+ ;;
+ -ti-i[56]86 | -ti-x86_64)
+ DEST="$V"
+ SRC="-n $V-ready"
+ ;;
+ -ti-i[56]86-test | -ti-x86_64-test)
+ DEST="$V"
+ SRC="-n $V"
+ ;;
+ -ac-amd64 | -ac-i[356]86 | -ac-athlon)
+ DEST="$V"
+ SRC="-n $V-ready"
+ ;;
+ -[1-9]G | -[1-9][0-9]G )
+ CHROOTSIZE="$V"
+ ;;
+ --cleanafter | -ca)
+ CLEANAFTER=true
+ ;;
+ --debug)
+ NODEBUG=false
+ ;;
+ --network)
+ NETWORK=true
+ ;;
+ --forceumount | -fu)
+ FORCE_UMOUNT=true
+ ;;
+ -[a-e])
+ SUFFIX="$OPT"
+ ;;
+ -~*)
+ SUFFIX="$V"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+if $BUILD; then
+ [ $# -ne 0 ] || usage
+ build_pkg="${1}"
+ build_pkg="${build_pkg%/}"
+ build_pkg="${build_pkg%.spec}"
+ build_pkg="${build_pkg#*/}"
+ shift
+
+ builder_options="$*"
+fi
+
+$NODEBUG || set -x
+
+CHNAME="chroot-$DEST$SUFFIX"
+CHDIR="$PWD/$CHNAME"
+CHHOME="/home/users/$USER"
+
+warn()
+{
+ echo -n -e "\033[31;1m" >&2
+ echo -n "$*" >&2
+ echo -e "\033[0m" >&2
+}
+
+die()
+{
+ code=$1
+ shift
+ warn "$*"
+ exit $code
+}
+
+info()
+{
+ echo -n -e "\033[32m"
+ echo -n "$*"
+ echo -e "\033[0m"
+}
+
+title()
+{
+ [ -t 1 ] || return 0
+ local msg="$CHNAME: $build_pkg: $*"
+ case "$TERM" in
+ cygwin|xterm*)
+ echo -ne "\033]1;$msg\007\033]2;$msg\007" >&2
+ ;;
+ screen*)
+ echo -ne "\033]0;$msg\007" >&2
+ ;;
+ esac
+ return 0
+}
+
+exit_after()
+{
+ return 0;
+}
+
+check_running()
+{
+ [ -r "$CHDIR/.pid" ] || return
+ PID=$(< "$CHDIR/.pid")
+ if [ -d /proc/$PID ]; then
+ die 10 "Another process ($PID) already running in $CHNAME"
+ fi
+}
+
+for D in installed buildlogs $CACHEDIR; do
+ if [ ! -d "$D" ]; then
+ info "mkdir $D"
+ su $USER -c "mkdir -p $D" || die 13 "Cannot create work directories"
+ fi
+done
+
+ignore \
+ upstart\* \
+ upstart \
+ compat-\* \
+ systemd-init \
+ hhvm \
+ vserver-packages \
+ xorg-driver-video-fglrx\* xorg-driver-video-nvidia\* xorg-xserver-xgl-libGL \
+ xorg-driver-video-vboxvideo \
+ xorg-data-xbitmaps \
+ compat-gcc\* \
+ libpng1\* \
+ libjpeg libjpeg-devel \
+ freetype1-devel-* \
+ anacron fcron hc-cron \
+ masqmail msmtp-sendmail omta postfix sendmail ssmtp nail-mail nullmailer \
+ ghostscript-esp \
+ perl-Scalar-List-Utils \
+ perl-ExtUtils-Install \
+ phonon-backend-mplayer phonon-backend-vlc \
+ libgcj libgcj-devel \
+ icedtea6-jre icedtea6-jdk \
+ icedtea7-jre icedtea7-jdk \
+ java-sun-jre java-sun-jdk \
+ java5-sun-jre java5-sun-jdk \
+ oracle-java7-jre oracle-java7-jdk \
+ gnome-menus \
+ gnome-speech-driver-festival gnome-speech-driver-speech-dispatcher
+
+if ! $MULTILIB; then
+ ignore '*-multilib-*'
+fi
+
+rebuilddb()
+{
+ $NOREBUILDDB || rpm --root=$CHDIR --rebuilddb
+}
+
+poldek()
+{
+ $NODEBUG || set -x
+ rebuilddb
+ /usr/bin/poldek $SRC -s "$RPMS_FROM" -r "$CHDIR" "--cachedir=$CACHEDIR" --conf=$PWD/poldekconf/poldek.conf "$@"
+}
+
+
+build_umount()
+{
+ for DIR in $CHHOME/rpm $CHHOME dev proc sys; do
+ [ -d $CHDIR/$DIR ] && umount $CHDIR/$DIR
+ done
+}
+
+build_remove_root()
+{
+ $NODEBUG || set -x
+ if $FORCE_UMOUNT; then
+ # safety checks.
+ [ "$CHDIR" ] || exit 1
+ [ -d "$CHDIR" ] || exit 1
+ rm -rf $CHDIR/*
+ umount -l $CHDIR
+ else
+ umount $CHDIR
+ fi
+ rmdir $CHDIR
+}
+
+clean()
+{
+ info "Cleaning $CHNAME"
+ title "cleaning chroot"
+ build_umount
+ build_remove_root
+}
+
+build_prepare_root()
+{
+ title "preparing chroot"
+ set -e
+ $NODEBUG || set -x
+ mkdir $CHDIR
+ mount -t tmpfs -o size=$CHROOTSIZE,relatime /dev/null $CHDIR
+ echo $$ > $CHDIR/.pid
+
+ rpmversion=$(rpm -E '%(v=%{_rpmversion}; IFS=.; set -- $v; echo $1)')
+ rpmversion=${rpmversion:-4}
+
+ if [ "$rpmversion" -ge 5 ]; then
+ rpm --root=$CHDIR -qa
+ else
+ rpm --root=$CHDIR --initdb
+ fi
+ poldek --up || :
+ poldek -O "ignore=$IGNORE" -u rpm-build pwdutils coreutils time util-linux git-core gawk
+ echo Poldek exit: $?
+
+ for DIR in dev proc sys; do
+ # We need to create these directories manually, because they are marked
+ # as netsharedpath in cleanbuild poldek.conf
+ mkdir $CHDIR/$DIR
+ mount -o bind /$DIR $CHDIR/$DIR
+ done
+
+ # group 'users' may already exist, so ignore errors
+ chroot $CHDIR groupadd $(id $USER -gn) -g$(id $USER -g) || :
+ chroot $CHDIR useradd -m $USER -u$(id $USER -u) -g $(id $USER -gn)
+
+ # replicate files which already belong to $USER
+ # so they will have correct owner and permissions
+ cp -a $CHDIR/$CHHOME/{tmp,rpm}
+ cp -a $CHDIR/$CHHOME/tmp $CHDIR$BUILDDIR
+
+ cp -a $CHDIR/$CHHOME/{.bashrc,.rpmmacros}
+ cat <<-EOM > $CHDIR/$CHHOME/.rpmmacros
+ %_builddir $BUILDDIR
+ %buildroot %{_builddir}/%{name}-%{version}-root-%(id -u -n)
+ %_rpmdirname cleanRPMS
+ %_rpmdir %{expand:%%global _rpmdir %([ -d %{_topdir}/../%{_rpmdirname} ] && (cd %{_topdir}/../%{_rpmdirname}; pwd) || echo %{_topdir}/%{_rpmdirname})}%_rpmdir
+ %distribution CleanPLD
+ %_binary_payload w1.gzdio
+EOM
+ [ -z "$RPMMACROS" ] || echo "$RPMMACROS" >> $CHDIR/$CHHOME/.rpmmacros
+
+ cp -a $CHDIR/$CHHOME/{.bashrc,.builderrc}
+ cat <<-'EORC' > $CHDIR/$CHHOME/.builderrc
+ TITLECHANGE=no
+EORC
+ [ -z "$BUILDERRC" ] || echo "$BUILDERRC" >> $CHDIR/$CHHOME/.builderrc
+
+ set +e
+}
+
+build_mount_home()
+{
+ $NODEBUG || set -x
+ mount -o bind $HOME/rpm $CHDIR/$CHHOME/rpm
+
+ # ensure RPMS dir is available
+ chroot $CHDIR su $USER -c 'mkdir -p $(rpm -E %_rpmdir)'
+}
+
+print_installed()
+{
+ echo=$1
+ if [ -r installed/$build_pkg ]; then
+ $echo "$(cat installed/$build_pkg | awk '{print $1}' | sort -u \
+ | awk '{br=br ", " $1} END{gsub(/^, /, "- BR: ", br ); print br}')"
+ cat installed/$build_pkg
+ fi
+}
+
+addlist()
+{
+ LIST="$1"
+
+ print_installed info
+
+ return
+ echo "*** $build_pkg $(date --rfc-3339=seconds) ***" >> $LIST
+ print_installed echo >> $LIST
+}
+
+builddie()
+{
+ LIST="$1"; shift
+ CODE="$1"; shift
+ MSG="$*"
+
+ rm -f $CHDIR/.pid
+
+ $CLEANAFTER && clean
+ title "failed !"
+
+ addlist "ERROR_$LIST"
+ die $CODE "$MSG"
+}
+
+LAST_INSTALL=""
+poldek_install()
+{
+ local I="$1" ret
+ # Nothing to install
+ [ -n "$I" ] || return 1
+ # Installing same packets second time
+ [ "$LAST_INSTALL" != "$I" ] || return 1
+ LAST_INSTALL="$I"
+
+ info "Installing" $I
+ poldek -O "ignore=$IGNORE" -u $I | tee $$.poldek_install
+ ret=
+ if grep -q "Preparing... ##################################################" $$.poldek_install \
+ && ! grep -q "file .* from install of .* conflicts with file from package" $$.poldek_install
+ then
+ info "Poldek:" $I "installed"
+ ret=0
+ elif grep -q "Nothing to do" $$.poldek_install; then
+ warn "Poldek:" $I "installed already"
+ ret=1
+ fi
+ rm $$.poldek_install
+ [ -n "$ret" ] && return $ret
+
+ # try harder
+ info "Poldek install failed, retry without ignore"
+ poldek -u $I && return 0
+ info "Poldek install failed, retry once more without ignore"
+ poldek -u $I && return 0
+ warn "Poldek:" "Could not install" $I
+ return 1
+}
+
+maybe_call()
+{
+ local cond="$1"; shift
+ local func="$1"; shift
+
+ [ $cond = "false" ] && return
+ "$func" "$@"
+ [ $cond = "exit_after" ] && exit
+}
+
+fetch()
+{
+ info "Fetching $build_pkg"
+ title "fetch"
+ $NODEBUG || set -x
+ su $USER -c "$HOME/rpm/packages/builder -g $build_pkg $builder_options" \
+ || die 11 "Fetch failed"
+}
+
+create()
+{
+ $NODEBUG || set -x
+ su $USER -c "poldek -s $RPMS_FROM --mkidx"
+
+ if [ ! -d $CHDIR ]; then
+ info "Preparing $CHNAME"
+ build_prepare_root
+ build_mount_home
+ fi
+}
+
+
+info "Configured Poldek sources"
+poldek -l
+
+maybe_call $FETCH fetch
+
+check_running
+
+maybe_call $CLEAN clean
+
+maybe_call $CREATE create
+
+echo $$ > $CHDIR/.pid
+
+maybe_call $INSTALL poldek_install "$*"
+
+maybe_call $NETWORK cp -bf /etc/resolv.conf $CHDIR/etc/
+
+$BUILD || exit
+
+if [ -p /tmp/fixfreq ]; then
+ echo $$ > /tmp/fixfreq
+fi
+
+while true; do
+ info "Building $build_pkg in $CHNAME"
+ rebuilddb
+ ./bin/cleanup-la $CHDIR
+ buildlog="buildlogs/$build_pkg"
+ if [ -r $buildlog ]; then
+ i=1
+ while [ -r $buildlog.$i ]; do
+ i=$((i+1))
+ done
+ info "moving $buildlog to $buildlog.$i"
+ mv $buildlog $buildlog.$i
+ fi
+ ./bin/findunusedbr -c $CHDIR $HOME/rpm/packages/$build_pkg/$build_pkg.spec
+ title "building"
+ ./bin/teeboth $buildlog chroot $CHDIR su $USER -c "$CHHOME/rpm/packages/builder -nn --define '_enable_debug_packages 0' -bb $build_pkg $builder_options"
+ ECODE=$?
+
+ if grep -q "error: Failed build dependencies:" $buildlog; then
+ SEARCH=$(cat $buildlog | awk '/^Error:/ { p = 0 }; { if ( p ) { f="p"; if ( $1 ~ /^\// ) f="f"; printf "search -%c %s; ", f, $1; } }; /error: Failed build dependencies:/ { p = 1 }')
+ INSTALL=$(poldek -O "ignore=$IGNORE" --shcmd="$SEARCH" | awk '{ if ( p ) { print; p = 0; } } / package\(s\) found:$/ { p = 1 }' | sed 's/^\(.*\)-.*-.*$/\1/' | sort -u)
+
+ if poldek_install "$INSTALL"; then
+ info "Deps installed"
+ continue
+ else
+ addlist ERROR_BRINSTALL
+ die 4 "Cannot install BRs"
+ fi
+ fi
+
+ ./bin/findbr $CHDIR/$BUILDDIR $buildlog > $$.installed
+ installed_something=false
+ while read pkg msg; do
+ if poldek_install $pkg; then
+ info "findbr:" $pkg "installed"
+ echo "$pkg $msg" >> installed/$build_pkg
+ ./bin/addbr $build_pkg "$pkg" "$msg"
+ installed_something=true
+ else
+ warn "findbr:" $pkg "not installed"
+ fi
+ done < $$.installed
+ rm -f $$.installed
+ $installed_something && continue
+
+ if [ $ECODE -eq 0 ]; then
+ $CLEANAFTER && clean
+ addlist BUILT_OK
+ ./bin/findunusedbr $CHDIR $HOME/rpm/packages/$build_pkg/$build_pkg.spec
+ info "$build_pkg built OK !"
+ title "OK !"
+ exit 0
+ else
+ builddie UNKNOWN 1 "Got error but dunno what to do !"
+ fi
+done
+
+
+# vim: ts=4 sw=4 filetype=sh
diff --git a/bin/cleanpoldekcache b/bin/cleanpoldekcache
new file mode 100755
index 0000000..24bd318
--- /dev/null
+++ b/bin/cleanpoldekcache
@@ -0,0 +1,58 @@
+#!/usr/bin/sudo /bin/sh
+
+CACHEDIR="$PWD/poldekcache"
+
+ignore() { }
+[ -r .cleanbuildrc ] && . ./.cleanbuildrc
+
+export LC_ALL=C
+unset LANGUAGE
+unset LANG
+
+cd "$CACHEDIR" || exit 1
+SIZE_IN=$(du -s . | sed 's/\t.*//')
+
+cleandir()
+{
+ DIR="$1"
+ /usr/bin/poldek --skip-installed -s "$DIR" --cachedir="$CACHEDIR" \
+ --shcmd="ls" > cleanpoldekcache.pkgs
+ for PKG in $(ls $DIR); do
+ case "$PKG" in
+ dirindex.pndir.tndb* | packages.ndir.*)
+ ;;
+ *)
+ if ! grep -q "${PKG%%.rpm}" cleanpoldekcache.pkgs; then
+ rm -v $DIR/$PKG
+ fi
+ ;;
+ esac
+ done
+ rm cleanpoldekcache.pkgs
+}
+
+for FILE in *; do
+ case "$FILE" in
+ ftp*.packages.i|http*.packages.i)
+ echo "removing $FILE if empty"
+ rmdir -v "$FILE"
+ ;;
+ ftp*|http*)
+ echo "cleaning inside $FILE"
+ cleandir "$FILE"
+ ;;
+ _* | tmpmd)
+ echo "removing $FILE"
+ rm -rv "$FILE"
+ ;;
+ *)
+ echo "removing $FILE"
+ rm -v "$FILE"
+ ;;
+ esac
+done
+
+SIZE_OUT=$(du -s . | sed 's/\t.*//')
+echo "Removed $(expr $SIZE_IN - $SIZE_OUT) kilobytes of data from poldek cache"
+
+# vim: ts=4 sw=4 filetype=sh
diff --git a/bin/cleanup-la b/bin/cleanup-la
new file mode 100755
index 0000000..2db6fd5
--- /dev/null
+++ b/bin/cleanup-la
@@ -0,0 +1,6 @@
+#!/bin/sh
+root=$1
+find $root/usr/lib{,64} -name "*.la" -print0 | xargs -0 -r sed -i -e "s@dependency_libs=.*@dependency_libs=' '@"
+
+# it's important this script does not fail if no matches found
+exit 0
diff --git a/bin/findbr b/bin/findbr
new file mode 100755
index 0000000..403db2e
--- /dev/null
+++ b/bin/findbr
@@ -0,0 +1,748 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use IPC::Open2;
+use Cwd;
+use constant DOCKER => -e '/.dockerenv';
+
+my $pwd = getcwd();
+# how to run poldek
+my @ignore = qw(vserver-packages python-devel-src);
+my @poldek;
+if (DOCKER) {
+ push(@poldek, qw[poldek]);
+} else {
+ push(@poldek, qw[sudo poldek -n th-x86_64-ready],
+ "--cachedir=$pwd/poldekcache",
+ "--conf=$pwd/poldekconf/poldek.conf",
+ );
+}
+push(@poldek, (
+ "--skip-installed",
+ "-O", "ignore=" . (join " ", @ignore)
+));
+
+# if multiple packages provide some funcionality those will be selected:
+my %preferred = (
+ "automake" => +1,
+ "autoconf" => +1,
+ "pkgconfig" => +1,
+
+ "python" => +1,
+ "python-modules" => +1,
+ "python-setuptools" => +1,
+
+ "perl-modules" => +1,
+ "perl-Encode" => +2,
+
+ "zlib-devel" => +1,
+ "libstdc++-devel" => +1,
+ "libusb-compat-devel" => +1,
+ "libjpeg-devel" => +1,
+ "libpng-devel" => +1,
+ "libsamplerate-devel" => +1,
+ "pulseaudio-devel" => +1,
+ "xorg-lib-libXrandr-devel" => +1,
+ "sqlite-devel" => +1,
+
+ "ice-devel" => -1,
+);
+
+# translate package name to provides name
+my %translate = (
+ "gcc-c++" => "libstdc++-devel",
+ "rarian-compat" => "scrollkeeper",
+ "Mesa-libGL" => "OpenGL",
+ "Mesa-libGL-devel" => "OpenGL-devel",
+ "Mesa-libGLU-devel" => "OpenGL-GLU-devel",
+);
+
+my @skip = qw(hostname git svn svnversion mt gawk);
+my %skip;
+@skip{ @skip } = (1) x scalar @skip;
+
+# for m4 in *.m4; do R=$(rpm -qf $m4); R=${R%-*-*}; \
+# awk -vr=$R '/^\s*(AC_DEFUN|AU_ALIAS)/ { gsub(/\].*/,""); gsub(/.*\[/,""); print r " " $0}' $m4; \
+# done | sort | awk '{print "\t\"" $2 "\" => \"" $1 "\","}'
+my %ac2br = do (DOCKER ? './cleanbuild/bin/findbr-ac2br' : './bin/findbr-ac2br');
+
+my %cmake2br = (
+ "findkde4:44" => "kde4-kdelibs",
+ "findmsgfmt" => "gettext-tools",
+ "findpythoninterp" => "python",
+);
+
+BEGIN {
+ $SIG{__WARN__} = sub
+ {
+ local $_ = shift;
+ chomp;
+ print STDERR "\033[31;1m" . $_ . "\033[0m\n"
+ };
+}
+
+my $builddir = shift @ARGV;
+my @lines = <ARGV>;
+
+my $reason;
+
+my %out;
+sub add_br
+{
+ my $pkg = shift;
+ my $msg = shift || $reason;
+ if ( ref $pkg ) {
+ foreach my $p ( @$pkg ) {
+ add_br( $p, $msg );
+ }
+ return;
+ }
+
+ $msg =~ s/\n/ # /sg;
+
+ $pkg = $translate{ $pkg } || $pkg;
+
+ return if exists $out{ $pkg };
+ $out{ $pkg } = $msg;
+ print STDERR "\033[33;1madding: $pkg => $msg\033[0m\n";
+}
+
+sub poldek_cmd
+{
+ my $cmd = shift;
+
+ warn "Poldek: $cmd\n";
+
+ my @cmd = (@poldek, "--shcmd=".$cmd);
+ open my $fh, '-|', @cmd or die "$!: @cmd";
+ my @read = <$fh>;
+ close $fh or die $!;
+
+ return wantarray ? @read : \@read;
+}
+
+my $check_ac = 0;
+my $check_config_log = undef;
+my $check_mkmf_log = undef;
+
+my %checked_files;
+sub poldek_file
+{
+ my @files;
+ foreach ( @_ ) {
+ next if $checked_files{ $_ };
+ $checked_files{ $_ } = 1;
+ push @files, $_;
+ }
+ return unless @files;
+
+ my $search = join "; ", map "search -f $_", @files;
+ warn "Reason: $reason\n";
+ my @read = poldek_cmd( $search );
+
+ local $_;
+ my @found;
+ while ( $_ = shift @read ) {
+ if ( /(\d+) package\(s\) found:$/ ) {
+ foreach my $i ( 1..$1 ) {
+ $_ = shift @read;
+ chomp;
+ $_ =~ /^(.*)-.*?-.*?$/;
+ push @found, $1;
+ }
+ }
+ }
+
+ return unless @found;
+
+ my $found = $found[0];
+ if ( @found > 1 ) {
+ my $i = 0.0;
+ my %pts = map { ( $_ => ( ($i += 0.001) + ( $preferred{ $_ } || 0 ) ) ) }
+ reverse @found;
+ my @pref = sort { $pts{$b} <=> $pts{$a} } @found;
+ my $pref = join ", ", map "$_ => $pts{$_}", @pref;
+ warn "Multiple found: $pref\n";
+ $found = $pref[0];
+ }
+
+ $found = $translate{ $found } if $translate{ $found };
+
+ add_br( $found );
+}
+
+my $pkglist;
+sub get_pkglist
+{
+ my %pkglist;
+ my $read = poldek_cmd( "ls" );
+ foreach ( @$read ) {
+ chomp;
+ next unless /(\S+)-.*?-.*?\.[a-z0-9_]+$/;
+ my $pkg = $1;
+ $pkglist{ lc $pkg } = $pkg;
+ }
+ $pkglist = \%pkglist;
+}
+
+sub guess_package
+{
+ my $origname = shift;
+ get_pkglist() unless $pkglist;
+ return unless defined $origname;
+ my $name = lc $origname;
+ my @try = (
+ "lib$name-devel",
+ "$name-devel",
+ "$name",
+ "lib$name-.*-devel",
+ "$name-.*-devel",
+ ".*-lib$name-devel",
+ ".*-$name-devel",
+ ".*-lib$name-.*-devel",
+ ".*-$name-.*-devel",
+ );
+ my @select;
+ for my $k ( keys %$pkglist ) {
+ if ( $k =~ /$name/ ) {
+ push @select, $k;
+ }
+ }
+ @select = sort @select;
+
+ foreach my $try ( @try ) {
+ foreach my $pkg ( @select ) {
+ if ( $pkg =~ /^$try$/ ) {
+ warn "guessed: $origname => $pkglist->{ $pkg }\n";
+ return $pkglist->{ $pkg };
+ }
+ }
+ }
+ warn "$origname not guessed\n";
+ return undef;
+}
+
+start_check:
+
+my %checked;
+my $cmake_get_call = 0;
+my $cmake_pkg_list = 0;
+my $py_ver = undef;
+while ( $_ = shift @lines ) {
+ chomp;
+ #next if $checked{ $_ };
+ #$checked{ $_ } = 1;
+
+ # try to extract current python version from setup.py run
+ if (m{^copying .+ -> build-(\d+)/lib/}) {
+ $py_ver = $1;
+ warn "py_ver set to '$py_ver'\n";
+ }
+
+ $reason = $_;
+ if ( /^\S+: (\S+): (?:Command )?not found$/ or /.*configure\[\d+\]: (\S+): not found$/
+ or m{which: no (\S+) in \(.*/bin.*\)}
+ or m{\S+: (\S+): command not found$}
+ or m{(?:/usr/bin/)?env: (\S+): No such file or directory}
+ or m{flock: (\S+): No such file or directory}
+ or m{Can't exec "(\S+)": No such file or directory} ) {
+ my $exec = $1;
+ $exec = $1 if $exec =~ m{^"(.*)"$};
+ next if $skip{ $exec };
+ warn "Looking for executable $exec\n";
+ if ( $exec =~ m#^/# ) {
+ poldek_file( $exec );
+ }
+ poldek_file( "/usr/bin/$exec", "/bin/$exec" );
+ }
+
+ if ( /\S+\.[ch](?:pp|xx|c)?:\d+:\d+: error: (\S+): No such file or directory$/ or
+ /\S+\.[ch](?:pp|xx|c)?:\d+:\d+: fatal error: (\S+): No such file or directory$/ or
+ /Can't find the '(\S+\.h)'? header/
+ ) {
+ my $h = $1;
+ warn "Looking for C(++) header $h\n";
+ poldek_file( "/usr/include*/$h" );
+ }
+
+ if (m{^ImportError: No module named (\S+)$}
+ or m{^ERROR: Cannot find .+: No module named (\S+)$}
+ or m{^ERROR: Failed to import the ".+" module: No module named (\S+)$}
+ or m{^distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse\('([^'>=]+).*'\)}
+ or m{^error: Could not find suitable distribution for Requirement.parse\('([^'>=]+).*'\)}
+ or m{^Couldn't find index page for '(\S+)'}
+ ) {
+ my $mod = $1;
+ $mod =~ s#\.#/#g;
+ warn "Looking for Python$py_ver module $mod\n";
+ poldek_file(
+ "/usr/share/python$py_ver*/site-packages/$mod/__init__.py*",
+ "/usr/share/python$py_ver*/$mod/__init__.py*",
+ "/usr/share/python$py_ver*/site-packages/$mod.py*",
+ "/usr/share/python$py_ver*/$mod.py*",
+ "/usr/lib*/python$py_ver*/site-packages/$mod/__init__.py*",
+ "/usr/lib*/python$py_ver*/$mod/__init__.py*",
+ "/usr/lib*/python$py_ver*/site-packages/$mod.py*",
+ "/usr/lib*/python$py_ver*/$mod.py*",
+ "/usr/lib*/python$py_ver*/site-packages/_$mod.so",
+ "/usr/lib*/python$py_ver*/_$mod.so",
+ "/usr/lib*/python$py_ver*/site-packages/$mod.so",
+ "/usr/lib*/python$py_ver*/$mod.so",
+ );
+ }
+
+ if (
+ m{^-- Could NOT find Sphinx \(missing: SPHINX_EXECUTABLE\)}
+ ) {
+ add_br("sphinx-pdg");
+ next;
+ }
+
+ if (
+ m{^You need to install the (\S+) module} or
+ m{\*\*\*Error\*\*\*: You must have (\S+) >= (\S+) installed}
+ ) {
+ add_br($1);
+ next;
+ }
+
+ if (
+ m{^cannot load such file -- (\S+)} or
+ m{in `require': cannot load such file -- (\S+) \(LoadError\)}
+ ) {
+ my $mod = $1;
+ warn "Looking for ruby module $mod\n";
+ poldek_file(
+ "/usr/share/ruby/*/$mod.rb",
+ "/usr/share/ruby/vendor_ruby/*/$mod.rb",
+ "/usr/lib64/ruby/vendor_ruby/*/$mod.so",
+ );
+ }
+
+ if ( /configure(?:\.in|\.ac)?:\d+: error: possibly undefined macro: (\S+)/
+ or m{configure(?:\.in|\.ac)?:\d+: error: m4 macro `(\S+)' is not defined}
+ or m{warning: macro `(\S+)' not found in library} ) {
+ my $macro = $1;
+ warn "Looking for autotools macro $macro\n";
+ if ( my $br = $ac2br{ $macro } ) {
+ add_br( $br );
+ next;
+ } else {
+ $check_ac = 1;
+ }
+ }
+ if ( /^No package '(\S+)' found$/ or
+ /Package (\S+) was not found in the pkg-config search path/
+ or m{None of the required '(\S+?)(?:[<>=].*)?' found}
+ or m{--\s+package '(\S+?)(?:[<>=].*)?' not found}
+ or m{ERROR: cannot find a valid pkg-config package for \['(\S+?)(?:[<>=].*)?'\]}
+ ) {
+ my $pkg = $1;
+ warn "Looking for package $pkg\n";
+ poldek_file( "/usr/lib*/pkgconfig/$pkg.pc", "/usr/share/pkgconfig/$pkg.pc" );
+ }
+
+ if (/^ocamlfind: Package `(\S+)' not found - required by/
+ or m{Camlp4: Uncaught exception: DynLoader.Error \("(\S+)", "file not found in path"\)}
+ ) {
+ my $pkg = $1;
+ warn "Looking for ocaml package $pkg\n";
+ poldek_file( "/usr/lib*/ocaml/*/$pkg.a", "/usr/lib*/ocaml/*/$pkg");
+ }
+
+ if ( m{^cp: cannot stat `(/.*)': No such file or directory$} ) {
+ my $f = $1;
+ warn "Looking for file $f\n";
+ poldek_file( $f );
+ }
+
+ if ( m{ERROR: Could not find KDE4 (kde4-config)}) {
+ my $f = "/usr/bin/$1";
+ warn "Looking for file $f\n";
+ poldek_file( $f );
+ }
+
+ if (m{Ragel State Machine Compiler not found}) {
+ add_br( "ragel" );
+ next;
+ }
+
+ if (m{ERROR: CMake is required to build}) {
+ add_br("cmake");
+ next;
+ }
+
+ # lucky guessing
+ if (m{'yum install (\S+)'}) {
+ add_br($1);
+ next;
+ }
+
+ if ( m{^find-lang.sh: Error: international files not found for '}
+ or m{ gettext tools not found}
+ ) {
+ add_br( "gettext-tools" );
+ next;
+ }
+
+ if ( m{ pkg-config .*not .*found}
+ or m{^checking for pkg-config\.\.\. no}
+ or m{^pkg-config unavailable, build terminated}
+ or m{^\*\*\*Error\*\*\*: You must have pkg-config >= .* installed}
+ or m{^-- Could NOT find PkgConfig \(missing: PKG_CONFIG_EXECUTABLE\)}
+ or m{exec: "pkg-config": executable file not found in \$PATH}
+ ) {
+ add_br( "pkgconfig" );
+ next;
+ }
+
+ if ( m{Can't locate (.*?\.pm) in \@INC} ) {
+ my $mod = $1;
+ warn "Looking for perl module $mod\n";
+ poldek_file( "/usr/lib*/perl*/$mod", "/usr/share/perl*/$mod" );
+ }
+
+ if (
+ m{^(?:/usr/bin/ld: )?cannot find -l(.*?)$}
+ ) {
+ my $lib = $1;
+ warn "Looking for library $lib\n";
+ poldek_file( "/usr/lib64/lib$lib.so", "/usr/lib/lib$lib.so",
+ "/usr/lib*/lib$lib.so" );
+ }
+
+ # full path to ldd files
+ if (
+ m{^WARNING; can.*t resolve .* dependency: (.*?)$}
+ ) {
+ my $lib = $1;
+ warn "Looking for library '$lib'\n";
+ poldek_file( "/usr/lib64/$lib", "/usr/lib/$lib", "/lib64/$lib", "/lib/$lib");
+ }
+
+ if ( m{^error: Couldn't exec (/\S+): No such file or directory$}
+ or m{^Can't open perl script "(/\S+)": No such file or directory$}
+ or m{unable to open (/\S+) \(No such file or directory\)$}
+ or m{GConf-CRITICAL \*\*: No such file `(/.\S+?)'$}
+ or m{make.*: \*\*\* No rule to make target `(/\S+)'}
+ or m{g(?:cc|\+\+): (/\S+): No such file or directory$}
+ or m{env: (/\S+): No such file or directory$}
+ ) {
+ my $file = $1;
+ warn "Looking for file $file\n";
+ poldek_file( $file );
+ }
+
+ if ( m{^ValueError: Couldn't find include '(.*\.gir)'} ) {
+ my $file = $1;
+ warn "Looking for gir file $file\n";
+ poldek_file( "/usr/share/gir-1.0/" . $file );
+ }
+
+ if ( m{^error: Package `(\S+)' not found in specified Vala API directories or GObject-Introspection GIR directories}
+ ) {
+ my $file = $1;
+ warn "Looking for gir file $file\n";
+ poldek_file( "/usr/share/vala/vapi/$file.vapi");
+ }
+
+ if ( m{failed.*http://www\.oasis-open\.org/docbook/xml/([\d\.]+/\S+\.dtd)} ) {
+ my $dtd = $1;
+ warn "Looking for docbook file $dtd\n";
+ poldek_file( "/usr/share/sgml/docbook/xml-dtd-$dtd" );
+ }
+ if ( m{http://docbook.sourceforge.net/release/xsl/current/(\S+\.xsl)} ) {
+ my $db = $1;
+ next if m{^\s*(/usr/bin/)?xsltproc };
+ warn "Looking for docbook file $db\n";
+ poldek_file( "/usr/share/sgml/*/$db" );
+ }
+ if (m{Could not find HTML docbook.xsl}) {
+ add_br("docbook-style-xsl");
+ }
+
+ if ( m{LaTeX Error: File `(\S+)' not found} ) {
+ my $tex = $1;
+ warn "Looking for tex file $tex\n";
+ poldek_file( "/usr/share/tex*/$tex" );
+ }
+ if ( m{mv: cannot move `\S+' to `(/var/lib/texmf.*?)':} ) {
+ my $tex = $1;
+ warn "Looking for tex file $tex\n";
+ poldek_file( $tex );
+ }
+
+ if ( m{configure: error: C\+\+ preprocessor "/lib/cpp" fails sanity check} ) {
+ add_br( "gcc-c++", "try: %undefine\t__cxx" );
+ }
+ if ( m{configure: error: C\+\+ compiler cannot create executables} ) {
+ add_br( "libstdc++-devel", "maybe try: %undefine\t__cxx" );
+ }
+ if ( m{ccache: error: Could not find compiler ".+-g\+\+" in PATH}) {
+ add_br("libstdc++-devel");
+ }
+ if ( m{configure: error: XML::Parser perl module is required for intltool} ) {
+ add_br( "perl-XML-Parser" );
+ }
+ if ( m{iconv: conversion from `\S+' is not supported} ) {
+ add_br( "iconv" );
+ }
+
+ if (m{rst2man \(python-docutils\) is required to build man pages}) {
+ add_br("docutils");
+ }
+
+ if ( m{ (\S+) does not appear in AM_CONDITIONAL$} ) {
+ my $macro = $1;
+ warn "Looking for autotools macro $macro\n";
+ if ( my $br = $ac2br{ $macro } ) {
+ add_br( $br );
+ next;
+ } else {
+ $check_ac = 1;
+ }
+ }
+
+ if ( m{configure\[\d+\]: syntax error: }
+ or m{\./configure\[\d+\]: \S+_\S+: not found}
+ or m{./configure\[\d+\]: .*unexpected}
+ or m{does not appear in AM_CONDITIONAL$}
+ ) {
+ warn "Need to check configure source: $reason\n";
+ $check_ac = 1;
+ }
+ if ( m{^configure: error:} ) {
+ $check_config_log = 1 unless defined $check_config_log;
+ }
+
+ if ( m{Check the mkmf.log file for more details} ) {
+ $check_mkmf_log = 1 unless defined $check_mkmf_log;
+ }
+
+ if ( m{^CMake (?:Error|Warning) at (?:\S+/)?(\S+?)\.cmake:(\d+) } ) {
+ my ( $module, $line ) = ( lc $1, $2 );
+ my $br;
+ if ( $module eq "findqt4" ) {
+ my $l = $lines[0];
+ chomp $l;
+ if ( $l =~ /qmake/ ) {
+ add_br( "qt4-qmake", $l );
+ } elsif ( $l =~ /rcc/ ) {
+ add_br( "qt4-build", $l );
+ } elsif ( $l =~ /Could NOT find (Qt\S+) header/ ) {
+ add_br( "$1-devel", $l );
+ } else {
+ warn "unrecognized Qt requirement: $l\n";
+ }
+ } elsif ( $module eq "qt5coreconfig" ) {
+ my $l = $lines[2];
+ chomp $l;
+ if ( $l =~ /qmake/ ) {
+ add_br( "qt5-qmake", $l );
+ } elsif ( $l =~ /moc/) {
+ add_br( "qt5-build", $l );
+ } else {
+ warn "Unrecognized Qt requirement: $l\n";
+ }
+ } elsif ( $module eq "cmakedeterminecxxcompiler" ) {
+ add_br( "libstdc++-devel",
+ '"try: -DCMAKE_CXX_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER="%{__cc}"' );
+ } elsif ( $br = $cmake2br{ $module . ":" . $line } ) {
+ add_br( $br );
+ } elsif ( $br = $cmake2br{ $module } ) {
+ add_br( $br );
+ } elsif ( $br = guess_package( $module =~ /find(.+)/ ) ) {
+ add_br( $br );
+ } else {
+ $cmake_get_call = 1;
+ warn "Unrecognized cmake error: $reason\n";
+ }
+ }
+
+ if ( m{^CMake Error at (?:\S+/)?(\S+?):(\d+) \(find_package\):} ) {
+ my ($file, $line) = (lc $1, $2);
+
+ #CMake Error at CMakeLists.txt:29 (find_package):
+ # Could not find a package configuration file provided by "LLVM" with any of the following names:
+ #
+ # LLVMConfig.cmake
+ # llvm-config.cmake
+ my @files = grep { /\.cmake$/ } @lines;
+ my @find = map { chomp; s/^\s+//; "/usr/*/cmake/*/$_" } @files;
+ poldek_file(@find);
+ }
+
+ if ( m{^\s*ERROR: (?:\S+/)?(\S+?\.cmake) not found} ) {
+ my $cmake = $1;
+ warn "Looking for cmake file: $cmake\n";
+ poldek_file( "/usr/*/cmake/*/$cmake" )
+ }
+ if ( $cmake_get_call ) {
+ if ( m{^\s*/\S+/(\S+)\.cmake:(\d+) } ) {
+ my ( $module, $line ) = ( lc $1, $2 );
+ my $br;
+ if ( $br = $cmake2br{ $module . ":" . $line } ) {
+ add_br( $br );
+ $cmake_get_call = 0;
+ } elsif ( $br = $cmake2br{ $module } ) {
+ add_br( $br );
+ $cmake_get_call = 0;
+ } elsif ( $br = guess_package( $module =~ /find(.+)/ ) ) {
+ add_br( $br );
+ $cmake_get_call = 0;
+ }
+ } elsif (m{Can not use "(.+)" module which has not yet been found}
+ or m{Could not find a package configuration file provided by "(.+)"}) {
+ my $cmake = $1;
+
+ warn "Looking for cmake file: $cmake\n";
+ poldek_file(
+ "/usr/*/cmake/*/$cmake.cmake",
+ "/usr/*/cmake/*/${cmake}Config.cmake",
+ "/usr/*/cmake/*/${cmake}-config.cmake",
+ );
+ $cmake_get_call = 0;
+ }
+ }
+ if ( m{^-- WARNING: you are using the obsolete 'PKGCONFIG' macro} ) {
+ add_br( "pkgconfig" );
+ }
+ if ( m{QT_(QT\S+)_LIBRARY \(ADVANCED\)}
+ or m{X11_(\S+)_LIB \(ADVANCED\)}
+ or m{Qt (\S+) library not found} ) {
+ my $find = $1;
+ my $pkg = guess_package( $find );
+ if ( $pkg ) {
+ add_br( $pkg );
+ } else {
+ warn "Cannot quess qt package: $find\n";
+ }
+ }
+
+ if ( m{Unable to find a javac compiler;$} ) {
+ add_br( "jdk" );
+ }
+ if ( m{Could not find (\S+) Java extension for this JVM$} ) {
+ my $jar = $1;
+ warn "Looking for jar file: $jar\n";
+ poldek_file( "/usr/share/java/$jar.jar", "*/$jar.jar" )
+ }
+
+
+ if ( m{^-- The following OPTIONAL packages could NOT be located on your system} ) {
+ $cmake_pkg_list = 1;
+ }
+ if ( $cmake_pkg_list ) {
+ if ( /\s+\* (\S+) / ) {
+ my $find = $1;
+ my $pkg = guess_package( $find );
+ if ( $pkg ) {
+ add_br( $pkg );
+ } else {
+ warn "Cannot quess optional package: $find\n";
+ }
+ } elsif ( /^\s*$/ ) {
+ $cmake_pkg_list = 0;
+ }
+ }
+
+ if (m{By not providing "Find(.+)\.cmake" in CMAKE_MODULE_PATH}
+ or m{Could not find a package configuration file provided by "(.+)"
+ }) {
+ my $cmake = $1;
+ my $lcmake = lc $cmake;
+
+ warn "Looking for cmake file: $cmake\n";
+ poldek_file(
+ "/usr/*/cmake/*/$cmake.cmake",
+ "/usr/*/cmake/*/${cmake}Config.cmake",
+ "/usr/*/cmake/*/${cmake}-config.cmake",
+ "/usr/*/cmake/*/${lcmake}Config.cmake",
+ "/usr/*/cmake/*/${lcmake}-config.cmake",
+ )
+ }
+
+ if ( m{^configure:\d+: checking for (?:"(\S+)"|(\S+))$} ) {
+ my $exec = $1 || $2;
+ if ( @lines and $lines[0] =~ m{^configure:\d+: result: no$} ) {
+ next if $skip{ $exec };
+ warn "Looking for executable $exec\n";
+ poldek_file( $exec ) if $exec =~ m#^/#;
+ poldek_file( "/usr/bin/$exec", "/bin/$exec" );
+ }
+ }
+
+
+ if (
+ m{Could not find (\S+)}
+ ) {
+ my $exec = $1;
+ poldek_file("/usr/bin/$exec", "/bin/$exec" );
+ }
+}
+
+
+
+sub find_configure
+{
+ return unless /^configure(\.(?:ac|in|in\.in))?$/;
+ return unless -r;
+
+ warn "$File::Find::name\n";
+ open F_IN, "<", $_;
+ my $file = $_;
+ while ( <F_IN> ) {
+ chomp;
+ if ( m{^\s*([A-Za-z0-9_]+)\s*(\(.*)?$} ) {
+ my $def = $1;
+ if ( my $br = $ac2br{ $def } ) {
+ add_br( $br, "$file: $_" );
+ } elsif ( $def !~ /^A[CM]_/ and $def =~ /^_?[A-Z]+_[A-Z_0-9a-z]+$/ ) {
+ #warn "Possible macro unrecognized: $def [[[$_]]]\n";
+ }
+ }
+ }
+ close F_IN;
+}
+
+use File::Find;
+if ( $check_ac ) {
+ find( \&find_configure, $builddir );
+}
+
+sub find_config_log
+{
+ return unless /^config\.log$/;
+ return unless -r;
+
+ warn "$File::Find::name\n";
+ open F_IN, "<", $_;
+ push @lines, <F_IN>;
+ close F_IN;
+}
+
+if ( $check_config_log ) {
+ $check_config_log = 0;
+ find( \&find_config_log, $builddir );
+ goto start_check if @lines;
+}
+
+if ($check_mkmf_log) {
+ $check_mkmf_log = 0;
+ find(sub {
+ return unless /^mkmf\.log$/;
+ return unless -r;
+
+ warn "$File::Find::name\n";
+ open F_IN, "<", $_;
+ push @lines, <F_IN>;
+ close F_IN;
+ }, $builddir);
+ goto start_check if @lines;
+}
+
+foreach my $pkg ( sort keys %out ) {
+ print "$pkg -- $out{$pkg}\n";
+}
+# vim: ts=4 sw=4
diff --git a/bin/findbr-ac2br b/bin/findbr-ac2br
new file mode 100644
index 0000000..1a3e146
--- /dev/null
+++ b/bin/findbr-ac2br
@@ -0,0 +1,420 @@
+ "CLANLIB_INIT" => "ClanLib-devel",
+ "AM_GCONF_SOURCE_2" => "GConf2-devel",
+ "GCONF_SCHEMAS_INSTALL" => "GConf2-devel",
+ "AM_PATH_ORBIT2" => "ORBit2-devel",
+ "AM_PATH_SDL" => "SDL-devel",
+ "AC_FIND_XBAE" => "Xbae-devel",
+ "AM_PATH_AALIB" => "aalib-devel",
+ "AC_CHECK_LIBAGG" => "agg-devel",
+ "AM_PATH_ALLEGRO" => "allegro-devel",
+ "AM_PATH_ALSA" => "alsa-lib-devel",
+ "AC_AQBANKING" => "aqbanking-devel",
+ "AM_PATH_AUDIOFILE" => "audiofile-devel",
+ "AG_PATH_AUTOOPTS" => "autogen-devel",
+ "ag_FIND_LIBOPTS" => "autogen-devel",
+ "AM_PATH_AVIFILE" => "avifile-devel",
+ "AC_BAKEFILE" => "bakefile",
+ "AC_BAKEFILE_CHECK_BASIC_STUFF" => "bakefile",
+ "AC_BAKEFILE_CREATE_FILE_BK_DEPS" => "bakefile",
+ "AC_BAKEFILE_CREATE_FILE_BK_MAKE_PCH" => "bakefile",
+ "AC_BAKEFILE_CREATE_FILE_DLLAR_SH" => "bakefile",
+ "AC_BAKEFILE_CREATE_FILE_SHARED_LD_SH" => "bakefile",
+ "AC_BAKEFILE_DEPS" => "bakefile",
+ "AC_BAKEFILE_GNUMAKE" => "bakefile",
+ "AC_BAKEFILE_METROWERKS_EXTO" => "bakefile",
+ "AC_BAKEFILE_PLATFORM" => "bakefile",
+ "AC_BAKEFILE_PLATFORM_SPECIFICS" => "bakefile",
+ "AC_BAKEFILE_PRECOMP_HEADERS" => "bakefile",
+ "AC_BAKEFILE_PROG_CC" => "bakefile",
+ "AC_BAKEFILE_PROG_COMPAQCC" => "bakefile",
+ "AC_BAKEFILE_PROG_COMPAQCXX" => "bakefile",
+ "AC_BAKEFILE_PROG_CXX" => "bakefile",
+ "AC_BAKEFILE_PROG_HPCC" => "bakefile",
+ "AC_BAKEFILE_PROG_HPCXX" => "bakefile",
+ "AC_BAKEFILE_PROG_INTELCC" => "bakefile",
+ "AC_BAKEFILE_PROG_INTELCC_10" => "bakefile",
+ "AC_BAKEFILE_PROG_INTELCC_8" => "bakefile",
+ "AC_BAKEFILE_PROG_INTELCXX" => "bakefile",
+ "AC_BAKEFILE_PROG_INTELCXX_10" => "bakefile",
+ "AC_BAKEFILE_PROG_INTELCXX_8" => "bakefile",
+ "AC_BAKEFILE_PROG_MWCC" => "bakefile",
+ "AC_BAKEFILE_PROG_MWCXX" => "bakefile",
+ "AC_BAKEFILE_PROG_SGICC" => "bakefile",
+ "AC_BAKEFILE_PROG_SGICXX" => "bakefile",
+ "AC_BAKEFILE_PROG_SUNCC" => "bakefile",
+ "AC_BAKEFILE_PROG_SUNCXX" => "bakefile",
+ "AC_BAKEFILE_PROG_XLCC" => "bakefile",
+ "AC_BAKEFILE_PROG_XLCXX" => "bakefile",
+ "AC_BAKEFILE_RES_COMPILERS" => "bakefile",
+ "AC_BAKEFILE_SHARED_LD" => "bakefile",
+ "AC_BAKEFILE_SHARED_VERSIONS" => "bakefile",
+ "AC_BAKEFILE_SUFFIXES" => "bakefile",
+ "_AC_BAKEFILE_LANG_COMPILER" => "bakefile",
+ "_AC_BAKEFILE_LANG_COMPILER_LATER_THAN" => "bakefile",
+ "_AC_BAKEFILE_PROG_COMPILER" => "bakefile",
+ "BISON_I18N" => "bison",
+ "AM_PATH_CHECK" => "check",
+ "OST_CCXX2_CHECK" => "commoncpp2-devel",
+ "OST_CCXX2_DYNLOADER" => "commoncpp2-devel",
+ "OST_CCXX2_FOX" => "commoncpp2-devel",
+ "OST_CCXX2_HOARD" => "commoncpp2-devel",
+ "OST_CCXX2_LD_THREADING" => "commoncpp2-devel",
+ "OST_CCXX2_VERSION" => "commoncpp2-devel",
+ "OST_CCXX2_XML" => "commoncpp2-devel",
+ "AM_PATH_CPPUNIT" => "cppunit-devel",
+ "AM_PATH_DOTCONF" => "dotconf-devel",
+ "EPIPHANY_EXTENSION_INIT" => "epiphany-devel",
+ "AM_ESD_SUPPORTS_MULTIPLE_RECORD" => "esound-devel",
+ "AM_PATH_ESD" => "esound-devel",
+ "AM_WITH_EXPAT" => "expat-devel",
+ "AM_PATH_LIBFLACPP" => "flac-c++-devel",
+ "AM_PATH_LIBFLAC" => "flac-devel",
+ "AC_CHECK_FT2" => "freetype-devel",
+ "AC_GWRAP_CHECK_GUILE" => "g-wrap-devel",
+ "AM_PATH_GWRAP" => "g-wrap-devel",
+ "AM_PATH_GDK_PIXBUF" => "gdk-pixbuf-devel",
+ "GDOME2_DEFS" => "gdome2-devel",
+ "AC_LIB_APPENDTOVAR" => "gettext-devel",
+ "AC_LIB_HAVE_LINKFLAGS" => "gettext-devel",
+ "AC_LIB_LINKFLAGS" => "gettext-devel",
+ "AC_LIB_LINKFLAGS_BODY" => "gettext-devel",
+ "AC_LIB_LINKFLAGS_FROM_LIBS" => "gettext-devel",
+ "AC_LIB_PREFIX" => "gettext-devel",
+ "AC_LIB_PREPARE_MULTILIB" => "gettext-devel",
+ "AC_LIB_PREPARE_PREFIX" => "gettext-devel",
+ "AC_LIB_PROG_LD" => "gettext-devel",
+ "AC_LIB_PROG_LD_GNU" => "gettext-devel",
+ "AC_LIB_RPATH" => "gettext-devel",
+ "AC_LIB_WITH_FINAL_PREFIX" => "gettext-devel",
+ "AC_TYPE_LONG_LONG_INT" => "gettext-devel",
+ "AC_TYPE_UNSIGNED_LONG_LONG_INT" => "gettext-devel",
+ "AM_GNU_GETTEXT" => "gettext-devel",
+ "AM_GNU_GETTEXT_INTL_SUBDIR" => "gettext-devel",
+ "AM_GNU_GETTEXT_NEED" => "gettext-devel",
+ "AM_GNU_GETTEXT_VERSION" => "gettext-devel",
+ "AM_ICONV" => "gettext-devel",
+ "AM_ICONV_LINK" => "gettext-devel",
+ "AM_ICONV_LINKFLAGS_BODY" => "gettext-devel",
+ "AM_INTL_SUBDIR" => "gettext-devel",
+ "AM_LANGINFO_CODESET" => "gettext-devel",
+ "AM_NLS" => "gettext-devel",
+ "AM_PATH_PROG_WITH_TEST" => "gettext-devel",
+ "AM_POSTPROCESS_PO_MAKEFILE" => "gettext-devel",
+ "AM_PO_SUBDIRS" => "gettext-devel",
+ "AM_XGETTEXT_OPTION" => "gettext-devel",
+ "AM_XGETTEXT_OPTION_INIT" => "gettext-devel",
+ "_AC_TYPE_LONG_LONG_SNIPPET" => "gettext-devel",
+ "gl_AC_HEADER_INTTYPES_H" => "gettext-devel",
+ "gl_AC_HEADER_STDINT_H" => "gettext-devel",
+ "gl_AC_TYPE_UINTMAX_T" => "gettext-devel",
+ "gl_GLIBC21" => "gettext-devel",
+ "gl_LOCK" => "gettext-devel",
+ "gl_LOCK_BODY" => "gettext-devel",
+ "gl_LOCK_EARLY" => "gettext-devel",
+ "gl_LOCK_EARLY_BODY" => "gettext-devel",
+ "gl_PREREQ_LOCK" => "gettext-devel",
+ "gl_SIZE_MAX" => "gettext-devel",
+ "gl_VISIBILITY" => "gettext-devel",
+ "gl_XSIZE" => "gettext-devel",
+ "gt_CHECK_DECL" => "gettext-devel",
+ "gt_GLIBC2" => "gettext-devel",
+ "gt_INTDIV0" => "gettext-devel",
+ "gt_INTL_MACOSX" => "gettext-devel",
+ "gt_INTL_SUBDIR_CORE" => "gettext-devel",
+ "gt_INTTYPES_PRI" => "gettext-devel",
+ "gt_LC_MESSAGES" => "gettext-devel",
+ "gt_PRINTF_POSIX" => "gettext-devel",
+ "gt_TYPE_INTMAX_T" => "gettext-devel",
+ "gt_TYPE_WCHAR_T" => "gettext-devel",
+ "gt_TYPE_WINT_T" => "gettext-devel",
+ "AM_PATH_GIMP_2_0" => "gimp-devel",
+ "AM_PATH_GLIB" => "glib-devel",
+ "AM_GLIB_DEFINE_LOCALEDIR" => "glib2-devel",
+ "AM_GLIB_GNU_GETTEXT" => "glib2-devel",
+ "AM_PATH_GLIB_2_0" => "glib2-devel",
+ "GLIB_RUN_PROG" => "glib2-devel",
+ "GLIBMM_CHECK_PERL" => "glibmm-devel",
+ "GLIBMM_CV_PERL_VERSION" => "glibmm-devel",
+ "AM_PATH_GNET_2_0" => "gnet-devel",
+ "GNOME_COMMON_INIT" => "gnome-common",
+ "GNOME_COMPILE_WARNINGS" => "gnome-common",
+ "GNOME_CXX_WARNINGS" => "gnome-common",
+ "GNOME_DEBUG_CHECK" => "gnome-common",
+ "GNOME_MAINTAINER_MODE_DEFINES" => "gnome-common",
+ "GNOME_DOC_DEFINES" => "gnome-doc-utils",
+ "GNOME_DOC_INIT" => "gnome-doc-utils",
+ "GOB2_CHECK" => "gob2",
+ "GOB2_HOOK" => "gob2",
+ "GOBJECT_INTROSPECTION_CHECK" => "gobject-introspection-devel",
+ "GOBJECT_INTROSPECTION_REQUIRE" => "gobject-introspection-devel",
+ "AM_PATH_GPGME" => "gpgme-devel",
+ "AM_PATH_GPGME_GLIB" => "gpgme-devel",
+ "AM_PATH_GPGME_PTH" => "gpgme-devel",
+ "AM_PATH_GPGME_PTHREAD" => "gpgme-devel",
+ "_AM_PATH_GPGME_CONFIG" => "gpgme-devel",
+ "AM_PATH_GSL" => "gsl-devel",
+ "AX_PATH_GSL" => "gsl-devel",
+ "AM_GST_ELEMENT_CHECK" => "gstreamer-devel",
+ "AM_PATH_GTK" => "gtk+-devel",
+ "AM_PATH_GTK_2_0" => "gtk+2-devel",
+ "GTK_DOC_CHECK" => "gtk-doc-automake",
+ "AM_PATH_GTKGL" => "gtkglarea1-devel",
+ "AC_GTKGLEXT_SUPPORTS_MULTIHEAD" => "gtkglext-devel",
+ "AM_PATH_GTKGLEXT_1_0" => "gtkglext-devel",
+ "AC_DEFUN(AC_GTKGLEXTMM_SUPPORTS_MULTIHEAD," => "gtkglextmm-devel",
+ "AM_PATH_GTKGLEXTMM_1_2" => "gtkglextmm-devel",
+ "AM_PATH_GTS" => "gts-devel",
+ "GUILE_CHECK" => "guile-devel",
+ "GUILE_FLAGS" => "guile-devel",
+ "GUILE_MODULE_AVAILABLE" => "guile-devel",
+ "GUILE_MODULE_CHECK" => "guile-devel",
+ "GUILE_MODULE_EXPORTS" => "guile-devel",
+ "GUILE_MODULE_REQUIRED" => "guile-devel",
+ "GUILE_MODULE_REQUIRED_EXPORT" => "guile-devel",
+ "GUILE_PROGS" => "guile-devel",
+ "GUILE_SITE_DIR" => "guile-devel",
+ "AC_GWENHYWFAR" => "gwenhywfar-devel",
+ "AM_PATH_GDK_IMLIB" => "imlib-devel",
+ "AM_PATH_IMLIB" => "imlib-devel",
+ "AC_PROG_INTLTOOL" => "intltool",
+ "IT_PO_SUBDIR" => "intltool",
+ "IT_PROG_INTLTOOL" => "intltool",
+ "_IT_SUBST" => "intltool",
+ "AC_CHECK_LIBAAL" => "libaal-devel",
+ "XIPH_PATH_AO" => "libao-devel",
+ "AM_CHECK_LIBASSUAN" => "libassuan-devel",
+ "AM_PATH_LIBASSUAN" => "libassuan-devel",
+ "AM_PATH_LIBASSUAN_PTH" => "libassuan-devel",
+ "AM_PATH_LIBASSUAN_PTHREAD" => "libassuan-devel",
+ "_AM_PATH_LIBASSUAN_COMMON" => "libassuan-devel",
+ "AST_ARG_BACKQUOTE_EXEC" => "libast-devel",
+ "AST_ARG_DEBUG" => "libast-devel",
+ "AST_ARG_REGEXP" => "libast-devel",
+ "AST_CHECK_LIBAST" => "libast-devel",
+ "AST_FLAGS" => "libast-devel",
+ "AST_FUNC_CHECKS" => "libast-devel",
+ "AST_HEADER_CHECKS" => "libast-devel",
+ "AST_IMLIB2_SUPPORT" => "libast-devel",
+ "AST_MMX_SUPPORT" => "libast-devel",
+ "AST_PROG_CHECKS" => "libast-devel",
+ "AST_REGEXP_SUPPORT" => "libast-devel",
+ "AST_SIZE_TYPE" => "libast-devel",
+ "AST_STATUS" => "libast-devel",
+ "AST_STD_CHECKS" => "libast-devel",
+ "AST_TYPE_CHECKS" => "libast-devel",
+ "AST_VAR_CHECKS" => "libast-devel",
+ "AST_X11_SUPPORT" => "libast-devel",
+ "dps_rlimit_memlock" => "libast-devel",
+ "dps_rlimit_nproc" => "libast-devel",
+ "dps_snprintf_oflow" => "libast-devel",
+ "dps_symlink_open_bug" => "libast-devel",
+ "dps_vsnprintf_oflow" => "libast-devel",
+ "LIBCAP_NG_PATH" => "libcap-ng-devel",
+ "AM_PATH_LIBCDAUDIO" => "libcdaudio-devel",
+ "AC_CHIPCARD_CLIENT" => "libchipcard-devel",
+ "AC_CHIPCARD_SERVER" => "libchipcard-devel",
+ "AC_CHECK_DODS" => "libdap-devel",
+ "AC_CHECK_LIBDAP" => "libdap-devel",
+ "AM_PATH_DVDNAV" => "libdvdnav-devel",
+ "AM_PATH_DVDREAD" => "libdvdread-devel",
+ "AM_PATH_LIBFAME" => "libfame-devel",
+ "AM_PATH_LIBGCRYPT" => "libgcrypt-devel",
+ "AM_PATH_LIBGLADE" => "libglade-devel",
+ "AM_PATH_GPG_ERROR" => "libgpg-error-devel",
+ "AC_CHECK_LIBGSTROKE" => "libgstroke-devel",
+ "smr_ARG_WITHINCLUDES" => "libgstroke-devel",
+ "smr_ARG_WITHLIB" => "libgstroke-devel",
+ "smr_CHECK_LIB" => "libgstroke-devel",
+ "AM_PATH_LIBHNJ" => "libhnj-devel",
+ "AM_PATH_KSBA" => "libksba-devel",
+ "AM_PATH_LD10K1" => "liblo10k1-devel",
+ "AC_LTDL_DLLIB" => "libltdl-devel",
+ "AC_LTDL_DLSYM_USCORE" => "libltdl-devel",
+ "AC_LTDL_SHLIBEXT" => "libltdl-devel",
+ "AC_LTDL_SHLIBPATH" => "libltdl-devel",
+ "AC_LTDL_SYMBOL_USCORE" => "libltdl-devel",
+ "AC_LTDL_SYSSEARCHPATH" => "libltdl-devel",
+ "AC_LTDL_SYS_DLOPEN_DEPLIBS" => "libltdl-devel",
+ "LTDL_CONVENIENCE" => "libltdl-devel",
+ "LTDL_INIT" => "libltdl-devel",
+ "LTDL_INSTALLABLE" => "libltdl-devel",
+ "LT_CONFIG_LTDL_DIR" => "libltdl-devel",
+ "LT_FUNC_DLSYM_USCORE" => "libltdl-devel",
+ "LT_LIB_DLLOAD" => "libltdl-devel",
+ "LT_SYS_DLOPEN_DEPLIBS" => "libltdl-devel",
+ "LT_SYS_DLSEARCH_PATH" => "libltdl-devel",
+ "LT_SYS_MODULE_EXT" => "libltdl-devel",
+ "LT_SYS_MODULE_PATH" => "libltdl-devel",
+ "LT_SYS_SYMBOL_USCORE" => "libltdl-devel",
+ "_LTDL_SETUP" => "libltdl-devel",
+ "_LT_LIBOBJ" => "libltdl-devel",
+ "gl_FUNC_ARGZ" => "libltdl-devel",
+ "gl_PREREQ_ARGZ" => "libltdl-devel",
+ "AM_PATH_LIBMCRYPT" => "libmcrypt-devel",
+ "AM_PATH_LIBMIKMOD" => "libmikmod-devel",
+ "XIPH_PATH_OGG" => "libogg-devel",
+ "AM_PATH_LIBOTR" => "libotr-devel",
+ "AM_PATH_LIBPRELUDE" => "libprelude-devel",
+ "AC_PATH_LQT" => "libquicktime-devel",
+ "XIPH_PATH_SHOUT" => "libshout-devel",
+ "AM_PATH_SIGC" => "libsigc++1-devel",
+ "AM_PATH_LIBSMI" => "libsmi-devel",
+ "AC_CHECK_LIBSTROKE" => "libstroke-devel",
+ "smr_ARG_WITHINCLUDES" => "libstroke-devel",
+ "smr_ARG_WITHLIB" => "libstroke-devel",
+ "smr_CHECK_LIB" => "libstroke-devel",
+ "AC_CHECK_LIBM" => "libtool",
+ "AC_DISABLE_SHARED" => "libtool",
+ "AC_DISABLE_STATIC" => "libtool",
+ "AC_ENABLE_SHARED" => "libtool",
+ "AC_ENABLE_STATIC" => "libtool",
+ "AC_LIBTOOL_COMPILER_OPTION" => "libtool",
+ "AC_LIBTOOL_DLOPEN_SELF" => "libtool",
+ "AC_LIBTOOL_LINKER_OPTION" => "libtool",
+ "AC_LIBTOOL_SYS_MAX_CMD_LEN" => "libtool",
+ "AC_PATH_TOOL_PREFIX" => "libtool",
+ "AC_PROG_LD" => "libtool",
+ "AC_PROG_LIBTOOL" => "libtool",
+ "AC_PROG_NM" => "libtool",
+ "AM_PROG_LD" => "libtool",
+ "AM_PROG_LIBTOOL" => "libtool",
+ "AM_PROG_NM" => "libtool",
+ "LTOBSOLETE_VERSION" => "libtool",
+ "LTOPTIONS_VERSION" => "libtool",
+ "LTSUGAR_VERSION" => "libtool",
+ "LTVERSION_VERSION" => "libtool",
+ "LT_AC_PROG_GCJ" => "libtool",
+ "LT_AC_PROG_RC" => "libtool",
+ "LT_AC_PROG_SED" => "libtool",
+ "LT_CMD_MAX_LEN" => "libtool",
+ "LT_INIT" => "libtool",
+ "LT_LANG" => "libtool",
+ "LT_LIB_M" => "libtool",
+ "LT_OUTPUT" => "libtool",
+ "LT_PATH_LD" => "libtool",
+ "LT_PATH_NM" => "libtool",
+ "LT_PROG_GCJ" => "libtool",
+ "LT_PROG_RC" => "libtool",
+ "LT_SUPPORTED_TAG" => "libtool",
+ "LT_SYS_DLOPEN_SELF" => "libtool",
+ "_LT_COMPILER_OPTION" => "libtool",
+ "_LT_LINKER_OPTION" => "libtool",
+ "_LT_PATH_TOOL_PREFIX" => "libtool",
+ "XIPH_PATH_VORBIS" => "libvorbis-devel",
+ "AM_PATH_XML2" => "libxml2-devel",
+ "AM_PATH_XSLT" => "libxslt-devel",
+ "AC_PATH_LIRC" => "lirc-devel",
+ "AM_PATH_LOG4CPP" => "log4cpp-devel",
+ "ENABLE_DOCUMENTATION" => "mm-common",
+ "MYSQL_CLIENT" => "mysql-devel",
+ "_MYSQL_CONFIG" => "mysql-devel",
+ "AM_PATH_NSPR" => "nspr-devel",
+ "AM_PATH_LIBOPENCDK" => "opencdk-devel",
+ "AC_FIND_LIBXP" => "openmotif-devel",
+ "AC_FIND_MOTIF" => "openmotif-devel",
+ "PARTED_CHECK_LIBPARTED" => "parted-devel",
+ "AM_PATH_PURPLE" => "pidgin-devel",
+ "AC_PILOT_LINK" => "pilot-link-devel",
+ "AC_PILOT_LINK_HOOK" => "pilot-link-devel",
+ "PKCS11_HELPER_1_CHECK_FEATURES" => "pkcs11-helper-devel",
+ "PKG_CHECK_EXISTS" => "pkgconfig",
+ "PKG_CHECK_MODULES" => "pkgconfig",
+ "PKG_PROG_PKG_CONFIG" => "pkgconfig",
+ "_PKG_SHORT_ERRORS_SUPPORTED" => "pkgconfig",
+ "AC_CHECK_LIBREISERFS" => "progsreiserfs-devel",
+ "AC_CHECK_PTH" => "pth-devel",
+ "_AC_PTH_ERROR" => "pth-devel",
+ "_AC_PTH_VERBOSE" => "pth-devel",
+ "AC_CHECK_LIBREISER4" => "reiser4progs-devel",
+ "AM_PATH_SANE" => "sane-backends-devel",
+ "AC_PROG_SHTOOL" => "shtool",
+ "AM_PATH_SMPEG" => "smpeg-devel",
+ "AM_PATH_SOUNDTOUCH" => "soundtouch-devel",
+ "XIPH_PATH_SPEEX" => "speex-devel",
+ "AM_PATH_LIBUNSHIELD" => "synce-unshield-libs-devel",
+ "AC_PROG_SYSCONFTOOL" => "sysconftool",
+ "AM_PATH_TN5250" => "tn5250-devel",
+ "AM_OPTIONS_WXCONFIG" => "wxWidgets-devel",
+ "AM_PATH_WXCONFIG" => "wxWidgets-devel",
+ "AM_PATH_WXRC" => "wxWidgets-devel",
+ "_WX_PRIVATE_CHECK_VERSION" => "wxWidgets-devel",
+ "XO_LIB_XAPIAN" => "xapian-core-devel",
+ "AM_PATH_XDELTA" => "xdelta-devel",
+ "BM_DEBUG_SUPPORT" => "xfce4-dev-tools",
+ "BM_DEPEND" => "xfce4-dev-tools",
+ "BM_DEPEND_CHECK" => "xfce4-dev-tools",
+ "BM_I18N" => "xfce4-dev-tools",
+ "BM_LIBSM" => "xfce4-dev-tools",
+ "BM_LIBX11" => "xfce4-dev-tools",
+ "BM_LIBX11_REQUIRE" => "xfce4-dev-tools",
+ "BM_LIBXPM" => "xfce4-dev-tools",
+ "BM_LIBXPM_REQUIRE" => "xfce4-dev-tools",
+ "XDT_CHECK_LIBSM" => "xfce4-dev-tools",
+ "XDT_CHECK_LIBX11" => "xfce4-dev-tools",
+ "XDT_CHECK_LIBX11_REQUIRE" => "xfce4-dev-tools",
+ "XDT_CHECK_LIBXPM" => "xfce4-dev-tools",
+ "XDT_CHECK_LIBXPM_REQUIRE" => "xfce4-dev-tools",
+ "XDT_CHECK_OPTIONAL_PACKAGE" => "xfce4-dev-tools",
+ "XDT_CHECK_PACKAGE" => "xfce4-dev-tools",
+ "XDT_CHECK_PYTHON_HEADERS" => "xfce4-dev-tools",
+ "XDT_FEATURE_DEBUG" => "xfce4-dev-tools",
+ "XDT_I18N" => "xfce4-dev-tools",
+ "XDT_PROG_PKG_CONFIG" => "xfce4-dev-tools",
+ "XDT_XFCE_MCS_PLUGIN" => "xfce4-dev-tools",
+ "XDT_XFCE_PANEL_PLUGIN" => "xfce4-dev-tools",
+ "XFCE_MCS_PLUGIN" => "xfce4-dev-tools",
+ "XFCE_PANEL_PLUGIN" => "xfce4-dev-tools",
+ "AM_PATH_XINE" => "xine-lib-devel",
+ "AM_PATH_XMLSEC1" => "xmlsec1-devel",
+ "AM_PATH_XMMS" => "xmms-devel",
+ "XMMS_TEST_VERSION" => "xmms-devel",
+ "XORG_FONTDIR" => "xorg-font-font-util",
+ "XORG_FONTROOTDIR" => "xorg-font-font-util",
+ "XORG_FONTSUBDIR" => "xorg-font-font-util",
+ "XORG_FONT_BDF_UTILS" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_COMPRESSION" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ENCODING" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ENCODING_LIST" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_1" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_10" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_11" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_12" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_13" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_14" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_15" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_16" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_2" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_3" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_4" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_5" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_6" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_7" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_8" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_ISO8859_9" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_JISX0201" => "xorg-font-font-util",
+ "XORG_FONT_CHECK_KOI8_R" => "xorg-font-font-util",
+ "XORG_FONT_COMMON_UTILS" => "xorg-font-font-util",
+ "XORG_FONT_FCCACHE" => "xorg-font-font-util",
+ "XORG_FONT_REQUIRED_PROG" => "xorg-font-font-util",
+ "XORG_FONT_SCALED_UTILS" => "xorg-font-font-util",
+ "XORG_FONT_UCS2ANY" => "xorg-font-font-util",
+ "XTRANS_CONNECTION_FLAGS" => "xorg-lib-xtrans-devel",
+ "XTRANS_SECURE_RPC_FLAGS" => "xorg-lib-xtrans-devel",
+ "XTRANS_TCP_FLAGS" => "xorg-lib-xtrans-devel",
+ "XORG_CHANGELOG" => "xorg-util-util-macros",
+ "XORG_CHECK_DOCBOOK" => "xorg-util-util-macros",
+ "XORG_CHECK_LINUXDOC" => "xorg-util-util-macros",
+ "XORG_CHECK_MALLOC_ZERO" => "xorg-util-util-macros",
+ "XORG_CWARNFLAGS" => "xorg-util-util-macros",
+ "XORG_DEFAULT_OPTIONS" => "xorg-util-util-macros",
+ "XORG_LINT_LIBRARY" => "xorg-util-util-macros",
+ "XORG_MANPAGE_SECTIONS" => "xorg-util-util-macros",
+ "XORG_PROG_RAWCPP" => "xorg-util-util-macros",
+ "XORG_RELEASE_VERSION" => "xorg-util-util-macros",
+ "XORG_STRICT_OPTION" => "xorg-util-util-macros",
+ "XORG_WITH_LINT" => "xorg-util-util-macros",
+ "XORG_DRIVER_CHECK_EXT" => "xorg-xserver-server-devel",
+ "AM_PATH_LIBXOSD" => "xosd-devel",
+ "YAZ_DOC" => "yaz-devel",
+ "YAZ_INIT" => "yaz-devel",
+ "PKG_CHECK_ZZIPLIB" => "zziplib-devel",
diff --git a/bin/findunusedbr b/bin/findunusedbr
new file mode 100755
index 0000000..daf4c37
--- /dev/null
+++ b/bin/findunusedbr
@@ -0,0 +1,101 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+die "Arguments missing: $0 [-c] <chroot> <spec>\n" unless @ARGV;
+my $clear;
+if ( $ARGV[0] eq "-c" ) {
+ $clear = 1;
+ shift @ARGV;
+}
+my $chroot = shift @ARGV or die "chroot directory not specified\n";
+my $spec = shift @ARGV or die "Spec file not specified\n";
+
+-d $chroot or die "chroot '$chroot' is not a directory\n";
+-r $spec or die "spec file '$spec' is not readable\n";
+
+my @rpms;
+open F_IN, "<", $spec or die "Cannot open '$spec'\n";
+while ( <F_IN> ) {
+ if ( /^\s*(?:%\{.*)?BuildRequires:\s*(\S+)/i ) {
+ local $_ = $1;
+ s/}$//;
+ push @rpms, $_;
+ } elsif ( /^%(prep|build|changelog)/ ) {
+ last;
+ }
+}
+close F_IN;
+
+sub clear_files
+{
+ my $rpm = shift;
+ my $files = shift;
+ foreach my $file ( @$files ) {
+ chop $file;
+ my $f = $chroot.$file;
+
+ local $_;
+ while ( $_ = readlink $f and m#^/# ) {
+ $f = $chroot.$_;
+ }
+
+ # skip missing files, like "%_excludedocs 0" being active
+ next unless stat $f;
+
+ # XXX: this truncates mtime to its low resolution value
+ my $mtime = (stat $f)[9];
+ warn "Mtime failed on $f" unless $mtime;
+ utime 0, $mtime, $f;
+ }
+}
+
+sub check_files
+{
+ my $rpm = shift;
+ my $files = shift;
+ #my $used = 0;
+ foreach my $file ( @$files ) {
+ chop $file;
+ my $f = $chroot.$file;
+
+ local $_;
+ while ( $_ = readlink $f and m#^/# ) {
+ $f = $chroot.$_;
+ }
+
+ my $atime = (stat $f)[8];
+ if ( not defined $atime ) {
+ print "$rpm: $f no atime\n";
+ } elsif ( $atime > 0 ) {
+ #print "$rpm: $file accessed\n";
+ #$used = 1;
+ return;
+ } else {
+ #print "$rpm: $file NOT accessed !\n";
+ }
+ }
+ print "$rpm may be superfluous !\n";# unless $used;
+}
+
+sub rpm {
+ my @cmd = ("rpm", "--root=$chroot", @_);
+ open my $fh, '-|', @cmd or die "$!: @cmd";
+ my @data = <$fh>;
+ close $fh;
+ warn $! if $!;
+ return @data;
+}
+
+foreach my $rpm ( @rpms ) {
+ my @files = rpm("-ql", "--what-provides", "$rpm");
+ next if $files[0] =~ /^no package provides/;
+ #print "*** $rpm ***\n";
+ if ( $clear ) {
+ clear_files( $rpm, \@files );
+ } else {
+ check_files( $rpm, \@files );
+ }
+ #print "\n\n";
+}
diff --git a/bin/fixfreq b/bin/fixfreq
new file mode 100755
index 0000000..befec4d
--- /dev/null
+++ b/bin/fixfreq
@@ -0,0 +1,54 @@
+#!/usr/bin/perl
+
+use Fcntl;
+my $fifo = "/tmp/fixfreq";
+
+system "mkfifo", $fifo;
+chmod 0600, $fifo;
+
+sysopen( READ_PIDS, $fifo, O_NONBLOCK|O_RDONLY) or die "Can't open modem: $!\n";
+
+
+END {
+ set( 0 );
+ close READ_PIDS;
+ unlink $fifo;
+}
+
+sub bye { exit; }
+
+$SIG{TERM} = \&bye;
+$SIG{INT} = \&bye;
+
+my $now_is = "";
+sub set
+{
+ my $num = shift;
+ my $set_to = $num ? "performance" : "ondemand";
+ return if $now_is eq $set_to;
+ $now_is = $set_to;
+ foreach my $gov ( glob "/sys/devices/system/cpu/cpu[0-9]*/cpufreq/scaling_governor" ) {
+ open GOV, ">", $gov;
+ print GOV $set_to;
+ close GOV;
+ }
+}
+
+my %pids;
+
+while ( 1 ) {
+ foreach my $pid ( keys %pids ) {
+ unless ( -d "/proc/".$pid ) {
+ delete $pids{ $pid };
+ }
+ }
+ while ( my $pid = <READ_PIDS> ) {
+ chomp $pid;
+ if ( -d "/proc/$pid" ) {
+ $pids{ $pid } = 1;
+ }
+ }
+ set( keys %pids );
+ sleep 1;
+}
+
diff --git a/bin/multibuild b/bin/multibuild
new file mode 100755
index 0000000..acf5330
--- /dev/null
+++ b/bin/multibuild
@@ -0,0 +1,151 @@
+#!/bin/sh
+
+b="$(echo -n -e '\033[1m')"
+B="$(echo -n -e '\033[22m')"
+r="$(echo -n -e '\033[31m')"
+g="$(echo -n -e '\033[32m')"
+c="$(echo -n -e '\033[33m')"
+e="$(echo -n -e '\033[0m')"
+
+ignore() { }
+MULTI_CONTINUE=false
+[ -r .cleanbuildrc ] && . ./.cleanbuildrc
+
+[ -d mbuild ] || mkdir mbuild
+
+end_pkg()
+{
+ result=fail
+ [ $ret -eq 0 ] && result=ok
+ mv mbuild/start.$package mbuild/$result.$package
+}
+
+get_pkg()
+{
+ list="$1"
+ package=""
+ [ -r $list ] || return
+ while read pkg info; do
+ if [ ! -r mbuild/ok.$pkg ] && [ ! -r mbuild/fail.$pkg ] \
+ && [ ! -r mbuild/start.$pkg ]; then
+ package="$pkg"
+ touch mbuild/start.$package
+ break
+ fi
+ done < $list
+}
+
+
+next_pkg()
+{
+ get_pkg blist
+
+ [ -n "$package" ] && return
+
+ get_pkg blist2
+
+ if [ -z "$package" ]; then
+ echo "${c}Nothing to build${e}"
+ exit
+ fi
+}
+
+./clean "$@"
+package=
+next_pkg
+build="cleanbuild"
+while true; do
+ time ./$build "$@" $package
+ ret=$?
+
+ OLDPWD="$PWD"
+ cd $HOME/rpm/packages/$package
+ DIFF="$(cvs -z3 diff -u $package.spec)"
+ echo "$DIFF" | colordiff
+ cd $OLDPWD
+
+ if [ $ret -eq 0 ]; then
+ COLOR="$g"
+ else
+ COLOR="$r"
+ fi
+ echo "$COLOR$package build finished with exit status $ret$e"
+
+ if $MULTI_CONTINUE && [ $ret -eq 0 -a -z "$DIFF" ]; then
+ echo "Nothing changed: continuing\n"
+ ./clean "$@"
+ end_pkg
+ exec $0 "$@"
+ exit
+ fi
+
+ MULTI_CONTINUE=false
+
+ while true; do
+ echo
+ echo -n "${c}clean ${b}r${B}ebuild," "re${b}b${B}uild," \
+ "${b}i${B}nstall," "${b}a${B}ddbr," \
+ "${b}v${B}im," "${b}c${B}i," \
+ "${b}l${B}og," "${b}N${B}ext ?${e} "
+
+ read ans
+ case "x$ans" in
+ x[rR])
+ build="cleanbuild"
+ ;;
+ x[bB])
+ build="build"
+ ;;
+ x[iI])
+ echo -n "${c}install>${e} "
+ read pkg
+ ./install "$@" $pkg
+ echo "pkg installed with exit status $?"
+ continue
+ ;;
+ x[aA])
+ echo -n "${c}br>${e} "
+ read pkg
+ ./install "$@" $pkg
+ echo "pkg installed with exit status $?"
+ [ $? == 0 ] && ./addbr $package $pkg "requested"
+ continue
+ ;;
+ x[vV])
+ vim $HOME/rpm/packages/$package/$package.spec
+ continue
+ ;;
+ x[cC])
+ cd $HOME/rpm/packages/
+ ./ci $package
+ cd -
+ continue
+ ;;
+ x[lL])
+ vim buildlogs/$package
+ continue
+ ;;
+ xN)
+ ./clean "$@"
+ end_pkg
+ exec $0 "$@"
+ exit
+ ;;
+ xn)
+ echo "upper case N required"
+ continue
+ ;;
+ x[qQ])
+ ./clean "$@"
+ end_pkg
+ exit
+ ;;
+ *)
+ continue
+ ;;
+ esac
+ break
+ done
+done
+
+# vim: ts=4:sw=4
diff --git a/bin/teeboth b/bin/teeboth
new file mode 100755
index 0000000..6054118
--- /dev/null
+++ b/bin/teeboth
@@ -0,0 +1,67 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+use Fcntl;
+use POSIX ":sys_wait_h";
+use IPC::Open3;
+use IO::Handle;
+use IO::Select;
+
+my $out = shift @ARGV;
+die unless @ARGV;
+
+open my $fout, ">", $out or die;
+
+my $select = IO::Select->new();
+my $alive = 1;
+my $pid;
+
+my $code;
+sub sigchld
+{
+ my $kid;
+ do {
+ $kid = waitpid( -1, WNOHANG );
+ if ( $kid == $pid ) {
+ $code = $? >> 8;
+ $alive = 0
+ }
+ } while ( $kid > 0 );
+}
+$SIG{CHLD} = \&sigchld;
+
+$pid = open3( \*child_in, \*child_out, \*child_err, @ARGV );
+close child_in;
+
+sub sethandle
+{
+ my $h = shift;
+ my $flags = 0;
+
+ fcntl ( $h, F_GETFL, $flags )
+ or die "Couldn't get flags for HANDLE : $!\n";
+ $flags |= O_NONBLOCK;
+ fcntl ( $h, F_SETFL, $flags )
+ or die "Couldn't set flags for HANDLE: $!\n";
+
+ $select->add( $h );
+}
+
+sethandle( \*child_out );
+sethandle( \*child_err );
+
+while ( $alive ) {
+ foreach my $h ( $select->can_read() ) {
+ sysread $h, $_, 102400;
+ print $fout $_;
+ if ( $h == \*child_err ) {
+ print "\033[31m$_\033[0m";
+ } else {
+ print $_;
+ }
+ STDOUT->flush();
+ }
+}
+
+exit $code;