runtime: source-build on unknown linux distros
For source-build we want to be able to build .NET using source-build on a system where the rid is not known to .NET.
We want this build to succeed, and the rid to be known to .NET.
For the build to succeed, we need to build using another rid which is known and compatible. I think this may be possible already (to some extent) by using the DOTNET_RUNTIME_ID envvar.
For the rid to be known to .NET, it needs to know its place in the graph.
Example pseudo build commands:
Build on Fedora 35 (rid derived from os-release is fedora.35):
./build.sh --build-rid linux --parent-rids fedora,linux
Build on RHEL 8 (rid derived from os-release is rhel.8):
./build.sh --build-rid linux --parent-rids linux
Build on CentOS 8 (rid derived from os-release is centos.8):
./build.sh --build-rid linux --parent-rids rhel.8,linux
Relates to https://github.com/NuGet/Home/issues/5862, https://github.com/dotnet/source-build/issues/297.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 28 (27 by maintainers)
I may be mistaken. It looks like the SDK did the work to pull out the runtime.json, bundle it in the SDK and provide it to NuGet. Thanks @dsplaisted, @nkolev92 https://github.com/NuGet/NuGet.Client/commit/04166a65cf687e1e62b756fd04385cf55c85863d https://github.com/dotnet/sdk/commit/27235895b381c762fe6597ceeb83b598d9012c2f
Assuming we flow the built content of Microsoft.NETCore.Platfroms from sourcebuild up through the SDK/installer then it looks like this should work. NuGet will “merge” the contents of the SDK’s runtimegraph with whatever is defined in packages. So even if someone added the public shipped platforms package it would still have your source-build defined RIDs.
This makes sense, we can easily add the ability to allow the source-build user to specify a new parent. I’ll add that to the current changes. I’m in the propcess of moving this over from dotnet/arcade to dotnet/runtime to make it easier to maintain. Next steps on my side are to finish this port and add it to the draft PR in dotnet runtime and move out of draft.
I was pointing to the existing property reads from
$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)which should derive it’s value from/etc/os-releasewith an override ofDOTNET_RUNTIME_ID.Here’s what I’m imagining the interface with the user. During a source build:
$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)in RID graphPackageRID|OutputRIDin RID graphAdditionalRIDspropertyAdditionalRIDsParentYeah, I’m actually preparing a draft PR right now. Should be available in a hour or so.
Infer was probably bad naming on my part: we infer the place in the graph but the RID is specified. There are already mechanisms today for determining what RID is being built. It can be specified or inferred. We leverage these rather than introducing anything new.
I’ve also added a property called InferRuntimeIdentifiers which can be use to add an arbitrary set of RIDs, where they belong, in the graph.
There is no guessing at parent, this follows the rules which are described in the checked in RuntimeGroups. So rather than let the caller specify a different hierarchy they add the new RID to the existing hierarchy where it belongs. As much as I can I’m trying to make it behave “as if” the change was checked into RuntimeGroups.props.
The above cases you describe should all work correctly. In those cases it looks like you’re trying to build the product as if it is a
linux-<arch>build but then also add RIDs to the graph for some new version of a known distro. In those cases you would need to specify theInferRuntimeIdentifiers(which I think is behaving like the--parent-ridscommand). So InferRuntimeIdentifiers=centos.10 would add centos.10 RIDs to the graph as if the change was made here, inheriting from rhel: https://github.com/dotnet/runtime/blob/366cd23a82fc44ea2c613c36bd4bfdbf8c310e56/src/libraries/Microsoft.NETCore.Platforms/pkg/runtimeGroups.props#L51-L57I think I’ll rename
InferRuntimeIdentifierstoAddRuntimeIdentifiers. I’ll also refine some of the tests in arcade to better illustrate how this is working. IWith what is proposed, both the first phase and second phase should work when the platform rid is not yet known. So I think this will work.
I don’t know how this would interact with the existing properties/parameters, and configurations. We need to figure that out.
When we use source-build there are two steps:
SourceBuildRid).TargetRid, e.g.fedora.32-x64) to generate a .NET installer for that system.We would like the tarball to be usable on a range of target distros. So, the tarball would target something common (
BuildRid, likelinux-x64).TargetRidcan be a unknown rid to .NET. As part of the build, .NET needs to learn how that rid connects to known rids (TargetRidGraph, e.g.fedora.32 -> fedora -> linux).For example. We run source-build on
linux-x64to generate a tarball that is usable onlinux-arm64, that is used onfedora.32-arm64, with rid graphfedora.32 -> fedora -> linux, gives us these values:TargetRidis calculated when building .NET. The other values can be specified.We don’t have a need to generate cross-target tarballs. So
SourceBuildRid = BuildRidfor our use-cases. We do want the source-build tarball to be usable on multiple platforms (TargetRidis compatible withBuildRid).@ericstj is it more clear?
cc @MichaelSimons @dleeapho @omajid
If it doesn’t work already, probably we can pick up
DOTNET_RUNTIME_IDin a few more places and avoid the complexity.