tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

make: exporting MAKEOBJDIR



For several years, make has allowed for doing cool things
by putting something like this

MAKEOBJDIR="\${.CURDIR:S,${SRCTOP},${OBJPREFIX}\${MACHINE},}"

in the environment.  This allows for a more consistent/neat .OBJDIR value
than MAKEOBJDIRPREFIX allows when the src is mounted via amd etc.

The above relies on ${.CURDIR} and ${MACHINE} being left unresolved so
that cross-building for multiple machines works as expected.

Now, last year I introduced the ability to clear the env so that one
can do things like this (http://www.crufty.net/help/sjg/mk-files.htm)

.if ${.MAKE.LEVEL} == 0
# we save any env var that starts with these
MAKE_SAVE_ENV_PREFIX += SB MK MAKE NEED_ CCACHE SSH
env_vars != env | egrep '^(${MAKE_SAVE_ENV_PREFIX:ts|})' | sed 's,=.*,,'; echo
MAKE_SAVE_ENV_VARS += \
        PATH HOME USER \
        SRCTOP OBJTOP \
        ${env_vars}

_export_list = 
.for v in ${MAKE_SAVE_ENV_VARS:O:u}
.if !empty($v)
_export_list += $v
# this won't be good if value should not be expanded!
$v := ${$v}
.endif
.endfor
# now clobber the environment
.unexport-env
# export our selection
.export ${_export_list}
.endif

As the comment says, this will destroy our clever MAKEOBJDIR value.

The patch below allows providing a name=value pair to .export
so that the value exported need not match the one used internally.
Eg.

# the $$'s delay expansion
MAKEOBJDIR= $${.CURDIR:S,${SRCTOP},${OBJPREFIX}$${MACHINE},}
.export MAKEOBJDIR=${MAKEOBJDIR}
# now resolve it for ourselves
MAKEOBJDIR := ${MAKEOBJDIR}

this works because in Var_Export we treat the name=value case as an
exception and 
1/ tell Var_Export1 that we are not the "parent"
2/ not record the variable as having been exported, so it won't be
   re-exported when the value changes

Index: var.c
===================================================================
RCS file: /cvs/juniper/src/buildtools/bmake/var.c,v
retrieving revision 1.34
diff -u -p -r1.34 var.c
--- var.c       21 Apr 2010 04:54:39 -0000      1.34
+++ var.c       1 Jun 2010 18:39:00 -0000
@@ -548,11 +548,10 @@ Var_Delete(const char *name, GNode *ctxt
  * We only manipulate flags of vars if 'parent' is set.
  */
 static int
-Var_Export1(const char *name, int parent)
+Var_Export1(const char *name, char *val, int parent)
 {
     char tmp[BUFSIZ];
     Var *v;
-    char *val = NULL;
     int n;
 
     if (*name == '.')
@@ -580,7 +579,9 @@ Var_Export1(const char *name, int parent
        (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
        return 0;                       /* nothing to do */
     }
-    val = Buf_GetAll(&v->val, NULL);
+    if (!val) {
+       val = Buf_GetAll(&v->val, NULL);
+    }
     if (strchr(val, '$')) {
        if (parent) {
            /*
@@ -645,7 +646,7 @@ Var_ExportVars(void)
             var != NULL;
             var = Hash_EnumNext(&state)) {
            v = (Var *)Hash_GetValue(var);
-           Var_Export1(v->name, 0);
+           Var_Export1(v->name, NULL, 0);
        }
        return;
     }
@@ -662,7 +663,7 @@ Var_ExportVars(void)
        val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0);
        av = brk_string(val, &ac, FALSE, &as);
        for (i = 0; i < ac; i++) {
-           Var_Export1(av[i], 0);
+           Var_Export1(av[i], NULL, 0);
        }
        free(val);
        free(as);
@@ -680,6 +681,7 @@ Var_Export(char *str, int isExport)
 {
     char *name;
     char *val;
+    char *args;
     char **av;
     char *as;
     int ac;
@@ -690,8 +692,8 @@ Var_Export(char *str, int isExport)
        return;
     }
 
-    val = Var_Subst(NULL, str, VAR_GLOBAL, 0);
-    av = brk_string(val, &ac, FALSE, &as);
+    args = Var_Subst(NULL, str, VAR_GLOBAL, 0);
+    av = brk_string(args, &ac, FALSE, &as);
     for (i = 0; i < ac; i++) {
        name = av[i];
        if (!name[1]) {
@@ -709,15 +711,23 @@ Var_Export(char *str, int isExport)
                continue;
            }
        }
-       if (Var_Export1(name, VAR_EXPORT_PARENT)) {
+       if ((val = strchr(name, '='))) {
+           *val++ = '\0';
+       }
+       /*
+        * If we are passing an explicit value, we want
+        * Var_Export1 to behave as though we are the child
+        * and not perturb the state of the variable in our context.
+        */
+       if (Var_Export1(name, val, (val == NULL))) {
            if (VAR_EXPORTED_ALL != var_exportedVars)
                var_exportedVars = VAR_EXPORTED_YES;
-           if (isExport) {
+           if (isExport && !val) {
                Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
            }
        }
     }
-    free(val);
+    free(args);
     free(as);
     free(av);
 }
@@ -898,7 +908,7 @@ Var_Set(const char *name, const char *va
            fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
        }
        if ((v->flags & VAR_EXPORTED)) {
-           Var_Export1(name, VAR_EXPORT_PARENT);
+           Var_Export1(name, NULL, VAR_EXPORT_PARENT);
        }
     }
     /*


Home | Main Index | Thread Index | Old Index