This is a module for mongodb that makes scons generate build.ninja files.
To use it, check out this repo into the src/mongo/db/modules
directory in
your mongodb checkout. You may want to rename it to something short like
ninja
. Then run scons
with your favorite flags and have it build
build.ninja. You can now use ninja
to build anything that scons can.
mkdir src/mongo/db/modules
cd src/mongo/db/modules
git clone https://github.com/RedBeard0531/mongo_module_ninja ninja
cd -
# On non-linux, remove -gsplit-dwarf.
# Also, be sure to read the section about split DWARF below.
python buildscripts/scons.py CC=clang CXX=clang++ \
VARIANT_DIR=ninja CCFLAGS='-gsplit-dwarf' \
MONGO_VERSION='0.0.0' MONGO_GIT_HASH='unknown' \
--link-model=dynamic \
build.ninja
export NINJA_STATUS='[%f/%t (%p) %es] ' # make the ninja output even nicer
ninja mongod # builds mongod
ninja # builds the default target (still mongod)
ninja core # supports all scons aliases except lint and distsrc
ninja build/unittests/TAB # autocompletion should work
If you want to change your build flags, just run the scons
command with the
new flags to have it regenerate the build.ninja file. ninja
will
automatically regenerate the build.ninja file whenever any of the SCons files
change so you don't shouldn't need to manually rerun scons often.
This module requires ninja >= 1.7. You can download it from
here
if if isn't in your distribution. Note that Fedora calls both the binary and the
package ninja-build
. Ubuntu calls the package ninja-build
but leaves the
binary named ninja
. Ubuntu <= yakkety (16.10) uses an old version of ninja so
you will need to download the binary if you aren't running that release.
This module adds the following options to scons. Unfortunately, they won't show
up with --help
so they are documented here.
Flag | Default | Description |
---|---|---|
--icecream |
off | LINUX ONLY Use icecream for distributed compilation |
--pch |
off | Use pre-compiled headers to speed up local compilation. Incompatible with icecream and ccache. Mostly useful on Windows. |
--link-pool-depth=NNN |
4 | WINDOWS ONLY: limit the number of concurrent link tasks |
--ninja-builddir=path |
current directory | Where ninja stores its database. Delete your build/ directory if you change this! |
- Email or slack me (Mathias) if you run in to any problems.
- If scons says your C or C++ compiler doesn't work, pass the
--config=force
flag to scons. - If you get an error about
is_derived_node
you are using an old version of scons. Try usingpython buildscripts/scons.py
rather than justscons
. - If you get an error about
Unknown variables specified:
try removing all of the\
s from your command line. - If scons is prompting for your password, try checking out this module with
the
https://
url used above rather than a[email protected]
url. - If running ninja errors with a message like
die: error: unable to read configuration file
your distro probably uses a different package namedninja
. Try uninstalling that and installing the package namedninja-build
. Also re-read the last paragraph of the introduction section. - If any of your debugging tools behave oddly, read the section about split
DWARF info below and consider removing
-gsplit-dwarf
from your CCFLAGS. - If ccache doesn't seem to be working, run
CCACHE_LOGFILE=/tmp/ccache.log ninja -j1
, let it compile a few objects, then look at/tmp/ccache.log
. It should tell you why it isn't able to use the cache. If that doesn't help, see step 1. - If you are using icecream and you build seems to hang or go really slowly,
try restarting the icecream daemon.
systemctl restart iceccd
orsystemctl restart icecream
depending on which distribution you are using.
You can run ninja +name_of_test
to build then run a cpp unit test. This uses
the "basename" of the test, so build/ninja/mongo/bson/bson_obj_test
is just
ninja +bson_obj_test
. This is intended to simplify iterating on one or two
tests. To run all of the unittests, continue to use something like ninja unittests && buildscripts/resmoke.py --suites=unittests -j16
.
This also works with micro-benchmarks (eg ninja +future_bm
), but only run them
by themselves not with anything else. For example, don't build another
target (ninja +future_bm mongod
), or even multiple benchmarks at once
(ninja +future_bm +clock_source_bm
). You want your system as close to idle as
possible when testing performance.
If you have ccache
installed and on your path, it will be used automatically.
If you have it installed but don't want to use it, pass --no-cache
to scons.
You can tell if it is being used by the message printed by scons:
> scons --modules=ninja build.ninja
...
Generating build.ninja with ccache support (pass --no-cache to scons to disable)
scons: done building targets.
> scons --modules=ninja build.ninja --no-cache
...
Generating build.ninja
scons: done building targets.
If you often switch between multiple sets of flags, you can make a *.ninja
file for each set. Each *.ninja
file is executable so you can run it directly,
but unfortunately that breaks tab completion.
I suggest passing --config=force
to scons
for all of your *.ninja
files to
keep scons from getting confused as you switch. If you are using ccache, I
suggest using the VARIANT_DIR=ninja
scons variable so that all builds have the
same path. Conversely, if you don't use ccache, I suggest using a different
VARIANT_DIR
for each set of flags so they don't conflict.
scons CC=clang CXX=clang++ VARIANT_DIR=ninja --config=force build.ninja
scons CC=gcc CXX=g++ VARIANT_DIR=ninja --config=force gcc.ninja
ninja mongod # builds mongod with clang
ninja -f gcc.ninja mongod # builds mongod with gcc
./gcc.ninja mongod # shorter syntax
You can have ninja generate the compilation db used by many clang-based tools by
running ninja compile_commands.json
or using the compiledb
alias like in
scons. For your convienience this will also update all generated sources so
tools will work when a compile db is created on a clean build tree. You probably
only want to use this with a .ninja file configured to use clang so that it uses
the set of flags that most tools expect.
The compilation db will be slightly different than the one generated by scons.
It adds flags that ninja uses to track header dependencies and each command may
be prefixed by ccache
. I have tested this with
rtags,
YouCompleteMe/ycmd and a few of the
extra clang tools and they all handle this fine.
Please let me know if this causes problems for any tools you use.
On linux, you can pass CCFLAGS=-gsplit-dwarf
to try out split dwarf support
which makes linking much faster. ccache
>= 3.2.3 supports it out of the box so
they can be used together. scons
will error if you use -gsplit-dwarf with an
older ccache or an unsupported platform.
In order to actually use the dwarf info, your debugging tools will need to
support it. I've tested the latest perf, addr2line, and llvm-symbolizer
(used by mongosymb.py
) on linux and they all work. I don't know about older
versions or other tools. If your tool of choice doesn't work, upgrade or remove
-gsplit-dwarf
and recompile.
GDB >= 7.11 has a bug
that makes it show all namespaces other than std
as (anonymous namespace)
.
If this affects you, you can either recompile without -gsplit-dwarf
or apply
the patch from that ticket to your gdb. If you are a MongoDB employee, you can
download the latest version of
our toolchain which
includes a patched gdb.
On linux, you can use icecream to distribute your compile tasks to your neighbors' computers, and literally Build Together. This can dramatically reduce the time to do large rebuilds.
- Make sure you are using ccache
- Follow the distribution-specific steps below to install and run the icecream daemon
- Add
--icecream
to the list of flags you pass to scons when building yourbuild.ninja
file - Run
ninja
with a high-j
value such as-j400
(this is specifically for when running ninja since the-j
you pass to scons when building thebuild.ninja
file doesn't matter)
Since others can now schedule builds on your machine at any time, consider
disabling the icecream daemon when doing benchmarking. Depending on your
distribution, this is either systemctl stop icecream
or systemctl stop iceccd
. You will want to restart the daemon before compiling again.
Due to this issue, ccache older
than 3.4 requires an additional pass of the C++ preprocessor when using clang
(but not gcc). This can become a bottleneck limiting the speed that you can
submit jobs to the cluster. You can set the CCACHE_DISABLE=1
environment
variable when running ninja to speed up your builds with the trade-off that it
won't cache the compilations. Or just upgrade to a newer ccache.
apt-get install icecc
- Download the
amd64.deb
from this ppa and install it withdpkg -i
(yes you need to install from the main repo first then upgrade...)
- Install
icecream
from the AUR systemctl enable --now icecream.service
dnf install icecream
and make sure it is installing 1.1rc2firewall-cmd --zone=FedoraServer --add-service=icecream
firewall-cmd --permanent --zone=FedoraServer --add-service=icecream