|
| 1 | +# Aeneas user documentation - developer docs |
| 2 | + |
| 3 | +## Architecture |
| 4 | + |
| 5 | +This is a separate `flake.nix` setup from the root repository's one, but it relies on Aeneas' Lean library from this repository. |
| 6 | + |
| 7 | +We pull Lean 4's upstream flake to build Lean in Nix, use some forked Alectryon-related tooling to assemble a mdBook HTML output. |
| 8 | + |
| 9 | +### How to add new files? |
| 10 | + |
| 11 | +If these files are not supposed to be inked by Alectryon (i.e. display interactive goals in the browser), they can be extended following [the vanilla mdBook documentation](https://rust-lang.github.io/mdBook/guide/creating.html) in the `src/` directory. |
| 12 | + |
| 13 | +If these files are supposed to be inked by Alectryon: |
| 14 | + |
| 15 | +- they need to appear in `src/lean/basics` as `xyz.lean` and `xyz.lean.md` |
| 16 | +- the Markdown file version should be included in the `SUMMARY.md` file. |
| 17 | +- the contents of `xyz.lean.md` by default should be the same as the others one, i.e. a Lean code block containing `{{#include xyz.lean}}` |
| 18 | + |
| 19 | +### How to add a new directory containing Lean files? |
| 20 | + |
| 21 | +This requires a change in the `flake.nix`, find the place where the `literate` package is defined: |
| 22 | + |
| 23 | +```nix |
| 24 | + literate = buildLeanPackage { |
| 25 | + name = "literate"; |
| 26 | + deps = [ aeneas-base ]; |
| 27 | + src = ./.; |
| 28 | + roots = [ |
| 29 | + { |
| 30 | + mod = "src/lean/basics"; |
| 31 | + glob = "submodules"; |
| 32 | + } |
| 33 | + ]; |
| 34 | + }; |
| 35 | +``` |
| 36 | + |
| 37 | +Add a new `root` as it follows, assuming your new module is `src/lean/advanced`: |
| 38 | + |
| 39 | +```nix |
| 40 | + literate = buildLeanPackage { |
| 41 | + name = "literate"; |
| 42 | + deps = [ aeneas-base ]; |
| 43 | + src = ./.; |
| 44 | + roots = [ |
| 45 | + { |
| 46 | + mod = "src/lean/basics"; |
| 47 | + glob = "submodules"; |
| 48 | + } |
| 49 | + { |
| 50 | + mod = "src/lean/advanced"; |
| 51 | + glob = "submodules"; |
| 52 | + } |
| 53 | + ]; |
| 54 | + }; |
| 55 | +``` |
| 56 | + |
| 57 | +### How to add a new Lean dependency to the project? |
| 58 | + |
| 59 | +Each `buildLeanPackage` can take a list of `deps`. |
| 60 | + |
| 61 | +Two cases: |
| 62 | + |
| 63 | +- either, this is a local dependency and this can be built like the `Base` (Aeneas standard library) one. |
| 64 | +- or, this is a remote dependency and this is often added to a Lakefile, this can be built like `Mathlib` and the others. |
| 65 | + |
| 66 | +## How to build? |
| 67 | + |
| 68 | +```console |
| 69 | +$ nix build .#docs |
| 70 | +``` |
| 71 | + |
| 72 | +## How to deploy? |
| 73 | + |
| 74 | +The `result/` symlink is a HTML webroot, this can be deployed as a static website. |
| 75 | + |
| 76 | +## How to update the dependencies? |
| 77 | + |
| 78 | +You just updated `backends/lean/lakefile.lean` dependencies or the Lean version. |
| 79 | + |
| 80 | +### Lean version |
| 81 | + |
| 82 | +Update the flake URI in `flake.nix`, this will trigger a mass rebuild of the documentation: rebootstrapping Lean 4 (this may take a couple of minutes), rebuilding Mathlib4 (this may take up to 20 minutes on a fast computer), building Aeneas standard library and finally the documentation. |
| 83 | + |
| 84 | +### Updating Aeneas standard library's dependencies |
| 85 | + |
| 86 | +You may need to change all `hash = "...";` reference between `aeneas-base =` and `in`, which are the dependencies of `Base`, Aeneas standard library. |
| 87 | + |
| 88 | +To do so, you can replace `hash = "...";` by `hash = lib.fakeHash;`, and rebuild, i.e. `nix build .#doc`, Nix will provide the actual SRI hash. |
| 89 | + |
| 90 | +_Advice_ : build with `--keep-going` to get all hashes at once instead of having to copy one hash per one hash. |
| 91 | + |
| 92 | +## My build is failing due to a compilation error but it works outside of Nix |
| 93 | + |
| 94 | +This is highly likely due to a mismatch between the dependencies in the Nix setup and outside. |
| 95 | + |
| 96 | +The Nix setup reads the `lakefile-manifest.json`, but this lockfile is insufficient to lock purely the dependencies (NAR SHA256 serialization are missing). |
| 97 | + |
| 98 | +To overcome this, they are specified manually in `flake.nix`, but each time the Aeneas standard library updates their dependencies, the `flake.nix` needs to have all its hash rewritten. Refer to "How to update" for guidance. |
| 99 | + |
| 100 | +In the future, it could be smart to extend the lockfile format or write another file besides in the Aeneas standard library containing all NAR SHA256 serializations and link it in the Lake build system so that each updates would regenerate this file. |
| 101 | + |
| 102 | +# Reference documentation |
| 103 | + |
| 104 | +## `fetchFromLakeManifest` |
| 105 | + |
| 106 | +This is a simple Nix function that looks inside a Lean manifest and pulls the Git input information, it does not handle yet automatically fetching the NAR SHA256 serialization of the Git input as Lake does not store this information in its lockfile. |
| 107 | + |
| 108 | +This means that whenever you are updating the manifest, you need to replace all `hash = "...";` by `hash = lib.fakeHash;` to bust the cache, otherwise you will run into compilation errors. |
| 109 | + |
| 110 | +## `addFakeFiles` |
| 111 | + |
| 112 | +Mathlib4 depends on `proof-widgets`, a Lean library which depends on Node.js for its build system, to avoid wasting time to package multi-language dependency system, `addFakeFiles` is a function to poly-fill by **empty files** specific modules, fooling the build system into believing that these files have been built externally. |
| 113 | + |
| 114 | +## `renderPackage` |
| 115 | + |
| 116 | +This is a function to analyze an entire Lean package via [Alectryon](https://github.com/cpitclaudel/alectryon) and [LeanInk](https://github.com/leanprover/LeanInk) and assemble this as a tree of symlinks for each module in the package. |
0 commit comments