ninja: Relative subninja paths don't resolve

I would attempt a PR for this, but I’m not entirely sure this is a bug or if it’s intended.

When including a subninja, I get

ninja: error: ‘mod.c’, needed by ‘mod.o’, missing and no known rule to make it

although running ninja directly in that directory works just fine. Under the suspicion that relative paths may be to blame, I copied the project structure to a new directory, prepended each input/output with the absolute path, and ran ninja from the parent directory (containing the build.ninja that subninja’d the module). It built just fine.

Is this suggesting we should be generating our ninja configurations with absolute paths? This has a lot of problems, along with the fact not every generator I’ve seen does this. Further, the documentation doesn’t make a distinction, and Ninja runs just fine otherwise.

I want to err on the side of it’s a bug, but I feel like a PR that does runtime path canonicalization might introduce a performance hit (though I’m waving my hands here without any benchmarks to back up that suspicion).

About this issue

  • Original URL
  • State: open
  • Created 9 years ago
  • Reactions: 6
  • Comments: 17

Commits related to this issue

Most upvoted comments

How about:

subninja path/to/build.ninja relative path/to

and an absent relative defaults to ./. That would make it non-breaking but still give the functionality if a generator so desires.

Or, following in the steps of other Ninja constructs, maybe

subninja path/to/build.ninja
  relative = path/to

I’m not sure I understand. Subninjas, in the use-case I’ve described in particular, don’t normally know about the parent ninja’s structure (at least, don’t need to know). I’m sure someone out there could find a case where they do, though.

The problem I’m facing right now is dependencies (third party libraries, etc.) that don’t use my generator (which is 100% of them) currently need to be built using a bootstrapper, and have to be bootstrapped every time they’re updated or changed, etc. Most generators I work with have the options to output to a ninja configuration, but they’re all configured for that directory alone (i.e. relative to that directory).

Being able to perform selective rebuilds using their configurations and graphs would be huge. Currently, I cannot do this due to the fact subninja assumes paths relative to the build directory.

That makes no sense, though. That means generators are going to have to all implement some way to prepend a prefix to the files, which means changing the working directory commands run in (which may change the original intent of the build configuration depending on how the generator/commands run).

What, then, are contrasting use cases for subninja vs include?

A subninja with paths relative to the build file would be useful in that depdencies that are configured to run within their own directory can do so without having to modify their paths, but can still contribute to the dependency graph of the parent ninja configuration.

include functionality would be unmodified, and would act exactly how subninjas act other than the fact rule names would now be in a combined namespace (as per #921). Currently, subninja and include achieve essentially the same thing other than scoping variables and rule names…