URL: <https://savannah.gnu.org/bugs/?63621>
Summary: Enhancement request - new built in variables Project: make Submitter: None Submitted: Wed 04 Jan 2023 03:56:14 PM UTC Severity: 3 - Normal Item Group: Enhancement Status: None Privacy: Public Assigned to: None Open/Closed: Open Discussion Lock: Any Component Version: None Operating System: None Fixed Release: None Triage Status: None _______________________________________________________ Follow-up Comments: ------------------------------------------------------- Date: Wed 04 Jan 2023 03:56:14 PM UTC By: Anonymous See discussion in https://stackoverflow.com/questions/74707248/using-call-in-a-makefile-recipe There are multiple use cases where it would be nice for a shell operation or the expansion of a string to be able to detect if it's within a makefile recipe or makefile body. Specific use case: I wanted to execute a shell command that returned a string that is later used (either echoed immediately or passed on to another program) I used a $(call...) to pass parameters from the parent Makefile, but found it did not work in recipes as it is executed at read-in time rather than shell invocation time. e.g. within the body it would be $(shell echo $(call fn,$(var))), which worked fine. But in the recipe it would be echo "some text" where "some text" is the premature expansion of echo $(call fn,$(var)). BTW $(info...) can't be used in the first example as the return is not always 7 bit ASCII. $(info) seems to fail with UTF. Suggested use cases: - Allow a different shell in $(shell...) and recipe without explicitly invoking it each time. - Allow a $(call...) to act differently in a recipe and when invoked in a $(shell), $(info) etc. - Allow the build environemtn host and the build job host to be different operating system or OS versions. Tried so far? I've done some tests and I can't find a set of enviroment conditions that can easily be used to detect if expanded within a recipe or not. (See https://gist.github.com/the-moog/62679586e9fba7448c8b07824565bb66) I can work round this by pre-calculating the resulting text before the recipe is called, then only returning the one that is meaningful, but that is all a bit hacky. I think there is a simple enhancement that would cover all of the above.... (Note: Examples for illustration only) My Suggestions: 1: Add a .RECIPE_SHELL variable that defaults to .SHELL unless override is used. simple example: .SHELL = /bin/bash override .RECIPE_SHELL := /bin/tcsh # Execute a bash statement res = $(shell $$((2+2))) # Execute a tcsh statement all: <TAB>setenv res $(RES); echo "res=$${res}" ---- 2: Add a .IN_RECIPE variable that evaluates to '1' if expanded within a recipe and '' otherwise. simple example: myprog := echo target := all deps := # The hello macro define hello = $(if $(.IN_RECIPE),$(myprog) "$1",$(shell $(myprog) "$1" >> /dev/stderr)) endef # Say hello $(call hello, world from make) # Do something with a previously unknown result $(target): $(deps) | $(call hello, Installing recipe for $(target)) <TAB>$(call hello, world from recipe) <TAB>if something; then \ <TAB> $(call hello, it did something);\ <TAB>else \ <TAB> $(call hello, something went wrong);\ <TAB>fi _______________________________________________________ Reply to this item at: <https://savannah.gnu.org/bugs/?63621> _______________________________________________ Message sent via Savannah https://savannah.gnu.org/