Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

llvmPackages_{12,13,14,15,16,17,18,git}: Allow overriding dependencies #320261

Merged
merged 1 commit into from
Jun 20, 2024

Conversation

pwaller
Copy link
Contributor

@pwaller pwaller commented Jun 16, 2024

... consistently.

This should require 0 package rebuilds.

Description of changes

Further to #307211, allow overriding arguments through llvmPackages.override.

This makes it possible to override any dependency of LLVM or
clang by overriding it on llvmPackages.override { <dependency> = ...; }.

This is useful in development or customization where sometimes it is
desirable to turn features on or off.

Without this patch the only way to for example override ncurses was to
do overriddenLLVM = llvmPackages.llvm.override { ncurses }, but then
you would have to thread overriddenLLVM as dependencies into clang and
other packages, which results in quite a difficult expression to write
correctly in cross compilation scenarios.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.11 Release Notes (or backporting 23.11 and 24.05 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

Copy link
Member

@RossComputerGuy RossComputerGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great.

@pwaller
Copy link
Contributor Author

pwaller commented Jun 16, 2024

@Artturin can this get the same backport treatment as #307211 please? :)

Thanks for the speedy review @RossComputerGuy!

@RossComputerGuy RossComputerGuy added the backport release-24.05 Backport PR automatically label Jun 16, 2024
@ofborg ofborg bot added 10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux labels Jun 16, 2024
@paparodeo
Copy link
Contributor

paparodeo commented Jun 16, 2024

can this be accomplished with a named attribute set argument?

{ ninja, foo, bar, ...} @args:
[...]
libclang callPackage ../common/clang (args // { });

? i'm not sure but would be nice to not have to manually keep the union of all llvmPackges_xx.xxx args in llvm/default.nix

@pwaller
Copy link
Contributor Author

pwaller commented Jun 16, 2024

can this be accomplished with a named attribute set argument?

Are you suggesting adding an overrides arg, and then doing llvmPackages.override { overrides.ncurses = ...; }? I suppose this would work, and allow overriding all the packages at once without needing to name all the args to all of the packages in the top level. If this was not what you were suggesting please write something more complete out so I can understand better.

I'm not sure how I feel about this. I would rather use the existing override mechanism than introduce yet-another-override pattern.

Another side effect of the PR as it stands is that it results in all of the dependencies being listed in the top level.

I note that the only harm of missing one out from the top level is that it cannot be overridden via llvmPackags.override, if someone discovers a need for it they can add it when the time comes.

@paparodeo
Copy link
Contributor

paparodeo commented Jun 16, 2024

can this be accomplished with a named attribute set argument?

Are you suggesting adding an overrides arg, and then doing llvmPackages.override { overrides.ncurses = ...; }?

no.

https://nix.dev/tutorials/nix-language.html#functions
https://nix.dev/tutorials/nix-language.html#named-attribute-set-argument

using a named attribute set argument should allow you to pass down the top level args to all the llvm submodules, i think.

in the top level llvm you'd use ellipses followed by @args. where args is the attribute set of all arguments including those not named which are contained in the ....

then when calling the subpackage the attribute set to callPackage is setup using (args // { patches = [ the patches ]; etc = something; }).

and the subpackage may need to be modified to take additional arguments so in libcxx say, you have to add an ellipses to the end of the argument set.

@pwaller
Copy link
Contributor Author

pwaller commented Jun 16, 2024

using a named attribute set argument should allow you to pass down the top level args to all the llvm submodules, i think.

This is already happening and I arranged it in #307211 exactly to allow this.

Unfortunately, if the argument is not named in the parameter set, you cannot .override it, you get an error:

error: function 'anonymous lambda' called with unexpected argument 'foo'

See for example nix eval -I nixpkgs=flake:nixpkgs --impure --expr '(import <nixpkgs> {}).llvmPackages.override { foo = 1; }'.

Therefore, I currently conclude it's necessary to specify the parameters which we want to be able to override as inputs to llvmPackages as this PR does.

@paparodeo
Copy link
Contributor

using a named attribute set argument should allow you to pass down the top level args to all the llvm submodules, i think.

This is already happening and I arranged it in #307211 exactly to allow this.

thanks. i didn't see the @args in the diff and my tree was not updated with the change.

Unfortunately, if the argument is not named in the parameter set, you cannot .override it, you get an error:

error: function 'anonymous lambda' called with unexpected argument 'foo'

See for example nix eval -I nixpkgs=flake:nixpkgs --impure --expr '(import <nixpkgs> {}).llvmPackages.override { foo = 1; }'.

so it doesn't seem like there are any ... in the llvm packge set. for example, if i do.

diff --git a/pkgs/development/compilers/llvm/12/default.nix b/pkgs/development/compilers/llvm/12/default.nix
index d3b823215c52..0c2267a68205 100644
--- a/pkgs/development/compilers/llvm/12/default.nix
+++ b/pkgs/development/compilers/llvm/12/default.nix
@@ -17,6 +17,7 @@
     then null
     else pkgs.bintools
 , darwin
+, ...
 }@args:
 
 let

i can run

nix-build -E 'with import ./. {}; llvmPackages_12.override { foo = 1; }'

just fine.

@pwaller
Copy link
Contributor Author

pwaller commented Jun 16, 2024

OK. Are you happy if I add , ... to this patch? That way it would be possible to override other things in the future should they be added, and the top level documents the arguments to all llvmPackages as they are today, at least.

@paparodeo
Copy link
Contributor

paparodeo commented Jun 16, 2024

OK. Are you happy if I add , ... to this patch? That way it would be possible to override other things in the future should they be added, and the top level documents the arguments to all llvmPackages as they are today, at least.

this makes sense to me as we don't have to manually adjust the top level arguments when the subpackages change. i'm not sure what the possible downsides are.
adding the top level ... and then the top level arguments can just include what is needed in the top-level default.nix

@pwaller
Copy link
Contributor Author

pwaller commented Jun 16, 2024

Thanks @paparodeo, I've added it as well.

... consistently.

Further to NixOS#307211, allow overriding arguments through llvmPackages.override.

This makes it possible to override any dependency of LLVM or
clang by overriding it on `llvmPackages.override { <dependency> = ...; }`.

This is useful in development or customization where sometimes it is
desirable to turn features on or off.

Without this patch the only way to for example override ncurses was to
do `overriddenLLVM = llvmPackages.llvm.override { ncurses }`, but then
you would have to thread `overriddenLLVM` as dependencies into clang and
other packages, which results in quite a difficult expression to write
correctly in cross compilation scenarios.

Signed-off-by: Peter Waller <[email protected]>
@pwaller pwaller changed the title llvmPackages_{12,13,14,15,16,17,18,git}: Pass dependencies consistently llvmPackages_{12,13,14,15,16,17,18,git}: Allow overriding dependencies Jun 16, 2024
@pwaller
Copy link
Contributor Author

pwaller commented Jun 16, 2024

Please note I won't have a chance to test this for a moment; I'm relying partially on the ofBorg package count rebuild result which should be zero and a good test. I'll also do a bit of testing over the coming days.

Copy link
Contributor

@paparodeo paparodeo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good. 0 builds for nixpkgs-review

Result of nixpkgs-review pr 320261 run on x86_64-linux 1

tried a few overrides and the correct things looked like they were being rebuilt.

$  nix-build -E 'with import ./. {}; llvmPackages_18.override { lua5_3 = lua5_3.overrideAttrs { foo =1; };}'
these 4 derivations will be built:
  /nix/store/z7vxw6cgh4gzhk5w44x90jnmml3ih0n4-utils.sh.drv
  /nix/store/784hhifl221ny531a8kzpbj3hmw7msdy-lua-5.3.6.drv
  /nix/store/n8sr8zdj4g3gxlmjqg85zhknb1s203fp-lldb-18.1.7.drv
  /nix/store/r7926xvs7abds7m2mjwrbyvy26g9nk6z-lldb-manpages-18.1.7.drv
$ nix-build -E 'with import ./. {}; llvmPackages_18.override { lit = lit.overrideAttrs { foo =1; };}'
these 4 derivations will be built:
  /nix/store/9zg056a72jkwrhvg2zz8yjpfp5751i0c-python3.11-lit-17.0.6.drv
  /nix/store/58qg67s9a06ci66r77sjsn8174i4s9zb-lldb-18.1.7.drv
  /nix/store/aizdk1y7ksv4pd93dwhd0kp43h4fk4d0-lldb-manpages-18.1.7.drv
  /nix/store/gp963g3pbn4a1z9fgxhaam2fiafnl6sm-openmp-18.1.7.drv

Copy link
Contributor

@philiptaron philiptaron left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes look good and consistent.

@wegank wegank added the 12.approvals: 3+ This PR was reviewed and approved by three or more reputable people label Jun 18, 2024
@Artturin Artturin merged commit 113b2b3 into NixOS:master Jun 20, 2024
26 checks passed
Copy link
Contributor

@pwaller pwaller deleted the llvm-pass-all-deps branch September 14, 2024 20:12
pwaller added a commit to pwaller/nixpkgs that referenced this pull request Sep 15, 2024
Pull NixOS#320261 introduced the possibility to consistently override
dependencies within an llvm package set. I think NixOS#325175 accidentally
dropped this, so reinstate it.

Signed-off-by: Peter Waller <[email protected]>
pwaller added a commit to pwaller/nixpkgs that referenced this pull request Sep 15, 2024
cmake flags have a 'last flag wins' logic, so by appending to the end of
the flags it is possible to override any cmake flag.

It also ignores (and warns) if a flag is unused, so passing flags across
all packages should be safe if you want to target one package.

In combination with NixOS#320261, this PR allows consistently overriding all
packages within LLVM with additional cmake arguments. Consistency here
means for example 'if you override LLVM, then all dependencies on it are
also see the overridden LLVM in their input'. Consistency is hard to
achieve with the other obvious way of implementing this as a user: if
you use overrideAttrs then you have to write a big mess of override code
in order to override all dependents, and this can be very difficult in a
cross-compilation scenario using crossSystem and useLLVM, for example.

With this PR it is possible to write an overlay which overlays
`llvmPackages` with `llvmPackage.override { devExtraCmakeFlags = [ ... ]; }`,
and then the toolchain used with useLLVM in effect should respect
these flags.

This is useful in development for experimenting with the effect of
various flags, hence the chosen name `devCmakeFlags`.

This won't work out of the box without NixOS#341855 applied, which fixes
override passthrough.

See-Also: NixOS#320261, NixOS#341855
Signed-off-by: Peter Waller <[email protected]>
pwaller added a commit to pwaller/nixpkgs that referenced this pull request Sep 15, 2024
Pull NixOS#320261 introduced the possibility to consistently override
dependencies within an llvm package set. I think NixOS#325175 accidentally
dropped this, so reinstate it.

Signed-off-by: Peter Waller <[email protected]>
pwaller added a commit to pwaller/nixpkgs that referenced this pull request Nov 10, 2024
Pull NixOS#320261 introduced the possibility to consistently override
dependencies within an llvm package set. This is useful for development
and testing exotic configurations.

Go one step further and enable overriding targetLlvmLibraries.

This makes it possible to write an overlay such as:

```nix
overlays = [
  (self: super: {
    llvmPackages = super.llvmPackages.override (prev: {
      targetLlvmLibraries = super.targetPackages.llvmPackages.libraries // {
        compiler-rt = super.targetPackages.llvmPackages.libraries.compiler-rt.override {
          ...
        }
      };
    });
  })
];
```

... where the overridden compiler-rt will be used in a pkgsLLVM build.

As a straw man, I've done the minimally invasive thing to the code
structure: `targetLlvmLibraries` is not an explicitly named parameter
for llvmPackages; but it is available in `packageSetArgs` if passed.
This makes it slightly less discoverable, but this seems like a
reasonable tradeoff considered that modifying this would be a fairly
advanced/esoteric thing to need to do.

In some ways it would be better to have as an explicit parameter with a
default, but the obvious thing won't work because the default needs to
be a non-trivial expression. Potentially we could instead have it as a
defaulted parameter with the value of 'null', and if it's null, then
compute the current thing.

Signed-off-by: Peter Waller <[email protected]>
pwaller added a commit to pwaller/nixpkgs that referenced this pull request Nov 10, 2024
Pull NixOS#320261 introduced the possibility to consistently override
dependencies within an llvm package set. This is useful for development
and testing exotic configurations.

Go one step further and enable overriding targetLlvmLibraries.

This makes it possible to write an overlay such as:

```nix
overlays = [
  (self: super: {
    llvmPackages = super.llvmPackages.override (prev: {
      targetLlvmLibraries = super.targetPackages.llvmPackages.libraries // {
        compiler-rt = super.targetPackages.llvmPackages.libraries.compiler-rt.override {
          ...
        }
      };
    });
  })
];
```

... where the overridden compiler-rt will be used in a pkgsLLVM build.

As a straw man, I've done the minimally invasive thing to the code
structure: `targetLlvmLibraries` is not an explicitly named parameter
for llvmPackages; but it is available in `packageSetArgs` if passed.
This makes it slightly less discoverable, but this seems like a
reasonable tradeoff considered that modifying this would be a fairly
advanced/esoteric thing to need to do.

In some ways it would be better to have as an explicit parameter with a
default, but the obvious thing won't work because the default needs to
be a non-trivial expression. Potentially we could instead have it as a
defaulted parameter with the value of 'null', and if it's null, then
compute the current thing.

Signed-off-by: Peter Waller <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
10.rebuild-darwin: 0 This PR does not cause any packages to rebuild on Darwin 10.rebuild-linux: 0 This PR does not cause any packages to rebuild on Linux 12.approvals: 3+ This PR was reviewed and approved by three or more reputable people backport release-24.05 Backport PR automatically
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants