I'm building webkit-gtk right now. It's one of these messy packages where a few source files need a lot of memory to compile, and ninja can randomly order jobs so that all of them suddenly start compiling simultaneously. So to keep things going smoothly without OOM-ing, I've been dynamically adjusting the available job count via steve the #jobserver.

While doing that, I've noticed that ninja isn't taking new jobs immediately after I increased the job count. So I've started debugging steve, and couldn't find out anything wrong with it. Finally, I've looked into ninja and realized how lazy their code is.

So, there are two main approaches to acquiring job tokens. Either you do blocking reads, and therefore wait for a token to become available, or you use polling to get noticed when it becomes available. Ninja instead does non-blocking reads, and if there are no more tokens available… it waits till one of its own jobs finish.

This roughly means that as other processes release tokens, ninja won't take them until one of its own jobs finish. And if ninja didn't manage to acquire any job tokens to begin with, it is just running a single process via implicit slot, and that process finishing provides it with the only chance to acquire additional tokens. So realistically speaking, as long as there are other build jobs running in parallel, ninja is going to need to be incredibly lucky to ever get a job token, since all other processes will grab the available tokens immediately.

This isn't something that steve can fix.

#Gentoo #NinjaBuild

Yeah, so the GNU #make jobserver protocol is trivial, which can be a blessing and a curse. It puts the job management entirely on the clients, which means that they must reliably return job tokens, or otherwise the jobserver will be left with no jobs available and everything will hang. The make documentation is clear on this:

> Your tool should be sure to write back the tokens it read, even under error conditions. This includes not only errors in your tool but also outside influences such as interrupts (SIGINT), etc. You may want to install signal handlers to manage this write-back.

https://www.gnu.org/software/make/manual/html_node/POSIX-Jobserver.html

I was worried that the #NinjaBuild jobserver implementation may not handle this correctly, but fortunately it does. The irony is, it turns out that GNU make does not…

https://savannah.gnu.org/bugs/index.php?67687

#Gentoo

POSIX Jobserver (GNU make)

POSIX Jobserver (GNU make)

Working with #cpp20 #cppmodules with #ninjabuild and #cmake

How can I run just the scan/dynamic based bits so that I can run clang-tidy without a full build?

ATM I have this hack
```
# cmake config
cmake --preset thing

# select what I need made
ninja -C build -t inputs | grep -E '\.cppm\.o$|\.o\.modmap$' | xargs -r ninja -C build

# then I can run clang-tidy
```

There must be a better way

#cpp #cplusplus #programming

@koakuma If you are maintaining #makefile by hand, you could just put time utility before every linker and compiler. Piping each command to tee would save your stdout now containing time how long given step took.

Anyway I don't think its really that usefull information, so maybe its better just to track overall #make / #ninjabuild time across changes?

I finally capitulated and added the following to my ~/.zshrc.. Hah.

# I type this wrong often..
alias nija='ninja'
alias inja='ninja'
alias ninj='ninja'

#zsh #zshrc #alias #shell #ninjabuild