On Tue, Aug 08, 2023 at 12:51:43PM +0200, Marc Espie wrote:
> Here's a revised diff (reordered plus actual use of the boolean)
> plus concrete example  use for bsd.port.mk (disregarding the fact
> _ALL_VARIABLES would have to move *after* all MASTER_SITES have been defined.

I tested this on a small scale and it looks okay to me. ok thfr@ for
var.c part; see other email for the bsd.port.mk part.

> Index: var.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/make/var.c,v
> retrieving revision 1.104
> diff -u -p -r1.104 var.c
> --- var.c     9 Jun 2022 13:13:14 -0000       1.104
> +++ var.c     8 Aug 2023 10:48:05 -0000
> @@ -104,6 +104,8 @@ static char       varNoError[] = "";
>  bool         errorIsOkay;
>  static bool  checkEnvFirst;  /* true if environment should be searched for
>                                * variables before the global context */
> +                             /* do we need to recompute varname_list */
> +static bool  varname_list_changed = true;
>  
>  void
>  Var_setCheckEnvFirst(bool yes)
> @@ -222,6 +224,7 @@ typedef struct Var_ {
>  #define VAR_FROM_ENV 8       /* Special source: environment */
>  #define VAR_SEEN_ENV 16      /* No need to go look up environment again */
>  #define VAR_IS_SHELL 32      /* Magic behavior */
> +#define VAR_IS_NAMES 1024    /* Very expensive, only defined when needed */
>  /* XXX there are also some flag values which are part of the visible API
>   * and thus defined inside var.h, don't forget to look there if you want
>   * to define some new flags !
> @@ -231,6 +234,8 @@ typedef struct Var_ {
>       char name[1];           /* the variable's name */
>  }  Var;
>  
> +/* for GNU make compatibility */
> +#define VARNAME_LIST ".VARIABLES"
>  
>  static struct ohash_info var_info = {
>       offsetof(Var, name),
> @@ -245,10 +250,11 @@ static void fill_from_env(Var *);
>  static Var *create_var(const char *, const char *);
>  static void var_set_initial_value(Var *, const char *);
>  static void var_set_value(Var *, const char *);
> -#define var_get_value(v)     ((v)->flags & VAR_EXEC_LATER ? \
> -     var_exec_cmd(v) : \
> -     Buf_Retrieve(&((v)->val)))
> -static char *var_exec_cmd(Var *);
> +static char *var_get_value(Var *);
> +static void var_exec_cmd(Var *);
> +static void varname_list_retrieve(Var *);
> +
> +
>  static void var_append_value(Var *, const char *);
>  static void poison_check(Var *);
>  static void var_set_append(const char *, const char *, const char *, int, 
> bool);
> @@ -423,6 +429,7 @@ var_set_initial_value(Var *v, const char
>       len = strlen(val);
>       Buf_Init(&(v->val), len+1);
>       Buf_AddChars(&(v->val), len, val);
> +     varname_list_changed = true;
>  }
>  
>  /* Normal version of var_set_value(), to be called after variable is fully
> @@ -440,6 +447,16 @@ var_set_value(Var *v, const char *val)
>       }
>  }
>  
> +static char *
> +var_get_value(Var *v)
> +{
> +     if (v->flags & VAR_IS_NAMES)
> +             varname_list_retrieve(v);
> +     else if (v->flags & VAR_EXEC_LATER)
> +             var_exec_cmd(v);
> +     return Buf_Retrieve(&(v->val));
> +}
> +
>  /* Add to a variable, insert a separating space if the variable was already
>   * defined.
>   */
> @@ -628,6 +645,7 @@ Var_Deletei(const char *name, const char
>  
>       ohash_remove(&global_variables, slot);
>       delete_var(v);
> +     varname_list_changed = true;
>  }
>  
>  /* Set or add a global variable, either to VAR_CMD or VAR_GLOBAL.
> @@ -687,7 +705,7 @@ Var_Appendi_with_ctxt(const char *name, 
>       var_set_append(name, ename, val, ctxt, true);
>  }
>  
> -static char *
> +static void
>  var_exec_cmd(Var *v)
>  {
>       char *arg = Buf_Retrieve(&(v->val));
> @@ -699,7 +717,30 @@ var_exec_cmd(Var *v)
>       var_set_value(v, res1);
>       free(res1);
>       v->flags &= ~VAR_EXEC_LATER;
> -     return Buf_Retrieve(&(v->val));
> +}
> +
> +static void
> +varname_list_retrieve(Var *v)
> +{
> +     unsigned int i;
> +     void *e;
> +     bool first = true;
> +
> +     if (!varname_list_changed)
> +             return;
> +     for (e = ohash_first(&global_variables, &i); e != NULL;
> +         e = ohash_next(&global_variables, &i)) {
> +             Var *v2 = e;
> +             if (v2->flags & VAR_DUMMY)
> +                     continue;
> +
> +             if (first)
> +                     var_set_value(v, v2->name);
> +             else
> +                     var_append_value(v, v2->name);
> +             first = false;
> +     }
> +     varname_list_changed = false;
>  }
>  
>  /* XXX different semantics for Var_Valuei() and Var_Definedi():
> @@ -1339,6 +1380,19 @@ set_magic_shell_variable()
>       v->flags = VAR_IS_SHELL | VAR_SEEN_ENV;
>  }
>  
> +static void
> +set_magic_name_list_variable()
> +{
> +     const char *name = VARNAME_LIST;
> +     const char *ename = NULL;
> +     uint32_t k;
> +     Var *v;
> +
> +     k = ohash_interval(name, &ename);
> +     v = find_global_var_without_env(name, ename, k);
> +     var_set_initial_value(v, "");
> +     v->flags = VAR_IS_NAMES;
> +}
>  /*
>   * Var_Init
>   *   Initialize the module
> @@ -1348,11 +1402,10 @@ Var_Init(void)
>  {
>       ohash_init(&global_variables, 10, &var_info);
>       set_magic_shell_variable();
> -
> +     set_magic_name_list_variable();
>  
>       errorIsOkay = true;
>       Var_setCheckEnvFirst(false);
> -
>       VarModifiers_Init();
>       Buf_Init(&subst_buffer, MAKE_BSIZE);
>  }
> 
> 
> 
> bsd.port.mk POC:
> 
> Index: bsd.port.mk
> ===================================================================
> RCS file: /cvs/ports/infrastructure/mk/bsd.port.mk,v
> retrieving revision 1.1592
> diff -u -p -r1.1592 bsd.port.mk
> --- bsd.port.mk       13 Jun 2023 10:28:40 -0000      1.1592
> +++ bsd.port.mk       8 Aug 2023 10:49:14 -0000
> @@ -118,9 +118,8 @@ _ALL_VARIABLES_PER_ARCH =
>  # consumers of (dump-vars) include sqlports generation and dpb
>  # dpb doesn't need everything, those are speed optimizations
>  .if ${DPB:L:Mfetch} || ${DPB:L:Mall}
> -_ALL_VARIABLES += DISTFILES PATCHFILES SUPDISTFILES DIST_SUBDIR MASTER_SITES 
> \
> -     MASTER_SITES0 MASTER_SITES1 MASTER_SITES2 MASTER_SITES3 MASTER_SITES4 \
> -     MASTER_SITES5 MASTER_SITES6 MASTER_SITES7 MASTER_SITES8 MASTER_SITES9 \
> +_ALL_VARIABLES += DISTFILES PATCHFILES SUPDISTFILES DIST_SUBDIR \
> +     ${.VARIABLES:MMASTER_SITES*:NMASTER_SITES_*} \
>       CHECKSUM_FILE FETCH_MANUALLY MISSING_FILES PERMIT_DISTFILES
>  .endif
>  .if ${DPB:L:Mtest} || ${DPB:L:Mall}

Reply via email to