INDEX user-friendliness and SMP speed-up patch
Kris Kennaway
kris at obsecurity.org
Mon Mar 15 02:36:52 PST 2004
The attached patch does a few things to 'make index':
* Fixes the bsd.port.subdir.mk code that is supposed to report index
breakage (the fallback code wasn't actually being run because make
would halt immediately following the error). This should help with
INDEX error reports because it will immediately show the cause of
failure, so we won't have to pull teeth to extract it from the
submitter.
* Streamlines the 'make describe' code a bit.
* Provide some basic instructions to the user when an index build
fails, on when and how to report index build failures (turn this off
with INDEX_QUIET=1)
* Removed INDEX_NOSORT, because I couldn't imagine it to be very useful.
* Don't prevent INDEX builds from seeing the local host environment.
Since a lot of users are using 'make index' thesedays they should get
an index that reflects their local settings and installed ports. If
you want to build a 'default' index that isn't influenced by local
settings (e.g. for release builds), set the INDEX_PRISTINE variable.
* Allows parallel INDEX builds (using make -j). The most obvious way
of doing this doesn't work, because I/O from child makes is broken up
into 2k chunks, and output lines from 'make describe' that exceed this
length (*cough* GNOME *cough*) will be intertwined with the output of
other makes, leading to a corrupted INDEX. Instead, I collect the
output from the child make processes in temporary files and
recombine them at the end.
The number of concurrent make processes to spawn can be set using
INDEX_JOBS. By default this is set to 2, which seems to be a sweet
spot for both single and dual-processor systems. On my tests I do not
see any significant performance changes on UP, but on a dual 4.x
system the build time drops by 47% (6 minute index builds on one test
machine!). Depending on your disk and CPU hardware you might see
further gains with INDEX_JOBS=4 or higher, so you might like to
experiment to see what works best. On a dual 5.x system the
performance gains do not seem to be as great (20-30%), but this is
still a significant net win. I'd be interested to see benchmarks from
/usr/bin/time on various systems - make sure that the system is idle
while you're building index, because it is sensitive to disk loads.
Please test, and provide feedback.
Kris
-------------- next part --------------
Index: Makefile
===================================================================
RCS file: /home/ncvs/ports/Makefile,v
retrieving revision 1.81
diff -u -r1.81 Makefile
--- Makefile 23 Feb 2004 04:41:00 -0000 1.81
+++ Makefile 15 Mar 2004 09:52:23 -0000
@@ -70,20 +70,39 @@
@rm -f ${.CURDIR}/${INDEXFILE}
@cd ${.CURDIR} && make ${.CURDIR}/${INDEXFILE}
+INDEX_JOBS?= 2
+
${.CURDIR}/${INDEXFILE}:
@echo -n "Generating ${INDEXFILE} - please wait.."; \
- export LOCALBASE=/nonexistentlocal; \
- export X11BASE=/nonexistentx; \
- cd ${.CURDIR} && make describe ECHO_MSG="echo > /dev/null" | \
- perl ${.CURDIR}/Tools/make_index | \
- sed -e 's/ */ /g' -e 's/| */|/g' -e 's/ *|/|/g' -e "s,$${LOCALBASE},/usr/local," -e "s,$${X11BASE},/usr/X11R6," > ${INDEXFILE}
-.if !defined(INDEX_NOSORT)
- @sed -e 's./..g' ${.CURDIR}/${INDEXFILE} | \
+ if [ "${INDEX_PRISTINE}" != "" ]; then \
+ export LOCALBASE=/nonexistentlocal; \
+ export X11BASE=/nonexistentx; \
+ fi; \
+ tmpdir=`/usr/bin/mktemp -d -t index` || exit 1; \
+ trap "rm -rf $${tmpdir}; exit 1" 1 2 3 5 10 13 15; \
+ ( cd ${.CURDIR} && make -j${INDEX_JOBS} INDEX_TMPDIR=$${tmpdir} BUILDING_INDEX=1 \
+ ECHO_MSG="echo > /dev/null" describe ) || \
+ (rm -rf $${tmpdir} ; \
+ if [ "${INDEX_QUIET}" = "" ]; then \
+ echo; \
+ echo "********************************************************************"; \
+ echo "Before reporting this error, verify that you are running a supported"; \
+ echo "version of FreeBSD (see http://www.FreeBSD.org/ports/) and that you"; \
+ echo "have a complete and up-to-date ports collection. If so, then report"; \
+ echo "the failure to ports at FreeBSD.org together with relevant details of"; \
+ echo "your ports configuration (including FreeBSD version, environment and"; \
+ echo "/etc/make.conf settings)."; \
+ echo "********************************************************************"; \
+ echo; \
+ fi; \
+ exit 1); \
+ cat $${tmpdir}/${INDEXFILE}.desc.* | perl ${.CURDIR}/Tools/make_index | \
+ sed -e 's/ */ /g' -e 's/| */|/g' -e 's/ *|/|/g' -e "s,$${LOCALBASE},/usr/local," \
+ -e "s,$${X11BASE},/usr/X11R6," -e 's./..g' | \
sort -t '|' +1 -2 | \
- sed -e 's../.g' > ${.CURDIR}/${INDEXFILE}.tmp; \
- mv -f ${.CURDIR}/${INDEXFILE}.tmp ${.CURDIR}/${INDEXFILE}
-.endif
- @echo " Done."
+ sed -e 's../.g' > ${.CURDIR}/${INDEXFILE}; \
+ rm -rf $${tmpdir}; \
+ echo " Done."
print-index: ${.CURDIR}/${INDEXFILE}
@awk -F\| '{ printf("Port:\t%s\nPath:\t%s\nInfo:\t%s\nMaint:\t%s\nIndex:\t%s\nB-deps:\t%s\nR-deps:\t%s\n\n", $$1, $$2, $$4, $$6, $$7, $$8, $$9); }' < ${.CURDIR}/${INDEXFILE}
Index: Mk/bsd.port.subdir.mk
===================================================================
RCS file: /home/ncvs/ports/Mk/bsd.port.subdir.mk,v
retrieving revision 1.52
diff -u -r1.52 bsd.port.subdir.mk
--- Mk/bsd.port.subdir.mk 4 Feb 2004 04:27:04 -0000 1.52
+++ Mk/bsd.port.subdir.mk 15 Mar 2004 01:00:30 -0000
@@ -198,38 +195,35 @@
.if !target(describe)
.if defined(PORTSTOP)
+# This is a bit convoluted to deal with the fact that make will overlap I/O from child make processes
+# if they write more than 2k. This will corrupt the INDEX file, so we have to make sure that each
+# child make writes to their own file, which we will combine at the end. This gives substantial
+# performance benefits over doing a make -j1
+
+.if defined(BUILDING_INDEX)
+describe: ${SUBDIR:S/^/describe./}
+
+.for i in ${SUBDIR}
+describe.$i:
+ @${MAKE} -B ${i:S/^/_/:S/$/.describe/} > ${INDEX_TMPDIR}/${INDEXFILE}.desc.${i}
+.endfor
+.else
describe: ${SUBDIR:S/^/_/:S/$/.describe/}
+.endif
.else
describe:
- @TMPFILE=`mktemp -q /tmp/describe.XXXXXX` || exit 1; \
- for sub in ${SUBDIR}; do \
- OK=""; \
- for dud in $$DUDS; do \
- if [ $${dud} = $$sub ]; then \
- OK="false"; \
- ${ECHO_MSG} "===> ${DIRPRFX}$$sub skipped"; \
- fi; \
- done; \
- if test -d ${.CURDIR}/$${sub}.${MACHINE_ARCH}; then \
- edir=$${sub}.${MACHINE_ARCH}; \
- elif test -d ${.CURDIR}/$${sub}; then \
- edir=$${sub}; \
+ @for sub in ${SUBDIR}; do \
+ if test -d ${.CURDIR}/$${sub}; then \
+ ${ECHO_MSG} "===> ${DIRPRFX}$${sub}"; \
+ cd ${.CURDIR}/$${sub}; \
+ ${MAKE} -B describe 2> /dev/null || \
+ (echo "===> ${DIRPRFX}$${sub} failed:" >&2 ; \
+ cd ${.CURDIR}/$${sub}; ${MAKE} -B describe >&2; \
+ exit 1) ;\
else \
- OK="false"; \
${ECHO_MSG} "===> ${DIRPRFX}$${sub} non-existent"; \
fi; \
- if [ "$$OK" = "" ]; then \
- ${ECHO_MSG} "===> ${DIRPRFX}$${edir}"; \
- cd ${.CURDIR}/$${edir}; \
- ${MAKE} -B describe 2>$${TMPFILE}; \
- if [ -s $${TMPFILE} ]; then \
- echo "===> ${DIRPRFX}$${sub} failed:" >&2; \
- cat $${TMPFILE} >&2; \
- echo -n >$${TMPFILE}; \
- fi; \
- fi; \
- done; \
- rm -f $${TMPFILE}
+ done
.endif
.endif
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-ports/attachments/20040315/45074064/attachment.bin
More information about the freebsd-ports
mailing list