-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Added support for environment variable NINJA_FLAGS #1399
Conversation
Not sure why the CI build is failing. Can somebody help me out? |
Previously #797. |
int argc = 0, i = 0; | ||
bool in_arg = false; | ||
|
||
argv[argc++] = (char *)""; // fake argv[0] (command) for getopt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
travis is failing because
src/ninja.cc:1141:16: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
argv[argc++] = ""; // fake argv[0] (command) for getopt
^
(click the red x to get to that: https://travis-ci.org/ninja-build/ninja/builds/354768286?utm_source=github_status&utm_medium=notification)
I'm generally wary of making env vars affect your build. If you have the power to set env vars for everyone, you also have the power to run |
"alias" is not an option on Windows, nor does it work when Ninja is called from another tool, for instance cmake. In those cases, how can you enforce custom default settings for -j and -l ? Would it be acceptable to have dedicated environment variables like NINJA_MAX_JOBS and NINJA_MAX_LOAD? That would affect only build performance and not the build output. Another option would be a configuration file, but it would have a bigger impact on the design. |
I'm somewhat skeptical of that too :-/ I've debugged so many build issues where in the end the resolution was "oh I had this one env var set that I set months ago and forgot about". |
Like I said, the two specific environment settings can not impact the build result, so the risk of "build issues" is limited to the performance, which is very easy to troubleshoot with the documentation or FAQ. Other build tools have something similar, for instance make has MAKEFLAGS, gradle has ~/.gradle/settings.gradle (for instance to enable/disable the daemon), Maven has ~/.m2/settings.xml, cmake has environment variables. All these tools live pretty well with the risk you mentioned, because it's more than compensated by the added value. I am obviously not the only one who needs that, there are several valid and common use cases, so what is the alternative to give to the user the possibility to set more sensible default values? |
I agree the risk is limited to performance, but that seems like a pretty big risk in a project whose purpose is performance. The alternative depends on your exact use case. For the one mentioned in comment 0, on linux I'd probably set the default nice level in limits.conf for each user since it sounds like you don't want this just for ninja builds. For just ninja at an admin level, I'd set the alias. For personal use, I'd manually use the flags. I'm less familiar with Windows, but similar things are probably possible there (if ninja is system-provided, put |
Using an alias or a BAT script has the same issues, with additional problems and limitations mentioned. So for the users who really needs this, it's better to provide a clean way. |
Hi @nico. If the main concern is the troubleshooting, how about displaying a message on the console when the environment variables are used? Something like:
Or if we want to limit this to the performance options:
People not using this feature would not be impacted. |
I mean, it is extremely common to install software to /usr/local then forget about it. will you also disable installation to /usr/local? |
I build software from the AUR (Arch User Repository) using ninja. I am searching for a solution to always use |
Instead of an #!/usr/bin/env python3
import sys
import subprocess
try:
subprocess.check_call(['/usr/bin/ninja', '-j1'] + sys.argv[1:])
except subprocess.CalledProcessError as e:
exit(e.returncode) Name it Not sure if this will work on Windows, too? @ocroquette Can you name some limitations with this script approach? It should work with CMake for example. |
This comment was marked as abuse.
This comment was marked as abuse.
It takes 50 ms on my system. Is that really noticeable in your builds? If I understand it correctly the use-case for this seems to be full rebuilds anyway. |
Thanks for the idea, but I can only repeat my comment above:
It looks like the design decision here is not to support any user settings. While I can understand the concern anything that could modify the build result, it doesn't apply for the parallelism factor. It just forces the user to resort to cumbersome solutions which doesn't need to be. |
Correct me if I'm wrong here, but I only see three issues mentioned here:
Python should work on Windows.
If it's on the PATH, it should work with CMake.
The Python script can remove those from So no, it does not have the same issues as an |
Python doesn't solve anything. If I wanted to solve this with an additional script, I would use a language supported natively by the platform anyway (for instance CMD on Windows and SH on Unix-likes), so that I don't have to deploy Python on every developer PC and build server of the company just to pass an integer to Ninja. Relying on a wrapper script is in general not a good option, our whole build system is complex enough by nature that we don't need a hack that relies on external files and the order of directories in PATH. The issues I was referring to are the one mentioned by nico, the main one being that it is possible to forget about the custom settings values. Refusing to do this in Ninja just moves the problem elsewhere. |
Of course that's also possible, I've just used Python, because I know it better.
It's only one external file.
Because you don't like reliance on env variables? That's exactly the reason why we are against
Yes, but I think this way it's a bit more explicit. Also moving it out of Ninja is exactly the point for a feature that won't be used by most of Ninja's users. |
A working solution then is to create a directory That would not prevent Am I missing anything? |
@jonesmz I agree with you that filtering NINJA_FLAGS would be inconvenient (and counterintuitive too). If it gets implemented, it should come with full power. But I'm really concerned with a particular and IMO concretely possible instance of your third case, i.e. a sysadmin with arcane intentions, or some idiot build tool, setting NINJA_FLAGS to a perverse default, which an unknowing user will then be forced to debug. And in my debugging experience a lot of time will often be wasted before one remembers to check for things that are completely out of context. So, this is not an instance of not knowing what you are doing, actually your very knowledge becomes an hindrance. Also the problem is more about collaboration than about single users. On the other hand it's true that solving such kind of problems is not in any way ninja's responsibility, yet I strongly believe that some protection, like a warning, should be included, as @ocroquette himself suggested. Which is not convenient either, but still better than nothing. E.g.:
(with all overloaded flags omitted). However this should come in a form that avoids hurting build log parsers. |
This comment was marked as abuse.
This comment was marked as abuse.
I'm not the only one and didn't even close this PR. Also I can't make final decisions about Ninja. |
This comment was marked as abuse.
This comment was marked as abuse.
I tried to catch the attention of other maintainers, with no luck so far. How do you suggest we should proceed then? Independently of the decision, your opinion as a maintainer matters, so it would definitely help to hear it. Do you personally think that the NINJA_FLAGS (restricted or not) is an acceptable way to solve our problem, since we didn't find any other good option in the lengthy discussion? Just for the record, I am thankful for the free time you spend on Ninja, including on this topic. But keep in mind you are not the only one. I have already spent several hours here, time that I cannot expect my employer to account for. I am surely not the only user in this case. |
Fastest way would be getting it merged in a fork, e.g. https://github.com/jonesmz/splinter
I would rather stay out of it for a while, sorry. |
It's great that @jonesmz shares his work, but forking just to have -j as a persistent setting isn't worth it, from my perspective.
I didn't think of that, thanks for the hint. I will do so. |
This was discussed on the mailing-list, and unfortunately no maintainer thinks our problem deserves a solution. https://groups.google.com/forum/#!topic/ninja-build/E3s9gE7RiLQ |
No meson and no ninja is the solution for me in the end. Thanks to everybody involved for trying to convince the maintainers the feature was worth it. |
This comment was marked as abuse.
This comment was marked as abuse.
We made our point and actually got responses from the 2 active maintainers, both negative.
I agree. But unfortunately, it is very easy for anyone (including maintainers) to be against any solution for a problem they are not impacted by. |
This comment was marked as abuse.
This comment was marked as abuse.
The independent Ninja build language reimplementation https://github.com/michaelforney/samurai supports this via the environment variable SAMUFLAGS. Simply use samu anywhere you'd otherwise use ninja, or install samu as your system /usr/bin/ninja (some linux distros have options to install this competing implementation as the default, or only, ninja). |
@eli-schwartz unfortunately samu doesn't support |
Consider asking samu to implement |
@lilydjwg Adding support for |
@lilydjwg there's an open feature request to add it to samurai and the developer has even said he will accept a patch for it. |
@ddevault @Salamandar @eli-schwartz thank you but I've taken another suggestion to make those processes compete fairly with cgroups because I don't need to modify the build environment this way so it's much simpler to implement. Hopefully make & ninja will play fair and give enough CPU resources to system services. (make -l & ninja -l doesn't play very well: the process numbers are unbalanced and CPU cores are under-utilized.) |
I think I agree. They just "dont start jobs if load is too high", that's not a good idea for a multi-user machine. Cgroups are the way to go. |
I think I agree. They just "dont start jobs if load is too high", that's not a good idea for a multi-user machine. Cgroups are the way to go.
Are those available on all modern Unix variants?
|
Depends on your definition of "modern Unix". But I guess that's a rhetorical question anyway and you already know that cgroups are a Linux kernel feature. |
But I guess that's a rhetorical question anyway and you already know that cgroups are a Linux kernel feature.
Actually I didn't, just had a hunch. Here's another not-really rhetorical question: how many such a platform-specific feature can you use in what's supposed to be a lean and mean application, before it isn't anymore? ;)
I agree though that the current load-limited option is (AFAICT) mostly interesting/useful if you want to allow ninja to take over the entire host without shooting itself in the foot (too much).
|
What does this have to do with anything? Someone who previously thought samurai wasn't a good replacement for ninja because it doesn't implement No one has suggested implementing or reimplementing |
The value of the variable is parsed like command line arguments. You can for
instance use less cores than available (-j), or limit the parallelism based
on the system load (-l). For instance, on a build server used by multiple
users, you may want to set
NINJA_FLAGS=-l 1
on the system level, so thatthe server never gets overloaded by parallel ninja builds. Command line
parameters override the flags set with NINJA_FLAGS.