dhbaird / rules_foreign_cc_jobserver

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

rules_foreign_cc_jobserver

Rules_foreign_cc_jobserver provides a Make-based jobserver to help run Make inside of Bazel in conjunction with rules_foreign_cc. Read this for the background information:

bazelbuild/rules_foreign_cc#329 Parallel build support

At some point, we may hope Bazel may provide a jobserver of its own, or other means of enabling parallel Make builds, and then you won't need rules_foreign_cc_jobserver anymore. But in the mean time, this may help!

News

20201008 - Renamed jmake to sjsmake (breaking change, apologies) to avoid conflict with another project that already uses the jmake name.

Instructions

Step 1: Get the jobserver running:

If you are running a systemd-based system:

sudo cp --preserve=mode start_jobserver /usr/local/bin
cp jobserver.service ~/.config/systemd/user/jobserver.service
systemctl --user daemon-reload
systemctl --user enable --now jobserver
systemctl --user status jobserver.service

Note: you may want to edit ~/.config/systemd/user/jobserver.service to adjust the number of job slots. By default, start_jobserver will use nproc to determine the number of threads available on your machine.

Step 2: Add this to your WORKSPACE (along with the other lines described at https://github.com/bazelbuild/rules_foreign_cc/:

http_archive(
   name = "rules_foreign_cc_jobserver",
   strip_prefix = "rules_foreign_cc_jobserver-main",
   url = "https://github.com/dhbaird/rules_foreign_cc_jobserver/archive/main.zip",
)

# Tell rules_foreign_cc to use sjsmake:
rules_foreign_cc_dependencies([
    "@rules_foreign_cc_jobserver//:built_sjsmake"
])

Step 3: When running Bazel, you have to provide options to help it locate and write to the jobserver directory:

JOBSERVER=$HOME/.jobserver   # <-- Maybe add this to your login scripts?
bazel build @all//... --sandbox_writable_path=$JOBSERVER --action_env=JOBSERVER=$JOBSERVER

How Does It Work?

The objective is to attain a reasonable level of parallelism out of the CPU: not wildly over-subscribing it, but also not under-subscribing it. Rules_foreign_cc_jobserver does this by allow O(N) processes to be scheduled at any time: Bazel can schedule N processes, and Make can schedule N processes, but subtract 1 because one of the Bazel processes is Make. N is the number of threads available on the CPU.

Without a shared jobserver, things become drastically worse. If you really try to exploit your CPUs, you end up with O(N*N) (quadratic) jobs by launching several independent Makes with the maximum concurrency and no shared jobserver. This will of course eat your RAM and cause unhelpful extra scheduling overhead. If you try to be conservative, you end up with possibly long O(1) tails, by disabling concurrency in Make. Those options are both bad. O(N) is what we want. Actually, exactly just N is what we really want, but in this case here we settle for a 2*N-1 compromise. This compromise is unavoidable since we have two separate schedulers that don't know about each other. But is a very usable compromise until Bazel can be enhanced to make one unified job scheduler possible.

Additional reading:

About

License:Apache License 2.0


Languages

Language:Shell 52.1%Language:Starlark 47.9%