8

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?

Gx1sptDTDa
  • 1,558
  • 2
  • 11
  • 23
  • 2
    Are you just trying to use the bare filename in the recipe? If so just use `$(notdir $<)` or `$( – Etan Reisner Apr 22 '15 at 14:00
  • Your question doesn't make the situation clear. If you were to write this rule as an explicit rule, what would it look like? What is the expanded target path you want, and what is the expanded prerequisite path you want? – MadScientist Apr 22 '15 at 14:38
  • The expanded prerequisite path should be `/project/something/nice/path1.bar`. It makes `nice/path//project/something/1.bar`. That is, it splits `%` in a prefix (`nice/path`) and a stem (`1.bar`), then prepends `/project/something/` to the stem, and THEN prepends the prefix to that. I want it to stop splitting `%` in a prefix and stem. – Gx1sptDTDa Apr 22 '15 at 15:14
  • You didn't answer my question. What is the full pathname of the _target_ you are trying to build? Is it just `1.foo` with no path? Is it `nice/path/1.foo`? I don't understand where the `nice/path` came from. Make starts with the target and from that determines the stem and from that determines the prerequisites. So if your target is `1.foo` as you say, then how can the stem of the prerequisite be `nice/path/1`? – MadScientist Apr 22 '15 at 15:27
  • Maybe if you provided a short, _complete_ example that actually shows the problem in action it would be simpler to see what's going on. – MadScientist Apr 22 '15 at 15:28

1 Answers1

1

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    
Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
  • 2
    I know *why* it does so (hence why I'm quoting the exact same docs in the question), but how can I turn it off? The reason is that in the actual use case I have to use this, is that my paths are dependent on file names (it's a somewhat complex folder structure). – Gx1sptDTDa Apr 22 '15 at 15:18
  • @Gx1sptDTDa Oops, missed your quote. Why can't you use full file names? – Maxim Egorushkin Apr 22 '15 at 15:20