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

buildDotnetModule buildInputs depend on dotnet runtime packages for every possible platform #337030

Open
gbtb opened this issue Aug 24, 2024 · 12 comments

Comments

@gbtb
Copy link
Member

gbtb commented Aug 24, 2024

Describe the bug

Hello 👋
This line makes buildDotnetModule include every package from SDK runtime-collection into build-time closure. Basically, each time I want to tweak or update existing dotnet package, nix-build floods my terminal with a download list of stuff for platforms like macOS, win32, musl-linux and what not, even though I only care about linux-x64 platform.

I wonder what's a motivation behind this unconditional dependence? For one particular package I'm working on right now, removal of sdk runtime packages doesn't make a difference, it builds just fine. Probably that's because its deps.nix was already containing reference to Microsoft.NETCore.App.Runtime.linux-x64 . Searching for the 'Microsoft.NETCore.App.Runtime.linux-x64' inside nixpkgs also reveals several packages whose deps.nix contain explicit ref to a runtime. I wonder, maybe we can remove this runtime-collection from buildInputs altogether or hide it behind some flag?

Steps To Reproduce

Steps to reproduce the behavior:

  1. Try to tweak any dotnet-based package in nixpkgs

Expected behavior

nix-build should only download dotnet runtime packages for platforms that I build my dotnet package for.

Notify maintainers

@NixOS/dotnet

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

- system: `"x86_64-linux"`
 - host os: `Linux 6.8.12, NixOS, 24.11 (Vicuna), 24.11pre657537.5ad6a14c6bf0`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.5`
 - channels(root): `"home-manager, master.tar.gz, nixos"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

Add a 👍 reaction to issues you find important.

@gbtb gbtb changed the title buildDotnetModule buildInputs depends on dotnet runtime packages for every possible platform buildDotnetModule buildInputs depend on dotnet runtime packages for every possible platform Aug 24, 2024
@corngood
Copy link
Contributor

This is something that's on my radar. Currently the package set is meant to be 'everything that can be implicitly referenced from the SDK'. That can be useful, since it's possible to cross-target other RIDs, but is overkill in a lot of situations.

Fixing this should also help integrate the souce-built SDK, because we can pull in binary packages for cross targeting.

Ideally I'd like to solve this for both SDK packages and nugetDeps at the same time.

I wonder what's a motivation behind this unconditional dependence?

This is described in update.sh

    # Moving them to a separate list stored alongside the SDK package definitions,
    # and implicitly including them along in buildDotnetModule allows us
    # to make updating .NET SDK packages a lot easier - we now just update
    # the versions of these packages in one place, and all packages that
    # use buildDotnetModule continue building with the new .NET version without changes.

For one particular package I'm working on right now, removal of sdk runtime packages doesn't make a difference, it builds just fine. Probably that's because its deps.nix was already containing reference to Microsoft.NETCore.App.Runtime.linux-x64 . Searching for the 'Microsoft.NETCore.App.Runtime.linux-x64' inside nixpkgs also reveals several packages whose deps.nix contain explicit ref to a runtime.

These explicit references are also bad, for the same reason.

@YoshiRulz
Copy link
Contributor

YoshiRulz commented Sep 12, 2024

I believe this is the same issue I brought up in #179136 (comment), where I also suggested unsafeDiscardStringContext, and the response was that it was impossible to fix.

@gbtb
Copy link
Member Author

gbtb commented Sep 19, 2024

Okay, I thought about current state of affairs and have several observations:

  1. During first-time creation or update of deps.nix file we don't need any of dotnet-sdk.packages
  2. Inside of deps.nix after it's been created, we will have all really required runtime packages with a fixed version, and that might be what people actually want for some usecases.
  3. But for a generic dotnet package inside nixpkgs current behavior of simplified mass-update of all packages is convenient.

What we can do with all those points above?

  1. We can add an argument to a buildDotnetModule - e.g. useSharedSdkPackages with options:
    1. UseDepsOnly - which means that package strictly uses it's deps.nix .
    2. OverrideDeps - which means that we find inside deps.nix all packages that are present in dotnet-sdk.packages and set minor.patch version to match what's inside dotnet-sdk.packages.
    3. AddAll - which means that all of the dotnet-sdk.packages will be appended (current behavior)
  2. In order to simplify an implementation of option 1.2, we should change a format of deps.nix file and make it a plain list of attrsets instead of a function with what is essentially a manually unrolled map over a list of attrsets. With a list of attrsets we can use a simple groupBy pname to make a lookup dictionary.
  3. We should set this new option to OverrideDeps by default. For fetch-deps we will always use UseDepsOnly mode .

What do you think?

@corngood
Copy link
Contributor

The first thing that comes to mind is that I think we should always prefer packages from nixpkgs. For example, if you're building with the source-built SDK, you should have the source-built packages that go along with it, even if they have the same version as something on nuget.org. I think this could be important in the future, because we may want to patch the sdk to be more nix-friendly. It may also be important if people care about meta.sourceProvenance.

What you're describing would mostly not interfere with that, except for during fetch-deps, when it would (if I understand correctly) be required to pull packages from nuget.org.

I think I'd prefer to explicitly limit the packages pulled in from sdk.packages, if the goal is to reduce build closure size.

Is closure size in fetch-deps even a concern? If a package supports all possible platforms (x86/arm*linux/darwin), then it's going to be pulling a lot of stuff from nuget.org that it currently gets from sdk.packages. That could end up being a lot slower.

@YoshiRulz
Copy link
Contributor

I don't think that rundeps should be unconditionally added to any packages, regardless of whether they're part of Nixpkgs. It goes against the idea of only depending on the derivations that are actually used/referenced (a la strictDeps).

re: closure size, at least it respects meta.platforms. Though when that's omitted it falls back to the full set that the SDK supports.
If at all possible, I'd prefer that foreign arch packages were never downloaded unless cross-compiling.

@gbtb
Copy link
Member Author

gbtb commented Sep 19, 2024

The first thing that comes to mind is that I think we should always prefer packages from nixpkgs.

As a base default for the nixpkgs - sure thing.

you should have the source-built packages that go along with it

That would be the behavior of OverrideDeps I'm proposing - we identify inside a deps.nix that a package depends on say, Microsoft.AspNetCore.App.Ref-8.0.1 from nuget.org for whatever reason, and then we override it during build with our source-built Microsoft.AspNetCore.App.Ref-8.0.8 .

Is closure size in fetch-deps even a concern?

It's a matter of perspective and specific usecases. If you have an unlimited optical line and 1TB SSD, this level of overhead might not be concerning. If you're are on a laptop with a metered mobile connection and limited disk space - it gets concerning IMO. Especially, if you can clearly see that half of what you're downloading is just useless.
Here is an example HelloWorld dotnet 8 app that targets linux-x86_64 only with a flake.nix . And here is what gets downloaded when you try to initialize deps.nix file -

Shell output

[artem@lenovo-nixos:/crucial/Projects/ConsoleApp]$ nix build .#default.fetch-deps
warning: Git tree '/crucial/Projects/ConsoleApp' is dirty

[artem@lenovo-nixos:/crucial/Projects/ConsoleApp]$ ./result 
fetching dependencies for hello-0.0.1
this derivation will be built:
  /nix/store/23x9npjmpahlij1ycby5jcsg3njq948n-dotnet-sdk-8.0.401-deps-nuget-deps.drv
these 99 paths will be fetched (710.29 MiB download, 3085.89 MiB unpacked):
  /nix/store/ibqfibyiad4vqssbxhcfql46qk6v8sb7-Microsoft.AspNetCore.App.Ref-8.0.8
  /nix/store/i2xrq1hcijj8r5bk1m8mw3f4bk944kwh-Microsoft.AspNetCore.App.Runtime.linux-arm-8.0.8
  /nix/store/d1bk8pbk41ljdj6aqmk65iq00g953rbw-Microsoft.AspNetCore.App.Runtime.linux-musl-arm-8.0.8
  /nix/store/iqf1i440vxmxfn7x024cqbxkb13ij1l4-Microsoft.AspNetCore.App.Runtime.linux-musl-arm64-8.0.8
  /nix/store/mi0wgpxm6nbx687xvli2lbsznkn99r8i-Microsoft.AspNetCore.App.Runtime.linux-musl-x64-8.0.8
  /nix/store/iqc56y6dq5m3s4m8kf078v0klj517zs8-Microsoft.AspNetCore.App.Runtime.win-arm64-8.0.8
  /nix/store/613dp1mm36ghgj2b8pgql27pdhbsxzc3-Microsoft.AspNetCore.App.Runtime.win-x64-8.0.8
  /nix/store/j546s29vwj1p2fnaw2nwv8gngg5z35nl-Microsoft.AspNetCore.App.Runtime.win-x86-8.0.8
  /nix/store/h2vx0nbsg5cy51980y6358iawr4gxkjn-Microsoft.NET.ILLink.Tasks-8.0.8
  /nix/store/bvbwbjh7v1f4ihy5ywrd5ym45dbhwvy7-Microsoft.NETCore.App.Crossgen2.linux-arm-8.0.8
  /nix/store/yq1x32kh15kwk4i3jmxfjd3jmc1hf3sq-Microsoft.NETCore.App.Crossgen2.linux-arm64-8.0.8
  /nix/store/38p7jlwd36qb3rzlf3h72r5j8q2hs657-Microsoft.NETCore.App.Crossgen2.linux-musl-arm-8.0.8
  /nix/store/rlkaa8a9rwdvxk6hi1kv1ylif1x2rm93-Microsoft.NETCore.App.Crossgen2.linux-musl-arm64-8.0.8
  /nix/store/5jvbz6ihjzi30bs88kxqynbdv8sa2psl-Microsoft.NETCore.App.Crossgen2.linux-musl-x64-8.0.8
  /nix/store/a6lismdwjvydm24jb4bpmdjdwq0ba3bs-Microsoft.NETCore.App.Crossgen2.linux-x64-8.0.8
  /nix/store/bhij2xdiq7rrgdnawyz2c0g4c9kr2drz-Microsoft.NETCore.App.Crossgen2.osx-arm64-8.0.8
  /nix/store/dk3agh6sga1wzjcld42ihbbshzqjhm8l-Microsoft.NETCore.App.Crossgen2.osx-x64-8.0.8
  /nix/store/9kvfljx01z3h7py75hj7yarcsrn5bcjd-Microsoft.NETCore.App.Host.linux-arm-8.0.8
  /nix/store/21g2lvg66mj2x3ljk32nxcamrhrddgc8-Microsoft.NETCore.App.Host.linux-musl-arm-8.0.8
  /nix/store/09s62pjphp85jm901a1rcdgi08dr8n9r-Microsoft.NETCore.App.Host.linux-musl-arm64-8.0.8
  /nix/store/8md0mmamm029lkh6nj3dihh7q8ysnfzn-Microsoft.NETCore.App.Host.linux-musl-x64-8.0.8
  /nix/store/wxghjnx0cirzigypkxv4fsa3cbpi01hx-Microsoft.NETCore.App.Host.linux-x64-8.0.8
  /nix/store/347x43wkjhr3jay6953d02nbr2hxw6wh-Microsoft.NETCore.App.Host.win-arm64-8.0.8
  /nix/store/7f7kgf18pqvwkwdf8h8pji1775sdnl0w-Microsoft.NETCore.App.Host.win-x64-8.0.8
  /nix/store/097v34jhgpkfj9nxjx7d7yhyslgw121c-Microsoft.NETCore.App.Host.win-x86-8.0.8
  /nix/store/x0ckfkigfw078qgbrcfxy2brhbhqqgsm-Microsoft.NETCore.App.Ref-8.0.8
  /nix/store/1m1dwh2v6v5bbavhbxkc1nqnfy4qvcyp-Microsoft.NETCore.App.Runtime.Mono.linux-arm-8.0.8
  /nix/store/9sfx6j4zdgscmqmriamq3xny02dbdif7-Microsoft.NETCore.App.Runtime.Mono.linux-arm64-8.0.8
  /nix/store/f3lrv5fiz7zn06g7zhq7ckxzv7bp3hzr-Microsoft.NETCore.App.Runtime.Mono.linux-musl-x64-8.0.8
  /nix/store/ccdwyyfdqrq11wg6zk0i55a5ylzw9bqc-Microsoft.NETCore.App.Runtime.Mono.linux-x64-8.0.8
  /nix/store/01l3740mk8rk2m0wq8x4lv7hliimphyf-Microsoft.NETCore.App.Runtime.Mono.osx-arm64-8.0.8
  /nix/store/qj09zlxjw1l56dh93m01dc6pr4j53z9z-Microsoft.NETCore.App.Runtime.Mono.osx-x64-8.0.8
  /nix/store/gv039kb9c440dp1kml19zj48w57maarc-Microsoft.NETCore.App.Runtime.Mono.win-x64-8.0.8
  /nix/store/bs64n77p7mlqiqywddfhc77x8513y2pp-Microsoft.NETCore.App.Runtime.Mono.win-x86-8.0.8
  /nix/store/qkhfp3s1p56pma4lhb4251i4cv1mxjyz-Microsoft.NETCore.App.Runtime.linux-arm-8.0.8
  /nix/store/rqhvfcnjkzhkqa373jbmmvm7xlvr141x-Microsoft.NETCore.App.Runtime.linux-musl-arm-8.0.8
  /nix/store/z0vg6kgym4rfg5m4ph6048ddk1x4jl72-Microsoft.NETCore.App.Runtime.linux-musl-arm64-8.0.8
  /nix/store/kls2cwqs7626cij40mb27cpx8h21lvnl-Microsoft.NETCore.App.Runtime.linux-musl-x64-8.0.8
  /nix/store/n56jjvkw6k3xvybwn8r00pb624dcxwi6-Microsoft.NETCore.App.Runtime.win-arm64-8.0.8
  /nix/store/vj4w19rh3wk3aw9mk8g6rdsm669j4hlb-Microsoft.NETCore.App.Runtime.win-x64-8.0.8
  /nix/store/b9zhscl4h8nw446gcld3jhs82n377rkp-Microsoft.NETCore.App.Runtime.win-x86-8.0.8
  /nix/store/65dm893a1bdq6ih6whajqmwgi46xgz8n-Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/q31ds283pznd71fhniwgs6sm913sbbll-Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/14v3ipncmdgb77npvn9hh4xdcry2d0sr-Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/qmghm6grzgz5xx152lb7202ny06dzxy4-Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/4nc5d2wah7clnxjyxzrambq0q6j61i54-dotnet-fixup-hook
  /nix/store/x69w5jkay6c8kqfgr6g54qn58v3ngl1p-dotnet-runtime-6.0.33
  /nix/store/d087nqkkng15mswq446klw37472mgc6w-runtime.linux-arm.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/3bwraxshrxxnrrvnx5raah23i9n85j1q-runtime.linux-arm.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/y3cwx3214w6x69h70b43bp7x455asacp-runtime.linux-arm.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/03bqzd5rlykva10smmg8gb4gnq3qqizp-runtime.linux-arm.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/if6ljslwhy89xhcmdfcgwdpmlnw5h1m9-runtime.linux-arm64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/1wviypjnl5k9da964r7kmz7frdya26lw-runtime.linux-arm64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/19lb2vwrgzzyhyjyl2173d6wf1mjynn9-runtime.linux-arm64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/dclhjn0ankrkm5l0svhllvzifbqqx2wc-runtime.linux-arm64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/mh2rbqpc83f7m40cqjc54labwsizbzir-runtime.linux-arm64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/0i2n60q2wqngm7xgbmwa26yxmc30n16n-runtime.linux-musl-arm.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/x4ljh1zy8viv4r9r54c3iidpihznar9w-runtime.linux-musl-arm.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/a74v8nx05h81a68774wkzlir8hmfyyks-runtime.linux-musl-arm.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/182dcf6xhhqcz6gyzlrj0c7dsjcswyd2-runtime.linux-musl-arm.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/pxlmbhm0nrracihf25h12p7zmpmcwvmk-runtime.linux-musl-arm64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/8kq9sspx1q74ms3i24shiw6cgikv3zsp-runtime.linux-musl-arm64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/5jw41fkdzwb1yq8la6n5rivqdssbhsiz-runtime.linux-musl-arm64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/s1zm5s1w4d0g50aqnbq7lqyi5i38xg81-runtime.linux-musl-arm64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/jd695rqniicayrarhcmj14hp0r0s6yix-runtime.linux-musl-arm64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/0z3jqks9rv5g7hiq03nz4m872mvinv33-runtime.linux-musl-x64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/kawbm253981swrzs4i7h2ycp8rghwhg9-runtime.linux-musl-x64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/d8k3353bxgrh4r8a62329dp2dxjghfli-runtime.linux-musl-x64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/zgy706zld1n9xnjv0k330zps6rbfx8hi-runtime.linux-musl-x64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/i7l6dn4zk8c29n3isx1047wmsg6jlkq6-runtime.linux-musl-x64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/k89cslyi2k9v8zgqxi4yhf3yb0nhs9i1-runtime.linux-x64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/jrhz9abl68hhl793p8p5msav4jh8nmjh-runtime.linux-x64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/9jdx53al3dk61zdplrj529k411rfp1l9-runtime.linux-x64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/zm2wn9k1yqlirkz6xn0kpb6xvbxzff53-runtime.linux-x64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/i9kanxpryynknj91b69sxsgd9qj3yjdj-runtime.linux-x64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/67vg0xpb0k8bw7lcw9sca68x0s3m2x0a-runtime.osx-arm64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/dxf362nbxi9g3jw1fsl30na6bn3wvsgz-runtime.osx-arm64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/iniyhg0s60n8k3vib3ng8x52l3lj4hiy-runtime.osx-arm64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/p7qn3bsjpykvw4v8b2fbpc5y01ih4vb7-runtime.osx-arm64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/lxm9plhkzjgm3qfi3npccwc7x21pfyfr-runtime.osx-arm64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/l2ki8gq1qlpp9rwy673nh4qy6sa1j9j0-runtime.osx-x64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/fvl7xshzkmlrdgd6jxxj5k38hkyq4v42-runtime.osx-x64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/dwmivnl0gbi4vnwabffw7n0kz7wfm7jy-runtime.osx-x64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/a83qa7lkm6srvlkyhww6flifpm76cg57-runtime.osx-x64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/9h38azjlzj480qj4jwxyzv063icjb8r7-runtime.osx-x64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/1n28k0p02lm67x3jhhg1jprk54r1spj5-runtime.win-arm64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/b0gd5c8y6698kshkgy0dawj3n1r7v6dz-runtime.win-arm64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/czih0mgvk2q88j1qvi3f8anzb38yzxhq-runtime.win-arm64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/4ibm9nqa5xdd2z8j0hrndy26j527wbn1-runtime.win-arm64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/3ca5a3wffr6y129b0q1xw076rdjyppgq-runtime.win-arm64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/aqq6a5r775nfh98fzjjy683myjws9ngq-runtime.win-x64.Microsoft.DotNet.ILCompiler-8.0.8
  /nix/store/n09ysmwmvf2ipk1s4l48bgv63i6jkshn-runtime.win-x64.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/69p44lr86ljkw2kg6hhj6hmwpyj33b0a-runtime.win-x64.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/479blslxgkxkamdahjmdjn58klswq2vw-runtime.win-x64.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/a57wgm6bk6kgkls9whgky62kx8hx3dmk-runtime.win-x64.Microsoft.NETCore.DotNetHostResolver-8.0.8
  /nix/store/gcb3lx0xyd3hhy9x748b702xinw2rav4-runtime.win-x86.Microsoft.NETCore.DotNetAppHost-8.0.8
  /nix/store/v4kg5x99k1r3hn64kzhrqzvdiifvjx6b-runtime.win-x86.Microsoft.NETCore.DotNetHost-8.0.8
  /nix/store/jlld9b0parzjsh90ihimsji3ps3sqa9q-runtime.win-x86.Microsoft.NETCore.DotNetHostPolicy-8.0.8
  /nix/store/dq7hxc3pvcyjm197fhpifl8qicraa70y-runtime.win-x86.Microsoft.NETCore.DotNetHostResolver-8.0.8

This gets multiplied by a number of relevant sdk (for example, fsautocomplete uses dotnet sdks from 6 to 8). If you maintain some dotnet project in a flake, you eventually will desync with your <nixpkgs> and you'll get another copy of those dependencies, and so on, and so forth.

except for during fetch-deps, when it would (if I understand correctly) be required to pull packages from nuget.org

Isn't it always the case now, especially during initial creation of of deps.nix file?
What I'm suggesting with regards to fetch-deps, is to don't require by default all of sdk.packages to be present.

@corngood
Copy link
Contributor

What if we start by making something like dotnet-sdk.packages.${targetPlatform.system}? We can map it using the same platforms we put in dotnetRuntimeIds.

In that case it'll need to pull in everything when doing fetch-deps (assuming the target supports all platforms), but for a build it'll only pull in one.

We could limit it further by having packages opt-in to AOT support, but that might be overkill.

@MattSturgeon
Copy link
Contributor

2. In order to simplify an implementation of option 1.2, we should change a format of deps.nix file and make it a plain list of attrsets instead of a function with what is essentially a manually unrolled map over a list of attrsets. With a list of attrsets we can use a simple groupBy pname to make a lookup dictionary.

This isn't central to the issue being discussed, but if such a refactor is done it should tie in with #325053 by either using a JSON deps file and lib.importJSON, or by using a structure that works well with nixfmt-rfc-style.

@corngood
Copy link
Contributor

What if we start by making something like dotnet-sdk.packages.${targetPlatform.system}? We can map it using the same platforms we put in dotnetRuntimeIds.

I started working on this. What I have so far is dotnet-sdk.packages provides only the packages for the sdk host/target platforms, but we also provide dotnet-sdk.targetPackages.${rid} to make all the others available for restore etc.

Unfortunately I've found that some downstream projects were depending on restoring packages for runtimes we aren't targeting. For example, ArchiSteamFarm restores the win-x64 runtime host (and several others) during build for linux-x64.

I'm going to take a look at fixing this in the projects, but I may have to add an escape hatch that brings in all the packages.

@GGG-KILLER
Copy link
Contributor

GGG-KILLER commented Sep 21, 2024

@corngood instead of splitting packages per rid, couldn't we restructure deps.nix in such a way that it only gets what it needs from dotnet-sdk.packages?

Maybe something like making fetchNuget that is passed to deps.nix first look at dotnet-sdk.packages and only then falling back to nuget.org (or wherever the package is hosted on)?
With this we could even potentially expand it to look for any nugget in nixpkgs in the future

@corngood
Copy link
Contributor

@GGG-KILLER The problem I see with that is that it's always going to be dependent on nuget.org if you build deps.nix using references to things from nuget.org. I'd like to at least have the option of packaging things without dependence on binary blobs.

Something we could potentially do to avoid that is figure out which packages are actually required from the sdk packages during fetch-deps. We'd probably have to disable NUGET_FALLBACK_PACKAGES and teach nuget-to-nix to write out information about packages that come from nixpkgs.

Is it worth it though? Here's what we're left with after cleaning things up (I stripped out everything except linux-x64):

  commonPackages = [
    (fetchNupkg { pname = "Microsoft.AspNetCore.App.Ref"; version = "8.0.8"; hash = "sha256-5iWiiKBaB6V5x3GDvZ1DpyxDHFIsmewksoeIizz8Z7k="; })
      (fetchNupkg { pname = "Microsoft.NETCore.DotNetAppHost"; version = "8.0.8"; hash = "sha256-2KBKkVUlpiO1bOY+Ia2PKjurY2taV7CHnzU7Jr5HYUs="; })
      (fetchNupkg { pname = "Microsoft.NETCore.App.Ref"; version = "8.0.8"; hash = "sha256-3x7ltOqJJXYO+zHIIvH1SDEz9fTrHqNoyK68teiHGZQ="; })
      (fetchNupkg { pname = "Microsoft.NETCore.DotNetHost"; version = "8.0.8"; hash = "sha256-ZGunPQaL6Kz97BpQY9lSOPEsy1CvZiTZeidqnG18anw="; })
      (fetchNupkg { pname = "Microsoft.NETCore.DotNetHostPolicy"; version = "8.0.8"; hash = "sha256-x45oE7EFl6V29tVnuvzfcnAufOQjVf8FYxG8TSNz77k="; })
      (fetchNupkg { pname = "Microsoft.NETCore.DotNetHostResolver"; version = "8.0.8"; hash = "sha256-UHKTFAfqIxoBZ38I6wBdMNA6NyQ4FhSJcHNQZxjaCu4="; })
      (fetchNupkg { pname = "Microsoft.DotNet.ILCompiler"; version = "8.0.8"; hash = "sha256-KmiA+uHHYOnsfdG3F20mu0XllcRxEvMvWkHz7vK39KQ="; })
      (fetchNupkg { pname = "Microsoft.NET.ILLink.Tasks"; version = "8.0.8"; hash = "sha256-st7UdPx9AFKf9o6WewsmUKhbP2IG2KQjHRCTdP4Vj00="; })
  ];

  hostPackages = {
    linux-x64 = [
      (fetchNupkg { pname = "Microsoft.NETCore.App.Crossgen2.linux-x64"; version = "8.0.8"; hash = "sha256-MJmQmBHWgvsqO8XYLnqsyUTfQ72VeJ/3EHq6OHtZ+n8="; })
      (fetchNupkg { pname = "runtime.linux-x64.Microsoft.DotNet.ILCompiler"; version = "8.0.8"; hash = "sha256-dmtcy7cqijoJAUCEJTNcvqaRneRMCn7WJkurjk2YpN8="; })
    ];
  };

  targetPackages = {
    linux-x64 = [
      (fetchNupkg { pname = "Microsoft.AspNetCore.App.Runtime.linux-x64"; version = "8.0.8"; hash = "sha256-/9Hsru4pLWKMb2LTF1erdHILGdEc/2NnuTIG+dcf1jY="; })
      (fetchNupkg { pname = "Microsoft.NETCore.App.Host.linux-x64"; version = "8.0.8"; hash = "sha256-Leqb/Un4/GRgRcymCJWnPhjZCn8A2hl4nFdYJfkNdqs="; })
      (fetchNupkg { pname = "Microsoft.NETCore.App.Runtime.linux-x64"; version = "8.0.8"; hash = "sha256-y5IbKOkqAKBpyWiA0PFmrtVXGXsWLHvX2FsiICm6egU="; })
      (fetchNupkg { pname = "runtime.linux-x64.Microsoft.NETCore.DotNetAppHost"; version = "8.0.8"; hash = "sha256-Ls2+jcDC4FW9zO81O2JP6BtKeazhydWEiXBPg/GJsfw="; })
      (fetchNupkg { pname = "runtime.linux-x64.Microsoft.NETCore.DotNetHost"; version = "8.0.8"; hash = "sha256-jJ7jGIYzDYqBZzJEG3BwS+NqUv7o7tRxUNgOTQ0oFSs="; })
      (fetchNupkg { pname = "runtime.linux-x64.Microsoft.NETCore.DotNetHostPolicy"; version = "8.0.8"; hash = "sha256-SCj9QjWOJvv3TvlR0TpIyFZrebRFTkVFVPdQ82F08gQ="; })
      (fetchNupkg { pname = "runtime.linux-x64.Microsoft.NETCore.DotNetHostResolver"; version = "8.0.8"; hash = "sha256-LbvKpuOg1Rdqtabz1UvoADiNOkh+phBdXcD9iBGAAD0="; })
      (fetchNupkg { pname = "Microsoft.NETCore.App.Runtime.Mono.linux-x64"; version = "8.0.8"; hash = "sha256-TwTvStZ7PMGpFh16lSI4iAJwDz/lnJkqHk/RQ0KEQB0="; })
    ];
  };

@corngood
Copy link
Contributor

#343837 Has my work so far on this, in case anyone is able to review.

I think the next step might be to look at fetch-deps and try to split out platform-specific dependencies there too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants