Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 07 Dec 2009 17:42:58 +0200
From:      =?utf-8?B?QW5kcml1cyBNb3JrxatuYXM=?= <hinokind@gmail.com>
To:        freebsd-ports@freebsd.org
Subject:   [patch] fix config-recursive
Message-ID:  <op.u4kq9wxy43o42p@klevas>

next in thread | raw e-mail | index | archive | help
------------RolSDr4pxGWbTbVbuZwNMe
Content-Type: text/plain; charset=utf-8; format=flowed; delsp=yes
Content-Transfer-Encoding: 7bit

Anyone who uses config-recursive more often than once a year knows that
it's broken. Or at least they know it needs to be run multiple times until
it doesn't show options dialog. While some people might just live with it,
I think it should be fixed properly, and so did the person who introduced
this target: "it sufficed to run config-recursive twice to catch all of the
dependancies I had configured. Maybe we can figure out how to it all in one
pass later"[1]. The "later" is now, almost 5 years after config-recursive
was first introduced [2].


As I was complaining on IRC how many times I had to run config-recursive to
finally config gnome2, someone told me "just rewrite it". And I did...
Probably the only reason this wasn't fixed earlier is that no one was
annoyed enough to write a patch.


The patch changes config-recursive so that it does a dependency check right
after config is saved for a particular port, effectively configuring only
the ports that are needed and configuring all dependencies in one pass.


rmconfig-recursive is not exactly ok either. Actually, it's even more
complicated. It removes all saved options for a particular port and its
dependencies. However new dependencies that were previously disabled are
introduced. Since rmconfig-recursive doesn't know about them during first
pass, it doesn't remove their options, creating a similar situation to
config-recursive. I'm not sure what to do about rmconfig-recursive,
because:
1. Some users may not like if there are changes in how it operates.
2. It's a pain to make it "do the right thing" without slowing it down or
making its output slightly different from the original.

However, I believe it's pretty safe to assume that if user is doing
rmconfig-recursive, he wants to clear options for all dependencies, both
currently selected via options and the default ones.
But here's a catch: there are options that are not enabled by default, not
selected by user, but may be configured already. I chose not to do anything
with them, because unconditionaly removing config for all possible
dependencies could wipe most of options user has ever set. It would be
possible to remove options for all possible dependencies only when something
like RMCONFIG_ALL is defined, but then it would do something similar to
"rm -f /var/db/ports/*/options", except much slower.

I've added changes to rmconfig-recursive to the patch, it's now slighly
slower than it was before, however still faster than running it twice or
no-idea-how-many-times. rmconfig-recursive now removes config for current
and default dependencies.
I've also added rmconfig-internal target, to be used by rmconfig-recursive.
It's very similar to rmconfig, but simplified and its output is intended to
be used by make itself rather than be human readable.


Target showconfig-recursive is fine, since it doesn't really do anything
with options.


My [rm]config-recursive is heavily based on all-depends-list, so it may help
understanding my patch better if you read and understand that target first.
Patch should be ok, but since it was rewritten and/or edited many times,
I may have left some unnecessary or otherwise wrong code. I'd appreciate
feedback and testing, if everything goes well I'll submit a pr for this.

1. http://www.freebsd.org/cgi/query-pr.cgi?pr=76254
2. http://lists.freebsd.org/pipermail/freebsd-ports/2004-December/018765.html

-- 
Andrius
------------RolSDr4pxGWbTbVbuZwNMe
Content-Disposition: attachment; filename=bsd.port.mk.diff
Content-Type: text/plain; name=bsd.port.mk.diff
Content-Transfer-Encoding: 7bit

--- Mk/bsd.port.mk.orig	2009-11-26 00:02:29.000000000 +0200
+++ Mk/bsd.port.mk	2009-12-07 17:04:41.845806510 +0200
@@ -6073,9 +6073,36 @@
 
 .if !target(config-recursive)
 config-recursive:
-	@${ECHO_MSG} "===> Setting user-specified options for ${PKGNAME} and dependencies";
-	@for dir in ${.CURDIR} $$(${ALL-DEPENDS-LIST}); do \
-		(cd $$dir; ${MAKE} config-conditional); \
+	@${ECHO_MSG} "===> Setting user-specified options for ${PKGNAME} and dependencies"; \
+	${MAKE} config-conditional;					\
+	L=$$(${MAKE} -V _DEPEND_DIRS);					\
+	checked="";							\
+	while [ -n "$$L" ]; do						\
+		l="";							\
+		for d in $$L; do					\
+			case $$checked in				\
+			$$d\ *|*\ $$d\ *|*\ $$d)			\
+				continue;;				\
+			esac;						\
+			checked="$$checked $$d";			\
+			if [ ! -d $$d ]; then				\
+				${ECHO_MSG} "${PKGNAME}: \"$$d\" non-existent -- recursive config incomplete" >&2; \
+				continue;				\
+			fi;						\
+			${MAKE} -C $$d config-conditional;		\
+			if ! children=$$(cd $$d && ${MAKE} -V _DEPEND_DIRS); then \
+				${ECHO_MSG} "${PKGNAME}: \"$$d\" erroneous -- recursive config incomplete" >&2; \
+				continue;				\
+			fi;						\
+			for child in $$children; do			\
+				case "$$checked $$l" in			\
+				$$child\ *|*\ $$child\ *|*\ $$child)	\
+					continue;;			\
+				esac;					\
+				l="$$l $$child";			\
+			done;						\
+		done;							\
+		L=$$l;							\
 	done
 .endif
 
@@ -6169,12 +6196,56 @@
 
 .if !target(rmconfig-recursive)
 rmconfig-recursive:
-	@${ECHO_MSG} "===> Removing user-specified options for ${PKGNAME} and dependencies";
-	@for dir in ${.CURDIR} $$(${ALL-DEPENDS-LIST}); do \
-		(cd $$dir; ${MAKE} rmconfig); \
+	@${ECHO_MSG} "===> Removing user-specified options for ${PKGNAME} and dependencies"; \
+	L=$$(${MAKE} -V _DEPEND_DIRS);					\
+	checked="";							\
+	while [ -n "$$L" ]; do						\
+		l="";							\
+		for d in $$L; do					\
+			case $$checked in				\
+			$$d\ *|*\ $$d\ *|*\ $$d)			\
+				continue;;				\
+			esac;						\
+			checked="$$checked $$d";			\
+			if [ ! -d $$d ]; then				\
+				${ECHO_MSG} "${PKGNAME}: \"$$d\" non-existent -- recursive rmconfig incomplete" >&2; \
+				continue;				\
+			fi;						\
+			if ! children=$$(${MAKE} -C $$d -V _DEPEND_DIRS); then \
+				${ECHO_MSG} "${PKGNAME}: \"$$d\" erroneous -- recursive rmconfig incomplete" >&2; \
+				continue;				\
+			fi;						\
+			if (${MAKE} -C $$d rmconfig-internal > /dev/null); then \
+				${ECHO_MSG} "===> Removing user-configured options for `${MAKE} -C $$d -V PKGNAME`"; \
+				children="$${children} $$(${MAKE} -C $$d -V _DEPEND_DIRS)"; \
+			else						\
+				${ECHO_MSG} "===> No user-specified options configured for `${MAKE} -C $$d -V PKGNAME`"; \
+			fi;						\
+			for child in $$children; do			\
+				case "$$checked $$l" in			\
+				$$child\ *|*\ $$child\ *|*\ $$child)	\
+					continue;;			\
+				esac;					\
+				l="$$l $$child";			\
+			done;						\
+		done;							\
+		L=$$l;							\
 	done
 .endif
 
+# This should only be used by rmconfig-recursive.
+.if !target(rmconfig-internal)
+rmconfig-internal:
+.if defined(OPTIONS) && exists(${OPTIONSFILE})
+	-@${ECHO_CMD}; \
+	optionsdir=${OPTIONSFILE}; optionsdir=$${optionsdir%/*}; \
+	${RM} -f ${OPTIONSFILE}; \
+	${RMDIR} $${optionsdir};
+.else
+	exit 1;
+.endif
+.endif
+
 desktop-categories:
 	@categories=""; \
 	for native_category in ${CATEGORIES}; do \

------------RolSDr4pxGWbTbVbuZwNMe--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?op.u4kq9wxy43o42p>