Home Explore Blog Models CI



nixpkgs

3rd chunk of `pkgs/development/compilers/llvm/README.md`
d09ea52cc55905b412936bfd7826bb40a5db11a7e570d4990000000100000bea
    For cases where the hunk is no longer needed you can simply remove it from the patch.

 This is fine for small corrections, but when more serious changes are needed, it's better to use git.

 1. Clone the LLVM monorepo at https://github.com/llvm/llvm-project/

 2. Check out the revision we were using before.

 3. Use `patch -p1 < path/to-path` in the project subdirectories to apply the patches and commit.

 4. Use `git rebase HEAD^ --onto <dest>` to rebase the patches onto the new revision we are trying to build, and fix all conflicts.

 5. Use `git diff HEAD^:<project> HEAD:<project>` to get subdir diff to write back to Nixpkgs.

## Information on our current patch sets

### "GNU Install Dirs" patches

Use CMake's [`GNUInstallDirs`](https://cmake.org/cmake/help/latest/module/GNUInstallDirs.html) to support multiple outputs.

Previously, LLVM just hard-coded `bin`, `include`, and `lib${LLVM_TARGET_PREFIX}`.
We are making it use these variables.

For the older LLVM versions, these patches live in https://github.com/Ericson2314/llvm-project branches `split-prefix`.
Instead of applying the patches to the worktree per the above instructions, one can checkout those directly and rebase those instead.

For newer LLVM versions, enough has has been upstreamed,
(see https://reviews.llvm.org/differential/query/5UAfpj_9zHwY/ for my progress upstreaming),
that I have just assembled new gnu-install-dirs patches from the remaining unmerged patches instead of rebasing from the prior LLVM's gnu install dirs patch.

## Adding a patch

To add an LLVM patch in the Nixpkgs tree,

1. Put the patch in the corresponding directory (`<VERSION>/<PACKAGE>`).

   _Example_: If you want your patch to apply to clang version 12 (and, optionally, later versions), put it in `./12/clang`.
2. Add the patch to the `patches` argument of the corresponding package in `./common`, guarded by a `lib.optionals` with the desired version constraints, passed through the `getVersionFile` function.

   _Example_: If you want the patch `./12/llvm/fix-llvm-issue-49955.patch` to apply to LLVM 12, add `lib.optional (lib.versions.major release_version == "12") (getVersionFile "llvm/fix-llvm-issue-49955.patch")` to `./common/llvm/default.nix`.
3. If you wish for this single patch to apply to multiple versions of the package, extend the conditions in the `lib.optional` guard and add the corresponding constraints to `./common/patches.nix`; note that `after` is inclusive and `before` is exclusive.

   _Example_:
   If you want the patch `./12/clang/purity.patch` to apply to versions 12, 13 and 14, you have to
   - Modify the guard in `./common/clang/default.nix` as follows: `lib.optional (lib.versionAtLeast release_version "12" && lib.versionOlder release_version "15")`
   - Add `{ "clang/purity.patch" = [ { after = 12; before = 15; path = ../12; } ]; }` to `common/patches.nix`.
   You may have multiple different patches with the same name that would apply to different versions; in that case, add the necessary constraints to `common/patches.nix`.


Title: LLVM Patching: Git-based Workflow, GNU Install Dirs, and Nixpkgs Addition
Summary
A Git-based workflow for significant LLVM patch changes is detailed: clone LLVM monorepo, checkout previous revisions, apply patches (`patch -p1`), rebase onto new revisions (fixing conflicts), and generate updated diffs using `git diff` for Nixpkgs. The "GNU Install Dirs" patches use CMake's `GNUInstallDirs` for flexible output directories (e.g., `bin`, `include`, `lib`), replacing hard-coded paths. Older versions use `split-prefix` branches; newer versions are re-assembled from unmerged patches due to upstreaming. Adding new LLVM patches to Nixpkgs involves: placing the patch in `<VERSION>/<PACKAGE>` (e.g., `./12/clang`), adding it to the `patches` argument in `./common/default.nix` with `lib.optionals` for version constraints, and extending multi-version applicability by updating the `lib.optional` guard and `common/patches.nix` with `after`/`before` constraints.