user213544
user213544

Reputation: 2126

Using a conditional directive in Makefile

I am struggling with a simple Makefile.

The simplified version looks something like this:

all : data/file1.RData

data/file1.RData : scripts/file1.R
  Rscript $<

I would like to execute the target of scripts/file1.R only when there is no file called data/file1.RData and I thought that the Syntax of Conditionals would be able to help me reach that goal.

From this post, I noticed constructions that looked something like:

target :
ifeq (...)
    ...
endif

But my lack of understanding of the syntax of Makefiles inhibits the translation to my use case. How do I perform this action?

Upvotes: 0

Views: 564

Answers (1)

MadScientist
MadScientist

Reputation: 101051

It's better to not use ifeq for this; that will run while the makefile is being parsed. You probably want to not make this check until you are ready to run the rule.

A simple way to do it is with the $(if ...) function. Something like this will work:

data/file1.RData : scripts/file1.R
        $(if $(wildcard $@),,Rscript $<)

I should point out that the RData file will always be considered (by make) to be out of date once scripts/file1.R is updated, since it never gets updated once it's created.

Documentation is available for the wildcard function:

The argument pattern is a file name pattern, typically containing wildcard characters (as in shell file name patterns). The result of wildcard is a space-separated list of the names of existing files that match the pattern.

(so, if the pattern, in this case just a simple filename, doesn't match an existing file the result is the empty string).

And the if function:

The first argument, condition, first has all preceding and trailing whitespace stripped, then is expanded. If it expands to any non-empty string, then the condition is considered to be true. If it expands to an empty string, the condition is considered to be false.

If the condition is true then the second argument, then-part, is evaluated and this is used as the result of the evaluation of the entire if function.

If the condition is false then the third argument, else-part, is evaluated and this is the result of the if function. If there is no third argument, the if function evaluates to nothing (the empty string).

Upvotes: 1

Related Questions