views:

230

answers:

2

I need the xpi_hash variable to be assigned only when update target's command is decided to execute. Then I'm using this variable as environment, exporting, etc..

If I put it outside of rule, it will be expanded firstly, before $(xpi) target is called, hence will not find that file.

substitute := perl -p -e 's/@([^@]+)@/$$ENV{$$1} bla bla...

export xpi_hash

.PHONY: dirs substitute update

update: $(xpi) $(target_update_rdf) 
    xpi_hash   := $(shell sha1sum $(xpi) | grep -Eow '^[^ ]+')
    @echo "Updating..."

$(target_update_rdf): $(update_rdf)
    $(substitute) $< > $@

and above of course is not correct, because for command part the shell is represented. So maybe another way to put this question is - how to bring variable as command output?

+1  A: 

I'm not sure exactly what you're looking for here, how are you planning to use xpi_hash? If you want to get the current hash every time you use the variable use = to assign the variable instead of :=, e.g.

xpi_hash=$(shell sha1sum $(xpi) | grep -Eow '^[^ ]+')
update:$(xpi) $(target_update_rdf)
    @echo $(xpi_hash)

will print the hash of xpi after it has been updated.

For variables in make, see section 6.2 of the manual. Briefly ':=' will expand variables on the right hand side, '=' will leave them to be expanded later.

The altered command in my comment (substitute = xpi_hash="$(xpi_hash)" perl -p -e 's/@([^@]+)@/$$ENV{$$1}...') will expand to be equivalent to

$(substitute)
xpi_hash="$(xpi_hash)" perl -p -e 's/@([^@]+)@/$$ENV{$$1}...'
xpi_hash="`sha1sum $(xpi) | grep -Eow '^[^ ]+'`" perl -p -e 's/@([^@]+)@/$$ENV{$$1}...'
xpi_hash="`sha1sum xpi_expansion | grep -Eow '^[^ ]+'`" perl -p -e 's/@([^@]+)@/$$ENV{$$1}...'

The xpi_hash="..." syntax is defining a variable in the bash subshell, rather than using the variable in make.

Scott Wales
@Scott: I'm exporting `xpi_hash` to use it later in perl command. I tried `=`, it made difference, but still called before `$(xpi)` target, so `sha1sum` can never locate the xpi file... Hope it's clear now.
Michael
Try changing the `substitute` definition to `substitute = xpi_hash="$(xpi_hash)" perl -p -e 's/@([^@]+)@/$$ENV{$$1} bla bla...'`, which is explicitly adding xpi_hash to the environment for the perl command.
Scott Wales
@Scott: could you please give me some reference chapters in gnu make about `=` and the alternative mechanism of exporting variables to environment?
Michael
@Michael Sure, done. The `xpi_hash="..."` bit is actually bash syntax.
Scott Wales
A: 

If only substitute must use xpi_hash, make xpi_hash a target-specific variable:

$(target_update_rdf): xpi_hash = $(shell ...)
$(target_update_rdf): $(update_rdf)
    $(substitute) $< > $@

If other Perl scripts will need xpi_hash, and you want to export it, you have a problem, because the variables assigned in the subshells of a rule cannot (easily) be communicated to Make. But you can store it in a file and include it:

xpi_hash_file: $(xpi)
    rm -f $@
    echo xpi_hash = $(shell...) > $@

-include xpi_hash_file
Beta