= Usage :page-pagination: next `zilch-cli-ninja` allows you to use Zilch to compile a Ninja-based nixpkgs derivation reproducibly, and to quickly modify it and rebuild it reproducibly as well. To use the tool, you first have to write a configuration file. This document will use this example, for `gtest`: .`gtest.scm` [,scheme] ---- (environment: "pkgs.gtest" depfile-path: "gtest-deps.scm") ---- This can then be used with the various subcommands of `zilch-cli-ninja`: == Building To build a derivation with `zilch-cli-ninja`, use the `build` subcommand. [,console] ---- $ zilch-cli-ninja -f gtest.scm build <1> … dev -> # out -> # $ zilch-cli-ninja -f gtest.scm build googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o <2> … googlemock/CMakeFiles/gmock_main.dir/src/gmock_main.cc.o -> "/nix/store/c96j8sqk08xj15pififz5myjzskg0cqw-Building-CXX-object-googlemock-CMakeFiles-gmock_main.dir-src-gmock_main.cc.o" ---- <1> Build the full derivation <2> Build a specific output of the Ninja file == Source editing Zilch makes it very easy to edit the source of any derivation built in this manner. With one command, you can export the source code used for building. This source can then be used to rebuild parts of the derivation that have changed. [,console] ---- $ zilch-cli-ninja -f gtest.scm source gtest-src <1> … $ zilch-cli-ninja -f gtest.scm -s gtest-src diff <2> … $ zilch-cli-ninja -f gtest.scm -s gtest-src build <3> … dev -> # out -> # ---- WARNING: Zilch will not regenerate the build files when editing source in this manner, for performance and logistical reasons. To change the build files, override the `src` attribute of the environment's derivation. == Limitations To make the Nixpkgs integration work, the Zilch code breaks up the derivation's phases into two steps: unpack + patch + configure, and check + install. This can cause issues with derivations that expect to share variables between these phases. If `meson` is present, it is assumed to be used, otherwise it is assumed the derivation is `cmake`-based. Other build systems are not yet supported. The final store path of the derivation is not known at configuration time, unlike normal derivations. Meson and CMake are configured to install into a prefix, and are then rewritten (using `sed`) to the final output store path. This may cause issues with programs that e.g. compress a file containing these paths during their build.footnote:[The only one to have known issues is Node.] == Patches In some cases, the code may not handle running in Zilch's environment. In this case, it's possible to add extra code to run before running the command of a target. These patches are defined as part of the configuration file, and are arbitrary Scheme code: [,scheme] ---- (environment: "import ./sample.drv" patch: (lambda (edge) (if (string=? (build-edge-rule edge) "foo") "rm src/foo; echo 'replacement file' > src/foo" #f))) ---- Patches are arbitrary shell scripts, run with GNU Coreutils in `$PATH`. The environment variable `$_ZILCH_ROOT` points to the root of the source + build file tree, and can be used to copy non-symlinked files into the working directory. == Automatic file elision To implement incremental builds efficiently, Zilch automatically slims down the part of the source directory that is accessible to each target. If a filename ends in `.cc` or `.c` and is directly depended upon as in input file to a target, it will be elided, and only the targets that depend on it directly will be able to read its contents. The `build/meson-private` directory is fully elided, except for derivations that directly depend upon it. This is to limit the amount of impurities that are part of the configuration process. === Dependency tracking When a depfile cache is provided, and the output being built supports dependency files, any files ending in `.h` and `.hh` that aren't a known dependency are elided. However, if the build fails, it will be retried with all header files visible to the client. In some cases, this dependency tracking is imprecise, and causes some header files to not be properly visible to targets that need it. In this case, you can add an extra entry to the configuration file: .`lix.scm` [,scheme] ---- (environment: "(pkgs.lix.override { enableDocumentation = false; }).overrideAttrs (a: { doCheck = false; doInstallCheck = false; })" depfile-path: "lix-depfile.scm" disallow-elide: (lambda (path) (string=? path "config.h"))) ---- This example ensures that `config.h` will be available to all targets being built for the derivation. == Library stubs When using Meson, any libraries that are linked will also simultaneously generate a stub `.so` file, using `llvm-ifs`. This stub library is valid for linking, but contains no code, and is generated deterministically. When linking any other libraries or binaries that depend on this library, the stub is automatically used, which improves early cutoff between library builds.