From 7c140f671f8fdc120568edd539ac3d15dd8d1a43 Mon Sep 17 00:00:00 2001 From: David Poole Date: Fri, 14 Jul 2023 08:04:58 -0600 Subject: [PATCH] add MAKELEVEL built-in variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "As a special feature, the variable MAKELEVEL is changed when it is passed down from level to level. This variable’s value is a string which is the depth of the level as a decimal number. The value is ‘0’ for the top-level make; ‘1’ for a sub-make, ‘2’ for a sub-sub-make, and so on. The incrementation happens when make sets up the environment for a recipe. " GNU Make Manual https://www.gnu.org/software/make/manual/make.html --- pymake/pymake.py | 23 ++++++++++++++++------- tests/submake.mk | 11 +++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/pymake/pymake.py b/pymake/pymake.py index fed3ec1..1fd4f9b 100644 --- a/pymake/pymake.py +++ b/pymake/pymake.py @@ -277,7 +277,7 @@ def _execute_statement_list(stmt_list, curr_rules, rulesdb, symtable): # bottom of loop return exit_code -def execute_recipe(rule, recipe, symtable): +def execute_recipe(rule, recipe, symtable, dry_run=False): def remove_duplicates(s_list): # the $^ variable removes duplicates but must must must preserve order seen_list = [] @@ -333,6 +333,8 @@ def check_prefixes(s): return s, ignore_failure, silent + makelevel = int(symtable.fetch("MAKELEVEL")) + # TODO many more automatic variables symtable.push("@") symtable.push("^") @@ -373,6 +375,11 @@ def check_prefixes(s): s, ignore_failure, silent = check_prefixes(s) + if dry_run: + # TODO submakes + print(s) + continue + if not silent: print(s) @@ -391,7 +398,7 @@ def check_prefixes(s): args = pargs.parse_args(submake_argv[1:]) # breakpoint() currwd = os.getcwd() - exit_code = _run_it(args) + exit_code = _run_it(args, makelevel+1) os.chdir(currwd) # clean up the output from the submake helper ret.stdout = "" @@ -408,7 +415,7 @@ def check_prefixes(s): return exit_status["error"] if exit_code else exit_status["success"] -def execute(makefile, args): +def execute(makefile, args, makelevel): # ha ha type checking assert isinstance(args, pargs.Args) @@ -429,6 +436,8 @@ def execute(makefile, args): # The -C option will be handled before this function is called. symtable.add("CURDIR", os.getcwd()) + symtable.add("MAKELEVEL", str(makelevel)) + target_list = [] # GNU Make allows passing assignment statements on the command line. @@ -496,7 +505,7 @@ def execute(makefile, args): # walk a dependency tree for rule in rulesdb.walk_tree(target): for recipe in rule.recipe_list: - exit_code = execute_recipe(rule, recipe, symtable) + exit_code = execute_recipe(rule, recipe, symtable, args.dry_run) if exit_code != 0: break @@ -505,7 +514,7 @@ def execute(makefile, args): return exit_status["error"] if exit_code else exit_status["success"] -def _run_it(args): +def _run_it(args, makelevel): # -C option if args.directory: os.chdir(os.path.join(*args.directory)) @@ -534,7 +543,7 @@ def _run_it(args): print(makefile.makefile(), file=outfile) print("# end makefile %s" % args.output) - exit_code = execute(makefile, args) + exit_code = execute(makefile, args, makelevel) return exit_code # FIXME ugly hack dependency injection to solve problems with circular imports @@ -553,7 +562,7 @@ def main(): # usage() # sys.exit(1) - sys.exit(_run_it(args)) + sys.exit(_run_it(args,0)) if __name__=='__main__': main() diff --git a/tests/submake.mk b/tests/submake.mk index 7d4fb54..775f8da 100644 --- a/tests/submake.mk +++ b/tests/submake.mk @@ -2,20 +2,31 @@ $(info CURDIR=$(CURDIR)) +# check on MAKELEVEL value +$(if $(MAKELEVEL),,$(error MAKELEVEL is missing)) + all: @echo hello from make pid=$$$$ $(MAKE) -f $(CURDIR)/tests/submake.mk submake A=B B=C C=D + +# we should ignore this error and continue -$(MAKE) -f $(CURDIR)/tests/submake.mk submake-error # adding a shell expression to verify we go through the shell @$(MAKE) -f $(CURDIR)/tests/submake.mk hello-world NUM=$$((10+20)) a={1,2,3} + if [ -z '$(MAKELEVEL)' ] ; then echo missing MAKELEVEL && exit 1 ; fi + if [ ! $(MAKELEVEL) -eq 0 ] ; then echo MAKELEVEL should be zero && exit 1 ; fi + submake: @echo hello from submake pid=$$$$ + if [ ! $(MAKELEVEL) -eq 1 ] ; then echo MAKELEVEL should be value 1 && exit 1 ; fi hello-world: + if [ ! $(MAKELEVEL) -eq 1 ] ; then echo MAKELEVEL should be value 1 && exit 1 ; fi @echo hello, world NUM=$(NUM) a=$(a) submake-error: + if [ ! $(MAKELEVEL) -eq 1 ] ; then echo MAKELEVEL should be value 1 && exit 1 ; fi @echo error && exit 1