Consider the following:
%.foo: %.bar
echo $< > $@
Assuming we have one file 1.bar
, the command executed is simply echo 1.bar > 1.foo
. However, when %
contains a path, rather than just a file name, it start becoming finicky. My problem is that I want to prepend another path to %.bar
, the pattern becomes completely mangled. I.e., when %.bar
is nice/path/1.bar
, this becomes impossible:
%.foo: /project/something/%.bar
echo $< > $@
This will run, but it executes echo nice/path//project/something/1.bar > 1.foo
in stead of echo /project/something/nice/path1.bar > 1.foo
The reason for this is in how make does its pattern rules. From the docs:
When the target pattern does not contain a slash (and it usually does not), directory names in the file names are removed from the file name before it is compared with the target prefix and suffix. [...] The directories are ignored only for the purpose of finding an implicit rule to use, not in the application of that rule. Thus, ‘e%t’ matches the file name src/eat, with ‘src/a’ as the stem. When prerequisites are turned into file names, the directories from the stem are added at the front, while the rest of the stem is substituted for the ‘%’. The stem ‘src/a’ with a prerequisite pattern ‘c%r’ gives the file name src/car
Is there any way I can turn this off for a specific rule?
What is add prefix in makefile? $(addprefix prefix , names …) The argument names is regarded as a series of names, separated by whitespace; prefix is used as a unit. The value of prefix is prepended to the front of each individual name and the resulting larger names are concatenated with single spaces between them.
realpath() expands all symbolic links and resolves references to /./ , /../ and extra / characters in the input path and returns the canonicalized absolute pathname.
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.
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.
You may like to read up on How Patterns Match:
When the target pattern does not contain a slash (and it usually does not), directory names in the file names are removed from the file name before it is compared with the target prefix and suffix. After the comparison of the file name to the target pattern, the directory names, along with the slash that ends them, are added on to the prerequisite file names generated from the pattern rule’s prerequisite patterns and the file name. The directories are ignored only for the purpose of finding an implicit rule to use, not in the application of that rule. Thus, ‘e%t’ matches the file name src/eat, with ‘src/a’ as the stem. When prerequisites are turned into file names, the directories from the stem are added at the front, while the rest of the stem is substituted for the ‘%’. The stem ‘src/a’ with a prerequisite pattern ‘c%r’ gives the file name src/car.
The above explains why nice/path/
is prepended to prerequisite /project/something/1.bar
.
One fix would be to use full file names in rules, e.g.:
${CURDIR}/nice/path/%.foo: /project/something/%.bar
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With