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

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
-       -...@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}:"
-       -...@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"
_______________________________________________
freebsd-ports@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ports
To unsubscribe, send any mail to "freebsd-ports-unsubscr...@freebsd.org"

Reply via email to