OPTIONS

Christopher Key cjk32 at cam.ac.uk
Sat Oct 9 19:02:51 UTC 2010


  On 06/10/2010 13:42, b. f. wrote:
>
> You can set those knobs via the command line, or via Makefile.{inc,
> ${ARCH}*, ${OPSYS}, local}, or via make.conf, where you can limit the
> scope based on the .CURDIR, etc.  Although we do have a problem, as
> you note in (4), with knobs that are OPTIONS, but are defined
> somewhere other than OPTIONSFILE. I hadn't seen:
>
> http://docs.freebsd.org/cgi/mid.cgi?4C476F69.1060200
>
> until swell.k pointed it out (thanks).  I think that it does some good
> things, but it does have some problems:
>
> --I don't think the priority is right: the "environment" settings
> ought to override the PORTS_DBDIR entries. This is because they will
> do so anyway in some circumstances (because of recursion, or the use
> of make -e/-E, or because you can't .undef some "environment"
> variables), but also because users may want to perform a test build
> with knobs defined in the "environment", without having to alter their
> settings in PORTS_DBDIR.
>
> --The parsing of the config files needs to be changed, so that
> _OPTION_SRC_${OPT} isn't set to "config" when it should be
> "environment" (see above). Also, the entries in OPTIONSFILE.local
> ought to override anything in OPTIONSFILE, without regard to
> precedence of WITHOUT_*.
>
> --There needs to be a final sanity-check, that fails with an
> appropriate error message if both WITH_* and WITHOUT_* are defined,
> because the .undefs are not sufficient to guarantee mutual
> exclusivity.
>
I'm afraid I'm really in a position to look at this closely now, but I 
think that the latest version (attached) might resolve some of the above 
problems.

Kind regards,

Christopher Key

-------------- next part --------------
Index: Mk/bsd.port.mk
===================================================================
RCS file: /home/ncvs/ports/Mk/bsd.port.mk,v
retrieving revision 1.643
diff -u -r1.643 bsd.port.mk
--- Mk/bsd.port.mk	15 Jul 2010 14:48:50 -0000	1.643
+++ Mk/bsd.port.mk	26 Jul 2010 12:31:53 -0000
@@ -1291,43 +1291,124 @@
 .endif
 OPTIONSFILE?=	${PORT_DBDIR}/${UNIQUENAME}/options
 .if defined(OPTIONS)
-# include OPTIONSFILE first if exists
+
+# Firstly, get a list of all options
+_OPTIONS_LIST=
+
+_FIELD=	0
+.	for O in ${OPTIONS:C/".*"//}
+.	if ${_FIELD} == 0
+_FIELD=	1
+_OPTIONS_LIST:=	${_OPTIONS_LIST} ${O}
+.	else
+_FIELD=	0
+.	endif
+.	endfor
+.	undef _FIELD
+
+# Get an on/off value for each option defined either in environment, make.conf, ports.conf or on the command line
+# Attempt to undef the corresponding WITH_XXX, WITHOUT_XXX (we'll restore them later) so that:
+# a) we can detect immutable options from the environment or command line
+# b) we can see what we read in
+.	for OPT in ${_OPTIONS_LIST}
+.	if defined(WITH_${OPT}) || defined(WITHOUT_${OPT})
+.	if defined(WITHOUT_${OPT}) # always check WITHOUT_XXX before WITH_XXX to give WITHOUT_XXX priority
+_OPTION_VAL_${OPT}=	off
+.	else
+_OPTION_VAL_${OPT}=	on
+.	endif
+_OPTION_SRC_${OPT}=	site
+.	undef WITH_${OPT}
+.	undef WITHOUT_${OPT}
+.   endif
+.   endfor
+
+# Detect which variables we failed to undef.  These will have been specified on the command line, and will be
+# immutable.  Check for duplicate WITH_XXX and WITHOUT_XXX, as we can't clean these up for the port.
+# Otherwise, update the option value to give cmdline priority over make.conf, ports.conf, and note that
+# this option is immutable, and cannot be overriden.
+.	for OPT in ${_OPTIONS_LIST}
+.	if defined(WITH_${OPT}) && defined(WITHOUT_${OPT})
+.	error You set both WITH_${OPT} and WITHOUT_${OPT}.  Abort.
+.	elif defined(WITH_${OPT}) || defined(WITHOUT_${OPT})
+.	if defined(WITHOUT_${OPT}) # always check WITHOUT_XXX before WITH_XXX to give WITHOUT_XXX priority
+_OPTION_VAL_${OPT}=	off
+.	else
+_OPTION_VAL_${OPT}=	on
+.	endif
+_OPTION_SRC_${OPT}=	env+args
+_OPTION_IMM_${OPT}=	true
+.   endif
+.   endfor
+
+# Include OPTIONSFILE if exists
 .	if exists(${OPTIONSFILE}) && !make(rmconfig)
 .	include "${OPTIONSFILE}"
 .	endif
 .	if exists(${OPTIONSFILE}.local)
 .	include "${OPTIONSFILE}.local"
 .	endif
-WITHOUT:=
-WITH:=
-.	if defined(OPTIONS)
-REALOPTIONS=${OPTIONS:C/".*"//g}
-.	for O in ${REALOPTIONS}
-RO:=${O}
-.	if ${RO:L} == off
-WITHOUT:=	${WITHOUT} ${OPT}
+
+# Update our list of option values based on what we read from our config file.  Only override the option
+# value if it isn't immutable, but always try to unset WITH_XXX and WITHOUT_XXX.  We'll restore them later,
+# ensuring that WITH_XXX and WITHOUT_XXX are mutually exclusive.
+.	for OPT in ${_OPTIONS_LIST}
+.	if defined(WITH_${OPT}) || defined(WITHOUT_${OPT})
+.	if !defined(_OPTION_IMM_${OPT})
+.	if defined(WITHOUT_${OPT}) # always check WITHOUT_XXX before WITH_XXX to give WITHOUT_XXX priority
+_OPTION_VAL_${OPT}=	off
+.	else
+_OPTION_VAL_${OPT}=	on
+.	endif
+_OPTION_SRC_${OPT}=	config
+.	endif
+.	undef WITH_${OPT}
+.	undef WITHOUT_${OPT}
+.   endif
+.   endfor
+
+# Set default value for remaining options
+_FIELD=	0
+.	for O in ${OPTIONS:C/".*"//}
+.	if ${_FIELD} == 0
+_FIELD=	1
+OPT:=	${O}
+.	else
+_FIELD=	0
+.	if !defined(_OPTION_VAL_${OPT})
+_OPTION_VAL_${OPT}:=	${O:L}
+_OPTION_SRC_${OPT}=	default
 .	endif
-.	if ${RO:L} == on
-WITH:=		${WITH} ${OPT}
 .	endif
-OPT:=${RO}
 .	endfor
+.	undef _FIELD
+.	undef OPT
+
+# restore WITH_XXX, WITHOUT_XXX appropriately
+.	for OPT in ${_OPTIONS_LIST}
+.	if ${_OPTION_VAL_${OPT}} == on
+WITH_${OPT}=	true
+.	else
+WITHOUT_${OPT}=	true
 .	endif
-# define only if NO WITH/WITHOUT_${W} is defined
-.	for W in ${WITH}
-.   if !defined(WITH_${W}) && !defined(WITHOUT_${W})
-WITH_${W}:=	true
-.   endif
 .	endfor
-.	for W in ${WITHOUT}
-.   if !defined(WITH_${W}) && !defined(WITHOUT_${W})
-WITHOUT_${W}:=	true
-.   endif
+
+# shell script to set variables for current option values
+_OPTIONS_SET_SH=
+.	for OPT in ${_OPTIONS_LIST}
+_OPTIONS_SET_SH:=	${_OPTIONS_SET_SH} \
+					OPTION_SRC_${OPT}=${_OPTION_SRC_${OPT}}; \
+					OPTION_VAL_${OPT}=${_OPTION_VAL_${OPT}};
 .	endfor
-.	undef WITH
-.	undef WITHOUT
-.	undef RO
-.	undef REALOPTIONS
+
+# clean up
+.	for OPT in ${_OPTIONS_LIST}
+.	undef _OPTION_VAL_${OPT}
+.	undef _OPTION_SRC_${OPT}
+.	undef _OPTION_IMM_${OPT}
+.	endfor
+.	undef _OPTIONS_LIST
+
 .endif
 
 .endif
@@ -6102,24 +6183,11 @@
 	${MKDIR} $${optionsdir} 2> /dev/null) || \
 		(${ECHO_MSG} "===> Cannot create $${optionsdir}, check permissions"; exit 1)
 .endif
-	- at if [ -e ${OPTIONSFILE} ]; then \
-		. ${OPTIONSFILE}; \
-	fi; \
+	-@${_OPTIONS_SET_SH} \
 	set -- ${OPTIONS} XXX; \
 	while [ $$# -gt 3 ]; do \
 		OPTIONSLIST="$${OPTIONSLIST} $$1"; \
-		defaultval=$$3; \
-		withvar=WITH_$$1; \
-		withoutvar=WITHOUT_$$1; \
-		withval=$$(eval ${ECHO_CMD} $$\{$${withvar}\}); \
-		withoutval=$$(eval ${ECHO_CMD} $$\{$${withoutvar}\}); \
-		if [ ! -z "$${withval}" ]; then \
-			val=on; \
-		elif [ ! -z "$${withoutval}" ]; then \
-			val=off; \
-		else \
-			val=$$3; \
-		fi; \
+		val=$$(eval ${ECHO_CMD} $$\{OPTION_VAL_$${1}\}); \
 		DEFOPTIONS="$${DEFOPTIONS} $$1 \"$$2\" $${val}"; \
 		shift 3; \
 	done; \
@@ -6176,21 +6244,11 @@
 .if defined(OPTIONS)
 .if exists(${OPTIONSFILE})
 # scan saved options and invalidate them, if the set of options does not match
-	@. ${OPTIONSFILE}; \
+	@${_OPTIONS_SET_SH} \
 	set ${OPTIONS} XXX; \
 	while [ $$# -gt 3 ]; do \
-		withvar=WITH_$$1; \
-		withoutvar=WITHOUT_$$1; \
-		withval=$$(eval ${ECHO_CMD} $$\{$${withvar}\}); \
-		withoutval=$$(eval ${ECHO_CMD} $$\{$${withoutvar}\}); \
-		if [ ! -z "$${withval}" ]; then \
-			val=on; \
-		elif [ ! -z "$${withoutval}" ]; then \
-			val=off; \
-		else \
-			val=missing; \
-		fi; \
-		if [ "$${val}" = "missing" ]; then \
+		src=$$(eval ${ECHO_CMD} $$\{OPTION_SRC_$${1}\}); \
+		if [ "$${src}" != "config" ]; then \
 			OPTIONS_INVALID=yes; \
 		fi; \
 		shift 3; \
@@ -6206,26 +6264,16 @@
 
 .if !target(showconfig)
 showconfig:
-.if defined(OPTIONS)
+.if !defined(OPTIONS)
+	@${ECHO_MSG} "===> No options to configure"
+.else
 	@${ECHO_MSG} "===> The following configuration options are available for ${PKGNAME}:"
-	- at if [ -e ${OPTIONSFILE} ]; then \
-		. ${OPTIONSFILE}; \
-	fi; \
+	@${_OPTIONS_SET_SH} \
 	set -- ${OPTIONS} XXX; \
 	while [ $$# -gt 3 ]; do \
-		defaultval=$$3; \
-		withvar=WITH_$$1; \
-		withoutvar=WITHOUT_$$1; \
-		withval=$$(eval ${ECHO_CMD} $$\{$${withvar}\}); \
-		withoutval=$$(eval ${ECHO_CMD} $$\{$${withoutvar}\}); \
-		if [ ! -z "$${withval}" ]; then \
-			val=on; \
-		elif [ ! -z "$${withoutval}" ]; then \
-			val=off; \
-		else \
-			val="$$3 (default)"; \
-		fi; \
-		${ECHO_MSG} "     $$1=$${val} \"$$2\""; \
+		val=$$(eval ${ECHO_CMD} $$\{OPTION_VAL_$${1}\}); \
+		src=$$(eval ${ECHO_CMD} $$\{OPTION_SRC_$${1}\}); \
+		${ECHO_MSG} "     $$1=$${val} ($${src}) \"$$2\""; \
 		shift 3; \
 	done
 	@${ECHO_MSG} "===> Use 'make config' to modify these settings"


More information about the freebsd-ports mailing list