Makefile variable initialization and export

后端 未结 4 1778
野趣味
野趣味 2021-02-02 08:00
somevar := apple
export somevar
update := $(shell echo \"v=$$somevar\")

all:
    @echo $(update)

I was hoping to apple as output of command, however i

4条回答
  •  被撕碎了的回忆
    2021-02-02 08:48

    Although export does not play nicely with $(shell ...), there is a simple workaround. We can pass the data to the shell script via the command line.

    Now of course, environment passage is robust against issues of escaping and quoting. However, the shell language has a single quote quoting method '...' which handles everything. The only problem is that there is no way to get a single quote in there; but of course that is solved by terminating the quote, backslash-escaping the needed single quote and starting a new quote: In other words:

    ab'cd -> 'ab'\''cd'
    

    In the shell script executed by $(shell ...) we just generate a variable assignment of the form var='$(...)', where $(...) is some make expression that interpolates suitably escaped material. Thus, Makefile:

    somevar := apple with 'quoted' "stuff" and dollar $$signs
    
    shell_escape = $(subst ','\'',$(1))
    
    update := $(shell v='$(call shell_escape,$(somevar))'; echo $$v > file.txt)
    
    .phony: all
    
    all:
        cat file.txt
    

    Sample run:

    $ make
    cat file.txt
    apple with 'quoted' "stuff" and dollar $signs
    

    If we want to communicate an environment variable to a command, we can do that using the shell syntax VAR0=val0 VAR1=val1 ... VARn=valn command arg .... This can be illustrated by some minor alterations to the above Makefile:

    somevar := apple with 'quoted' "stuff" and dollar $$signs
    
    shell_escape = $(subst ','\'',$(1))
    
    update := $(shell somevar='$(call shell_escape,$(somevar))' env > file.txt)
    
    .phony: all
    
    all:
            grep somevar file.txt
    

    Run:

    $ make
    grep somevar file.txt
    somevar=apple with 'quoted' "stuff" and dollar $signs
    

    file.txt contains a dump of environment variables, where we can see somevar. If export in GNU Make did the right thing, we would have been able to just do:

    export somevar
    update := $(shell env > file.txt)
    

    but the end result is the same.

    Since the end result you want is to echo $(update), you would shell_escape anyway, even if GNU Make passed exported vars to $(shell ...). That is to say, look at one more Makefile:

    somevar := apple with 'quoted' "stuff" and dollar $$signs
    
    shell_escape = $(subst ','\'',$(1))
    
    update := $(shell v='$(call shell_escape,$(somevar))'; echo $$v)
    
    .phony: all
    
    all:
        @echo '$(call shell_escape,$(update))'
        @echo $(update)
    

    Output:

    apple with 'quoted' "stuff" and dollar $signs
    apple with quoted stuff and dollar
    

提交回复
热议问题