Index: docs/GN.rst
===================================================================
--- docs/GN.rst
+++ docs/GN.rst
@@ -0,0 +1,118 @@
+=====================
+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.
+
+*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 week!
+
+`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 `_.
+
+.. _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.
+
+#. In the root of the monorepo, run `gn gen out/gn` (or any other directory)
+
+#. 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
+`_.
+
+GN has an autoformatter: `git ls-files '*.gn' '*.gni' | xargs -n 1 gn format`
+after making GN build changes is your friend.
+
+.. _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.