lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master f93cd2f 2/4: Improve documentation


From: Greg Chicares
Subject: [lmi-commits] [lmi] master f93cd2f 2/4: Improve documentation
Date: Fri, 24 May 2019 09:41:08 -0400 (EDT)

branch: master
commit f93cd2fe1fc7885ecf6986aca2a8f1341369e2bf
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>

    Improve documentation
---
 gwc/parent.make | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 50 insertions(+), 6 deletions(-)

diff --git a/gwc/parent.make b/gwc/parent.make
index e835b9a..9b47722 100644
--- a/gwc/parent.make
+++ b/gwc/parent.make
@@ -39,14 +39,58 @@ all:
 # single file. See this discussion:
 #   https://lists.nongnu.org/archive/html/lmi/2019-05/msg00052.html
 
+# How does this work?
+#
+# Only a few lines of code are required, and the subtlest one:
+#   $(eval include $(LMI_ENV_FILE))
+# isn't very difficult: it simply expands to an appropriate 'include'
+# directive at a particular time. The real challenge is understanding
+# the implicit synchronization. It is instructive to run test cases
+# with 'make --trace', whose output is paraphrased here:
+#
+# begin reading parent.make
+#   parent.make has $(LMI_ENV_FILE) as a prerequisite
+#     therefore, must remake $(LMI_ENV_FILE)
+#       source the script; in the same shell,
+#       write 'make' variable definitions to $(LMI_ENV_FILE)
+#     finished remaking $(LMI_ENV_FILE)
+#   finished prerequisites of parent.make
+# resume reading parent.make
+#   now $(LMI_ENV_FILE) is newer than parent.make
+#   therefore, must remake parent.make
+#     its recipe contains $(eval include $(LMI_ENV_FILE))
+#     which expands to a make directive
+#     which is executed when parent.make is reread
+#     which causes the definitions to take effect
+#   finished remaking parent.make
+# finished reading parent.make
+#
+# It is tempting to rearrange the code to make it simpler, but the
+# '--trace' output shows why that doesn't work--for example:
+#
+#  - Can the two recipes be combined into one, sourcing the script
+# and writing the temporary file just before $(eval)? No: $(eval)
+# would take effect before the script has been sourced. 'include'
+# is a make directive, not a shell command, so its effect occurs
+# when the makefile is reread--before the recipe is executed.
+#
+#  - Can $(eval include) be moved outside the recipe it occurs in,
+# and written outside any rule context (as directives typically are)?
+# No: it would take effect the first time the makefile is read, before
+# the script has been sourced, and it wouldn't be reconsidered later.
+# Functions are usually expanded when read, but not in rule contexts,
+# where expansion is deferred.
+
+# Prior art; alternatives
+#
 # Obviously one could simply write a cover script to replace direct
-# invocation of 'make', but that's nasty. See:
+# invocation of 'make', but the goal here is to avoid that. See:
 #   https://lists.gnu.org/archive/html/help-make/2006-04/msg00142.html
 # which suggests 'eval'.
 #
-# This is unhelpful:
-#   
https://stackoverflow.com/questions/7507810/how-to-source-a-script-in-a-makefile
-# except that it has a link to:
+# An online search for 'make "eval include"' finds few articles, and
+# fewer still that use that construct in a recipe. This one:
 #   https://blog.153.io/2016/04/18/source-a-shell-script-in-make/
-# which doesn't actually work in its final, simplified version;
-# but earlier in that article it uses 'eval include', which does work.
+# demonstrates the 'eval include' technique adapted here (though it
+# doesn't literally source a script). Its earlier 'eval include'
+# example works, though its final, simplified example seems not to.



reply via email to

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