Ulrich Spoerlein wrote: > I wrote a script That got stripped by the mailling lists ... second try. You can also fetch it from
http://coyote.dnsalias.net/create_pkg_makefile.sh Ulrich Spoerlein -- "The trouble with the dictionary is you have to know how the word is spelled before you can look it up to see how it is spelled." -- Will Cuppy
#!/usr/bin/env zsh # vi:set sw=2 tw=78: # # "THE BEER-WARE LICENSE" (Revision 42): # <[EMAIL PROTECTED]> wrote this file. As long as you retain this notice you # can do whatever you want with this stuff. If we meet some day, and you think # this stuff is worth it, you can buy me a beer in return. Ulrich Spoerlein # # What this is: # # This script will output a Makefile, that is self-contained and suitable for # building individual sets of packages with maximum parallelism. # # Who it is for: # # For people needing to build clean packages, probably with a custom # make.conf, for system deployment. # # How it works: # # It will recursively walk the $PORTS tree for the specified package origins # (or all POs if none are given) and create the correct dependency tree plus # targets to build those packages. # # To guarantee a clean package without "contamination", as can happen by # configure scripts picking up random installed libraries, it uses a clean # "installworld" provided by either an unionfs mount or by copying the tree to # the destination. (There are a some problems with unionfs mounts, if packages # don't build, try the cpio method first.) # # How to use: # # First, you need to create a clean environment: # cd $SRC && make buildworld installworld distribution DESTDIR=$ROOT/live # mkdir -p $ROOT/live/usr/ports $ROOT/distfiles $ROOT/obj $ROOT/packages/All # # Since we can't change make(1)s .OBJDIR to some arbitrary value, create an # obj link to the package directory: # ln -sf $ROOT/packages/All obj # # Create a make.conf with your desired flags, set CONF=$PWD/make.conf # (default) # vi make.conf # # And torture your machine # ./create_pkg_makefiles.sh editors/vim x11/kde3 | make -f- -j4 all # # To watch the build progressing, use something like: # while sleep 3; do screen -r; done # # The Makefile for all ports can be created by: # ./create_pkg_makefiles.sh > Makefile # # The special "check" target will only print what packages would be build; # use it in conjunction with "all" or your desired package origins. # make -j4 check editors/vim x11/kde3 # make check all # # To update all your installed packages, a heavy handed approach would be to: # cp /etc/make.conf . # ./create_pkg_makefiles.sh `pkg_info -qao` | make -f- -j2 all # pkg_delete -fa # pkg_add -F $ROOT/packages/All/* # # User configuration ROOT=/vol PORTS=/usr/ports SRC=/usr/src CONF=$PWD/make.conf #CONF=/etc/make.conf # End of user configuration. # Global hash, saving pkg-origin -> pkg-name. Is also used to look up # which pkg-origins have already been checked. typeset -A pkg print_make_header() { cat <<EOS # Root dir of build space R=${ROOT} B=\$R/live O=\$R/obj PKG=\$R/packages DIST=\$R/distfiles # Source directories S=${SRC} P=${PORTS} CONF=${CONF} # Choose your poison MK_LIVE_TREE= cd \$B && find . | cpio --quiet -dump \$O/\$\$po UNMK_LIVE_TREE= rm -rf \$O/\$\$po #MK_LIVE_TREE= zfs clone ... #UNMK_LIVE_TREE= zfs remove clone ... MK_LIVE_TREE= mount -t unionfs -o below,noatime \$B \$O/\$\$po UNMK_LIVE_TREE= umount \$O/\$\$po; rm -rf \$O/\$\$po CLEAN_BUILD_SPACE=clean_build_space() { set +e; po=\$\$1; shift; \ umount \$O/\$\$po/usr/ports/packages; \ umount \$O/\$\$po/usr/ports/distfiles; \ umount \$O/\$\$po/usr/ports; \ umount \$O/\$\$po/usr/src; \ umount \$O/\$\$po/compat/linux/proc; \ umount \$O/\$\$po/dev; \ \${UNMK_LIVE_TREE}; return 0; }; clean_build_space CREATE_BUILD_SPACE=create_build_space() { po=\$\$1; shift; \ mkdir -p \$O/\$\$po/usr/ports; \ mkdir -p \$O/\$\$po/compat/linux/proc; \ \${MK_LIVE_TREE}; \ mount -t devfs devfs \$O/\$\$po/dev; \ mount -t linprocfs linprocfs \$O/\$\$po/compat/linux/proc; \ mount -t nullfs -oro \$S \$O/\$\$po/usr/src; \ mount -t nullfs -oro \$P \$O/\$\$po/usr/ports; \ mount -t nullfs \${DIST} \$O/\$\$po/usr/ports/distfiles; \ mount -t nullfs \${PKG} \$O/\$\$po/usr/ports/packages; \ test ! -r "\${CONF}" || cp \${CONF} \$O/\$\$po/etc; }; create_build_space # The su(1) is required to have a fresh environment, otherwise the # make(1) vars of -jX will interfere with the package build. # screen(1) will always exit with code 0, use test(1) outside of screen # to figure out if everything went well. CREATE_PACKAGE=create_package() { set -e; po=\$\$1; shift; \ cd \$O/\$\$po && screen -L -D -m chroot . time -lp -o time.out sh -ec "\ for dep in \${.ALLSRC}; do \ echo \"Adding package \\\$\${dep}\"; \ PKG_PATH=/usr/ports/packages/All pkg_add -F \\\$\${dep%.tbz}; \ done; \ su -l root -c \"make -C /usr/ports/\$\$po WRKDIRPREFIX=/usr/obj \ BATCH=yes build package\""; \ test -f \${PKG}/All/\${.TARGET}; }; create_package PARSE_TIME=parse_time() { po=\$\$1; shift; \ awk -v po=\$\$po '/real/{r=\$\$2} /user/{u=\$\$2} \ /sys/{s=\$\$2} /resident set size/{rss=\$\$1} \ END{print po ": real " r " user " u " sys " s " rss " rss}' \ \$O/\$\$po/time.out 2>/dev/null; }; parse_time .SILENT: check: EOS } print_pkg() { local po po=$1; shift cat <<EOS $po: ${pkg[$po]} ${pkg[$po]}: $* .if make(check) echo "$po: Building \${.TARGET} <= \${.ALLSRC}" .else for dep in $*; do test -f \${PKG}/All/\$\$dep || \\ (echo \"$po: Missing dep \$\$dep, skipped\"; exit 1); done echo '$po: Preparing build space' \${CLEAN_BUILD_SPACE} $po 2>/dev/null \${CREATE_BUILD_SPACE} $po echo '$po: Building package' \${CREATE_PACKAGE} $po \${PARSE_TIME} $po echo '$po: Cleaning build space' \${CLEAN_BUILD_SPACE} $po .endif EOS } get_pkg_recursive() { local po list depport deplist level po=$1; shift level="${1}="; shift # Don't revisit already visited nodes if [ -n "$pkg[$po]" ]; then return fi if [ -z "$pkg[$po]" ]; then pkg[$po]=$(make -C $po __MAKE_CONF=$CONF -V PKGNAME).tbz fi printf "%-45s %s\n" "$level > $po" $pkg[$po] >&2 # Get dependency dirs list=$(make -C $po __MAKE_CONF=$CONF -V _DEPEND_DIRS | sed "s|${PORTS}/*||g") for depport in `eval echo $list`; do if [ -z "$pkg[$depport]" ]; then get_pkg_recursive $depport $level fi case "$deplist" in *${pkg[$depport]}*) ;; *) deplist="$deplist ${pkg[$depport]}" ;; esac done echo "$level < $po" >&2 print_pkg $po `eval echo $deplist` } # Main entry point print_make_header cd $PORTS if [ "$#" -gt 0 ]; then for po; do get_pkg_recursive $po "" done else for sub in $(make -C $PORTS -V SUBDIR); do for port in $(make -C $PORTS/$sub -V SUBDIR); do get_pkg_recursive $sub/$port "" done done fi printf "\nall: $pkg\n"
pgpqnIvcE9wkW.pgp
Description: PGP signature