Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Requst/Documentation Request: use build.ninja stub to bootstrap ninja #2562

Open
titaniumtraveler opened this issue Jan 28, 2025 · 3 comments · May be fixed by #2563
Open

Feature Requst/Documentation Request: use build.ninja stub to bootstrap ninja #2562

titaniumtraveler opened this issue Jan 28, 2025 · 3 comments · May be fixed by #2563

Comments

@titaniumtraveler
Copy link

When reading about how ninja, one of my first thoughts was that why not use ninja itself bootstrap the build.ninja file?

I tried googling this topic, but haven't really found anything, other than some closed issues concerning problems when regenerating build.ninja, but nothing directly about using a build.ninja-stub to bootstrap the project.

Looking at the build.ninja of this project, it at least contains a passage to regenerate its contents when ./configure is changed:

# Regenerate build files if build script changes.
rule configure
  command = ${configure_env}python3 $root/configure.py $configure_args
  generator = 1
build build.ninja: configure | $root/configure.py $root/misc/ninja_syntax.py

So my questions are:

Why not have that part in an otherwise empty build.ninja, so that the user can just run ninja the first time and the project bootstraps itself?

Does the build.ninja get reloaded by the running ninja process when it changes?
As in would running ninja manual succeed in generating doc/manual.html?

If the answer to these questions is "yes" it would be nice for those details to be part of the manual and maybe documented as potential pattern to use to bootstrap projects.

Though arguably writing to a source-controlled file might be a bad idea, instead one could write to an build.ninja file contained in the build directory and include that? (Does changing those cause ninja re-source them? And would ninja run when the file path doesn't exist currently, but is defined as a build target?)

If the answer is "no", it would be good to document that as gotcha and might be a potentially neat feature to consider in the future.

I would of cause be open to discuss this topic either here, or on the mailing list.

@digit-google
Copy link
Contributor

digit-google commented Jan 28, 2025 via email

@titaniumtraveler
Copy link
Author

I don't understand what you are proposing. If you care about the
convenience of just invoking ninja manual directly, then the
build.ninja must be in the build directory which is the top-level source
directory.

I'm having difficulties to express my proposal in details, but my main idea is basically that a typical contributor shouldn't have to think about the build system when they get started with a project.

So my ideal workflow would be, if they see that the project is build with ninja,
they don't need to care about how generator is invoked, but can just run ninja with some target.

And if we can prove that works for ninja itself, the pattern might get adopted for other projects that use ninja as well.

As context I'm relatively new to C/C++ and with many projects I feel like before being able to even build a project, you have to carefully study the build instruction to make sure you don't do anything wrong, which is a big barrier of entry for C in general in my opinion.
(My first attempt at learning C failed at figuring out cmake for example)

I know a lot of this complexity is somewhat inherent to C, but I feel a lot of them can also be solved with some good defaults.

If the answer to these questions is "yes" it would be nice for those
details to be part of the manual and maybe documented as potential pattern
to use to bootstrap projects.

Yes, feel free to upload a PR for review.

I will. I think I will start with a basic Proof of Concept and see from there.

@titaniumtraveler
Copy link
Author

So, I have written a basic POC of how self-bootstrapping ninja file could look like. (See #2563)

It can be tested with

rm -rf build && mkdir build # make sure build directory is empty
touch configure.py          # force the `configure` rule to be run to generate ninja file
touch build/build.ninja     # make sure include target exists so that ninja doesn't error out
ninja <some-target>

The only thing missing to make it actually work is some way conditionally execute includes. (Without the script above that is)

I think the best to achieve that is to allow for include (and subninjas too for that matter) to be able to receive build targets.

So that when ninja encounters an include, it will check, whether the file is in the list of build targets and when necessary build/rebuild that target.

(There might be other solutions to this problem, but this feels most natural)

I think that considering changes of includes, or subninjas when deciding whether to rebuild the manifest would be an good idea anyways, since it feels consistent with ninjas behavior when changing build.ninja itself during build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants