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.