Exporting environment variables to Makefile shell

2020-03-12 03:50发布

I want to do immediate expansion of a shell command within a Makefile, but I want the shell command to have access to the environment variables within the Makefile. If I use the $(shell ...), it expands immediately, but there is no access to the variables. If I use the backquotes, the expansion is not immediate, and it causes problems for me later in the Makefile. I'm wondering if there is any way to make the backquotes expand immediately, or to pass the current environment to a $(shell) command.

For example, the following makefile:

SOME_VAR := some_val
export SOME_VAR

VAR1 := `echo $$SOME_VAR`
export VAR1
VAR2 := `echo $$VAR1`

all:
      @echo VAR1=$(VAR1)
      @echo VAR2=$(VAR2)

Will output:

~/tmp/t2> make
VAR1=some_val
VAR2=`echo $SOME_VAR`

Where I want it to print "VAR2=some_val". The real example is a bit more complicated (environment variables are inherited from parent makefiles, and I'm trying to use a perl script to edit the variables), but the principle is the same.

Any help is appreciated.

5条回答
地球回转人心会变
2楼-- · 2020-03-12 04:09

Is this what you want?

VAR2 := $(shell VAR1="$(VAR1)" script_that_uses_var1)

查看更多
Anthone
3楼-- · 2020-03-12 04:09

What's wrong with this?

VAR1 := $(shell echo $(SOME_VAR))
VAR2 := $(shell echo $(VAR1))
查看更多
祖国的老花朵
4楼-- · 2020-03-12 04:13

You may try to use Special Built-in Target Name: .EXPORT_ALL_VARIABLES

.EXPORT_ALL_VARIABLES:

MY_VAR = foo

test:
  @echo $$MY_VAR
查看更多
ゆ 、 Hurt°
5楼-- · 2020-03-12 04:24

As I mentioned in some of the comments, my actual goal was to make the script generate filenames based on the settings the object was being compiled with. I then need another script to generate a specially formatted list of all the filenames generated (the target is an embedded system which doesn't have a JIT compiler on it). At any given time, there are over thirty settings which can potentially effect the binary, and this may be used on more than one module in the future, so I'd like something scalable.

My solution is as follows. Instead of passing the variables in, I modified my script to output a makefile-parsable string based on the settings:

-include $(SOME_MK_FILE)

$(SOME_MK_FILE) : .phony
    script.pl $(SETTINGS_OF_INTEREST_LIST) > $(SOME_MK_FILE)

someFilename := $(shell script2.pl $(VAR1))

script.pl outputs a string that looks something like:

VAR1 := CONFIG_X1=$(CONFIG_X1) CONFIG_X2=$(CONFIG_X2) CONFIG_X33=$(CONFIG_X33)

and script2 outputs a filename that looks something like 'someFilename.X1_y.X2_n.elf'

and then, later on, in another rule, I have:

someobj: somedep
    script3.pl $(someFilename) >> builtfiles.txt

which properly builds builtfiles.txt (which in turn is the input for yet another script...). In the end this is a workaround to the fact that make cannot pass its environement to $(shell). It's not overly pretty but it works.

John

查看更多
地球回转人心会变
6楼-- · 2020-03-12 04:25
登录 后发表回答