Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify a makefile target in a different directory?

Tags:

makefile

I am trying to figure out why I can't specify a target as being in different directory.

I am trying to generate some php classes from json files, but I've changed the line that actually generates the php to a dummy echo statement, so somebody else can just copy paste and test if they feel very generous.

There are two other things to add to the directory containing the makefile:

  • A dummy dependency file called PatientDbPath.json
  • A directory called out

If I have a makefile with the following:

.SUFFIXES: .php .json
.json.php:
    echo "HelloMe" > PatientDbPath.php

PatientDbPath.php: PatientDbPath.json

clean:
    $(RM) PatientDbPath.php

Then everything works when I run make; PatientDbPath.php is correctly created and the next time I run make, I get the message make: 'PatientDbPath.php' is up to date.

However, I want to generate the php file in a separate directory, so I updated my makefile to the following:

.SUFFIXES: .php .json
.json.php:
    echo "HelloMe" > out/PatientDbPath.php

out/PatientDbPath.php: PatientDbPath.json

clean:
    $(RM) out/PatientDbPath.php

As soon as I do that, Make tells me make: Nothing to be done for 'out/PatientDbPath.php' even though there is no file PatientDbPath.php in the out directory.

So I thought maybe it was something with the suffix rules and I created a third makefile.

out/PatientDbPath.php: PatientDbPath.json
    echo "Whatever" > out/PatientDbPath.php

clean:
    rm out/PatientDbPath.php

This one works well, like the first one. Can anybody see what I'm doing wrong in my 2nd makefile?

Thanks.

like image 838
Juan Mendes Avatar asked Nov 09 '10 20:11

Juan Mendes


People also ask

Can makefile target be a directory?

Yes, a Makefile can have a directory as target. However, you shouldn't. When a file is added or removed from a directory, its mtime is updated. This can cause weird behaviour by causing multiple targets depending on a single directory to become implicitly rebuilt by one another.

What is $@ in makefile?

The file name of the target of the rule. If the target is an archive member, then ' $@ ' is the name of the archive file. In a pattern rule that has multiple targets (see Introduction to Pattern Rules), ' $@ ' is the name of whichever target caused the rule's recipe to be run.

What is a target and a rule in makefile?

A rule appears in the makefile and says when and how to remake certain files, called the rule's targets (most often only one per rule). It lists the other files that are the prerequisites of the target, and the recipe to use to create or update the target.


1 Answers

There's another way to do the same thing, perhaps more elegantly:

$(JSON_FILES): out/%.php: %.json
    action

This will create a rule for every file listed in JSON_FILES, so if it were defined JSON_FILES= foo.json bar.json, then this would be equivalent to:

out/foo.php: foo.json
    action

out/bar.php: bar.json
    action

You could then use $(wildcard *.json) to set that value if you really wanted all the .json files, or set it manually if the rule is unique to just a few.

like image 199
davenpcj Avatar answered Nov 15 '22 06:11

davenpcj