[Top][All Lists]

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

Re: [lmi] [lmi-commits] master 210257a 7/9: Source a script in a makefil

From: Vadim Zeitlin
Subject: Re: [lmi] [lmi-commits] master 210257a 7/9: Source a script in a makefile
Date: Wed, 22 May 2019 18:50:45 +0200

On Wed, 22 May 2019 15:53:10 +0000 Greg Chicares <address@hidden> wrote:

GC> Let me begin with a patch that I think represents what you would recommend:
GC> diff --git a/gwc/parent.make b/gwc/parent.make
GC> index 81fd3eb3..37780e94 100644
GC> --- a/gwc/parent.make
GC> +++ b/gwc/parent.make
GC> @@ -22,8 +22,12 @@ parent.make:: $(LMI_ENV_FILE)
GC>     rm $(LMI_ENV_FILE)
GC> -   @echo "Sourcing 'set.sh'"; \
GC> -   . ./set.sh ; \
GC> +   @echo "Sourcing 'set.sh'"
GC> +   @. ./set.sh ; \
GC> +     { \
GC> +       echo "export LMI_OUT1 := $$LMI_OUT1"; \
GC> +       echo "export LMI_OUT2 := $$LMI_OUT2"; \
GC> +     } > $@ ; \
GC>     echo "'$$LMI_IN' --> '$$LMI_OUT1', '$$LMI_OUT2' : sourced in 
GC>  all:
GC> diff --git a/gwc/set.sh b/gwc/set.sh
GC> index 0660dc91..4367d492 100755
GC> --- a/gwc/set.sh
GC> +++ b/gwc/set.sh
GC> @@ -16,12 +16,6 @@ case "$LMI_IN" in
GC>  esac
GC>  echo "'$LMI_IN' --> '$LMI_OUT1', '$LMI_OUT2' : leaving 'set.sh'"
GC> -if [ -n "$LMI_ENV_FILE" ]; then
GC> -    {
GC> -    echo "export LMI_OUT1 := $LMI_OUT1"
GC> -    echo "export LMI_OUT2 := $LMI_OUT2"
GC> -    } > "$LMI_ENV_FILE"
GC> -fi
GC>  }
GC>  foo

 Sorry, I don't think this corresponds to what I'd like to do. I'd rather
like to replace all occurrences of

        export LMI_VAR=whatever

in set.sh with

        echo "export LMI_VAR=$LMI_VAR"

(of course, in this simple case just "echo export LMI_VAR=whatever" would
work just as well, but the above also works if LMI_VAR is assigned
conditionally as is the case for LMI_OUT2) and then just do

        ./set.sh > $@

instead of ". ./set.sh" in parent.make.

 I.e. there is no "source" (a.k.a. ".") in play any more, the helper script
just outputs the statements assigning the values to the variables and the
caller evals them. This has the advantage of being simpler at both make and
shell levels and not requiring any coordination between the two. The only
disadvantage I see right now is that we have to use "=" and not ":=" if we
want the script to work in both shell and make, but I don't think it's such
a huge drawback as all the variables we're going to use this mechanism for
will be simple strings anyhow. And if it's really a problem, we could add a
call to sed replacing the first "=" with ":=" inside $(shell).

 As mentioned before, if you think it would still be useful to have a
source-able file for interactive use, it can be trivially achieved by
renaming set.sh to echo.sh and then having a one-line set.sh doing just
"eval $(./echo.sh)".

 To make this even more concrete, here is a simple patch which seems to
work for me:
---------------------------------- >8 --------------------------------------
diff --git a/gwc/parent.make b/gwc/parent.make
index 81fd3eb37..d6a8ca50b 100644
--- a/gwc/parent.make
+++ b/gwc/parent.make
@@ -23,7 +23,7 @@ parent.make:: $(LMI_ENV_FILE)

        @echo "Sourcing 'set.sh'"; \
-       . ./set.sh ; \
+       ./set.sh > $@ ; \
        echo "'$$LMI_IN' --> '$$LMI_OUT1', '$$LMI_OUT2' : sourced in 

diff --git a/gwc/set.sh b/gwc/set.sh
index 0660dc91f..b5282f761 100755
--- a/gwc/set.sh
+++ b/gwc/set.sh
@@ -1,13 +1,4 @@
-#!/bin/sh this-script-must-be-sourced-not-run
-# $LMI_ENV_FILE is defined by the makefile that sources this script.
-# shellcheck disable=SC2154
-echo "LMI_ENV_FILE in 'set.sh': $LMI_ENV_FILE"
-echo "'$LMI_IN' --> '$LMI_OUT1', '$LMI_OUT2' : entering 'set.sh'"
-export LMI_OUT1="$LMI_IN"
-export LMI_OUT2="$LANG"

 case "$LMI_IN" in
     (Mongolia) LMI_OUT2="mn_MN" ;;
@@ -15,15 +6,5 @@ case "$LMI_IN" in
     (*) ;;

-echo "'$LMI_IN' --> '$LMI_OUT1', '$LMI_OUT2' : leaving 'set.sh'"
-if [ -n "$LMI_ENV_FILE" ]; then
-    {
-    echo "export LMI_OUT1 := $LMI_OUT1"
-    echo "export LMI_OUT2 := $LMI_OUT2"
-    } > "$LMI_ENV_FILE"
-unset -f foo
+echo export LMI_OUT1="$LMI_IN"
+echo export LMI_OUT2="$LMI_OUT2"
---------------------------------- >8 --------------------------------------

 Note that initially I thought we could also avoid using a temporary file
completely and just do "$(eval $(shell ./set.sh))" but this, unfortunately,
doesn't work because GNU make $(shell) function replaces new lines with
spaces, which breaks everything as soon as there is more than one variable
and there doesn't seem to be any way to prevent this from happening

GC> I think your objection is mainly to commit 315d415d, discussed below.

 It's difficult to pick a single commit to object to, as it's just a
different approach, but this one is indeed as good a choice as any other

GC> But maybe we shouldn't like 315d415d. Its commit message says:
GC> | The list of environment variables may change over time. Maintenance is
GC> | easier if this list appears in one file rather than two.
GC> |
GC> | It is also nicer to write shell code in scripts than in makefiles where
GC> | dollar signs must be doubled.
GC> and it did essentially this, simplified for this discussion:
GC> [makefile]
GC>   $(eval include env.make) # in recipe to remake top-level makefile
GC> - . ./set.sh ; \
GC> -   echo "export LMI_OUT1 := $$LMI_OUT1" > $(TEMPORARY_FILE)
GC> + . ./set.sh
GC> [script]
GC> + echo "export LMI_OUT1 := $LMI_OUT1" > $TEMPORARY_FILE
GC> so the question is: where should the 'make' assignments be written?
GC> In one place only, because one is better than two, ceteris paribus?

 Of course it should be done in one place only, I don't argue at all
against this.

GC> I think you're saying that, despite the advantages claimed for
GC> maintaining the list of variables in one place only, it seems
GC> better to make the sourceable script do one and only one thing,
GC> and have the makefile do whatever's necessary to use the shell
GC> environment variables set by the script.
GC> Is that what you're saying?

 No, sorry. I think the confusion stems from the fact that I assumed that
it was widely known how the tools such as gpg-agent worked and just
referenced it as "xxx-agent way" without going into the details. I hope
that now that I tried to explain this in more details, it is more clear,
but please let me know if this still isn't the case.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]