Reputation: 5851
I'm writing an R package that generates Makefile
s, I need to write a Makefile
that calls Rscript
before making the targets. A MWE of the problem is below. Make quits in error because the right-hand side of .INIT
does not execute. Writing a recipe for file.rds
does not suit my needs.
a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`
all: file2.rds
file2.rds: file.rds
cp file.rds file2.rds
clean:
rm file.rds file2.rds
What can I do to fix this Makefile
and keep it portable? From the R extensions manual, I can't use $(shell
for what I'm trying to accomplish.
EDIT
From @Spacedman's first answer, I learned that .INIT
is "expanded"/executed if and only if it is used as a variable somewhere. This is perfect! @Spacedman, I invite you to copy the following Makefile
into an answer of your own so I can give you credit.
a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`
all: file2.rds
file2.rds:
echo "file.rds should not have been built."
file3.rds:
echo -n $(.INIT)
cp file.rds file3.rds
clean:
rm file.rds file2.rds
The following demonstrates the results I had hoped for.
$ make file2.rds
echo "file.rds should not have been built."
file.rds should not have been built.
$ ls file.rds
ls: cannot access file.rds: No such file or directory
$ make file3.rds
echo -n `Rscript -e 'saveRDS('1', "file.rds")'`
cp file.rds file3.rds
$ ls file.rds
file.rds
Upvotes: 0
Views: 300
Reputation: 94307
I think you need to use :=
and $(shell ...)
thus:
.INIT := $(shell Rscript -e 'saveRDS('$(a)', "file.rds")')
This makes a simply expanded variable
rather than a recursively expanded variable
. I think Make doesn't bother even looking at your definition for .INIT
because its never used.
Backticks don't work like this in Make, you have to use $(shell ...)
. Can you really not use $(shell ...)
anywhere?
https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_6.html
Test:
$ rm file.rds file2.rds
$ make
cp file.rds file2.rds
$ ls file*rds
file2.rds file.rds
Which seems to show make
has created file.rds
via the R script.
If you can put the backquoted string in a recipe, you can make it work (as you discovered!). Note I don't think you need to echo the string, you can just get it expanded and this seems to work:
a=1
.INIT=`Rscript -e 'saveRDS('$(a)', "file.rds")'`
all: file2.rds
file2.rds:
echo "file.rds should not have been built."
file3.rds:
$(.INIT)
cp file.rds file3.rds
Upvotes: 1