forked from OSchip/llvm-project
130 lines
5.6 KiB
ReStructuredText
130 lines
5.6 KiB
ReStructuredText
|
=====================
|
||
|
Building LLVM with GN
|
||
|
=====================
|
||
|
|
||
|
.. contents::
|
||
|
:local:
|
||
|
|
||
|
.. _Introduction:
|
||
|
|
||
|
Introduction
|
||
|
============
|
||
|
|
||
|
*Warning* The GN build is experimental and best-effort. It might not work,
|
||
|
and if you use it you're expected to feel comfortable to unbreak it if
|
||
|
necessary. LLVM's official build system is CMake, if in doubt use that.
|
||
|
If you add files, you're expected to update the CMake build but you don't need
|
||
|
to update GN build files. Reviewers should not ask authors to update GN build
|
||
|
files. Keeping the GN build files up-to-date is on the people who use the GN
|
||
|
build.
|
||
|
|
||
|
*Another Warning* Right now, we're in the process of getting the GN build
|
||
|
checked in. As of this writing, it's not yet functional at all. Check back
|
||
|
in a few weeks!
|
||
|
|
||
|
`GN <https://gn.googlesource.com/gn/>`_ is another metabuild system. It always
|
||
|
creates ninja files, but it can create some IDE projects (MSVC, Xcode, ...)
|
||
|
which then shell out to ninja for the actual build.
|
||
|
|
||
|
Its main features are that GN is very fast (it currently produces ninja files
|
||
|
for LLVM's build in 35ms on the author's laptop, compared to 66s for CMake) --
|
||
|
a 2000x difference), and since it's so fast it doesn't aggressively cache,
|
||
|
making it possible to switch e.g. between release and debug builds in one build
|
||
|
directory.
|
||
|
|
||
|
It is arguable easier to configure than the CMake build, and has native support
|
||
|
for building with multiple toolchains in one build directory. The build
|
||
|
description is declarative-ish, allowing GN to print it in a json format that
|
||
|
can fairly easily be converted to other metabuild system inputs.
|
||
|
|
||
|
The main motivation behind the GN build is that some people find it more
|
||
|
convenient for day-to-day hacking on LLVM than CMake. Distribution, building
|
||
|
just parts of LLVM, and embedding the LLVM GN build from other builds are a
|
||
|
non-goal for the GN build.
|
||
|
|
||
|
This is a `good overview of GN <https://docs.google.com/presentation/d/15Zwb53JcncHfEwHpnG_PoIbbzQ3GQi_cpujYwbpcbZo/edit#slide=id.g119d702868_0_12>`_.
|
||
|
|
||
|
.. _Quick start:
|
||
|
|
||
|
Quick start
|
||
|
===========
|
||
|
|
||
|
*Warning* Right now, we're in the process of getting the GN build checked in.
|
||
|
As of this writing, it's not yet functional at all.
|
||
|
|
||
|
GN only works in the monorepo layout.
|
||
|
|
||
|
#. Obtain a `gn binary <https://gn.googlesource.com/gn/#getting-started>`_.
|
||
|
|
||
|
#. In the root of the monorepo, run
|
||
|
`gn gen --dotfile=$PWD/llvm/utils/gn/.gn --root=. out/gn` (`out/gn` is the
|
||
|
build directory, it can have any name, and you can have as many as you want,
|
||
|
each with different build settings).
|
||
|
|
||
|
#. Run e.g. `ninja -C out/gn check-lld` to build all prerequisites for and
|
||
|
run the LLD tests.
|
||
|
|
||
|
By default, you get a release build with assertions enabled that targets
|
||
|
the host arch. You can set various build options by editing `out/gn/args.gn`,
|
||
|
for example putting `is_debug = true` in there gives you a debug build. Run
|
||
|
`gn args --list out/gn` to see a list of all possible options. After touching
|
||
|
`out/gn/args.gn`, just run ninja, it will re-invoke gn before starting the
|
||
|
build.
|
||
|
|
||
|
GN has extensive built-in help; try e.g. `gn help gen` to see the help
|
||
|
for the `gen` command. The full GN reference is also `available online
|
||
|
<https://gn.googlesource.com/gn/+/master/docs/reference.md>`_.
|
||
|
|
||
|
GN has an autoformatter: `git ls-files '*.gn' '*.gni' | xargs -n 1 gn format`
|
||
|
after making GN build changes is your friend.
|
||
|
|
||
|
To not put `BUILD.gn` into the main tree, they are all below `utils/gn/tree`.
|
||
|
For example, the build file for `llvm/lib/Support` is in
|
||
|
`utils/gn/tree/llvm/lib/Support`.
|
||
|
|
||
|
.. _Philosophy:
|
||
|
|
||
|
Philosophy
|
||
|
==========
|
||
|
|
||
|
GN believes in using GN arguments to configure the build explicitly, instead
|
||
|
of implicitly figuring out what to do based on what's available on the current
|
||
|
system.
|
||
|
|
||
|
configure is used for three classes of feature checks:
|
||
|
|
||
|
- compiler checks. In GN, these could use exec_script to identify the host
|
||
|
compiler at GN time. For now the build has explicit toggles for compiler
|
||
|
features. (Maybe there could be a script that writes args.gn based on the
|
||
|
host compiler). It's possible we'll use exec_script() for this going forward,
|
||
|
but we'd have one exec_script call to identify compiler id and version,
|
||
|
and then base GN arg default values of compiler id and version instead of
|
||
|
doing one exec_script per feature check.
|
||
|
(In theory, the config approach means a new os / compiler just needs to tweak
|
||
|
the checks and not the code, but in practice a) new os's / compilers are rare
|
||
|
b) they will require code changes anyhow, so the configure tradeoff seems
|
||
|
not worth it.)
|
||
|
|
||
|
- library checks. For e.g. like zlib, GN thinks it's better to say "we require
|
||
|
zlib, else we error at build time" than silently omitting features. People
|
||
|
who really don't want to install zlib can explicitly set the GN arg to turn
|
||
|
off zlib.
|
||
|
|
||
|
- header checks (does system header X exist). These are generally not needed
|
||
|
(just keying this off the host OS works fine), but if they should become
|
||
|
necessary in the future, they should be done at build time and the few
|
||
|
targets that need to know if header X exists then depend on that build-time
|
||
|
check while everything else can build parallel with it.
|
||
|
|
||
|
- LLVM-specific build toggles (assertions on/off, debug on/off, targets to
|
||
|
build, ...). These map cleanly to GN args (which then get copied into
|
||
|
config.h in a build step).
|
||
|
|
||
|
For the last two points, it would be nice if LLVM didn't have a single
|
||
|
`config.h` header, but one header per toggle. That way, when e.g.
|
||
|
`llvm_enable_terminfo` is toggled, only the 3 files caring about that setting
|
||
|
would need to be rebuilt, instead of everything including `config.h`.
|
||
|
|
||
|
GN doesn't believe in users setting arbitrary cflags from an environment
|
||
|
variable, it wants the build to be controlled by .gn files.
|