-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
source-build on unknown linux distros #48507
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Thanks for filing this issue, @tmds ! I think this captures our issues with RID well: we just need a way for a random Linux distro to get an RID automatically, and assign some parents RIDs (mostly |
Tagging subscribers to this area: @ViktorHofer Issue DetailsFor 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 on RHEL 8 (rid derived from os-release is rhel.8):
Build on CentOS 8 (rid derived from os-release is centos.8):
Relates to NuGet/Home#5862, dotnet/source-build#297.
|
It would be good to understand if this is sufficient or if you would also need to modify the shared-framework's deps file (where the RID fallbacks live) in the tool shared framework. Doing the latter is possible but grows the complexity of this. runtime/src/libraries/Microsoft.NETCore.Platforms/pkg/runtimeGroups.props Lines 248 to 258 in 09a1256
|
Also, once you produce such a shared framework, are you OK with nuget restore not knowing about? NuGet still gets the runtimegraph from the Micrsoft.NETCore.Platforms package which the user's package graph brings down. This is what is used for resolving and publishing self-contained apps. |
Is there a fallback here? To something like
Does that mean self-contained apps wont build/work? What about normal Framework-Dependent apps? |
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 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. |
If it doesn't work already, probably we can pick up |
@tmds can you better specify the inputs of what you'd like to see happen? Describe what needs to be specified, vs what is calculated from the system, and how that is used by the build system. Also talk about how things interact with existing properties / parameters to the build Interesting considerations:
|
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:
We would like the tarball to be usable on a range of target distros. So, the tarball would target something common (
For example. We run source-build on
We don't have a need to generate cross-target tarballs. So @ericstj is it more clear? |
So this means that the tarball cannot have a single RID burned in, it should either have many or we should delay the RID generation until the second phase. I'd prefer the latter since it supports any hypothetical RID we already have a way to "burn in" RIDs: commit to source. Do you need these distros to "know" about the others. For instance do you (or your customers) need to build a self-contained application that targets Can you think about this one:
Are any of new RIDs drastically new, or can you imagine them being covered by this logic: Lines 12 to 21 in a4c765d
|
Can you clarify what you mean by "configurations" here? Is it Release/Debug? Whether to use bundled libraries? Or My understanding is that source-build provides separate general ways to control this, separate from the exact RID computation/graph-patching. For example, there's generic logic to use System libraries: And can even set up more specific build tweaks at build-time: IMO, that seems to work fine. We could implicitly infer that an RID of |
The general workflow for a Linux distribution like Fedora (also true for RHEL) - aside from bootstrapping - is that we always/only build on the exact same RID as the target one, both in terms of distro name and architecture. There's one additional wrench worth considering, though: what if the system's RID changes. This happens during OS development: a distribution may identify itself as "fedora.35-x64", then it would get branched off and identify itself as "fedora.36-x64" without any other changes in libraries, packages or tools. If we can build .NET just before the RID change, we want to be able to take the SDK we just built and use it to build something just after the RID change. This scenario currently works, but we are adding to the RID graph via source-build, AFAIK. |
Sorry, I should avoid the old jargon. I'm talking about how we resolve against the TargetFramework strings (which were previously encoding in Configuration values). We have a separate smaller mapping of compatible TargetOS values that could need to change for new OSes: https://github.com/dotnet/runtime/blob/main/src/libraries/OSGroups.json From what I see in this discussion I'm in agreement that we can leave this stuff alone and assume it will just work for the case we're examining.
I think it mostly works, but if you change the RID after you build .NET then I wouldn't expect the RID graph to "know" about that RID. Do you have an example of this, can you point me to the bits that were built on the previous RID then used on the new one? Examine the Microsoft.NETCore.App.deps.json in the shared framework and the RuntimeIdentifierGraph.json in the SDK. Do these understand your new RID? If not then some things won't work (self-contained app targeting new RID, framework dependent app selecting rid-specific assets at runtime).
I'm not sure we want to allow ad-hoc parenting rules. All this information already exists in https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.NETCore.Platforms/pkg/runtimeGroups.props I'll put up a PR in arcade that I think can facilitate the type of additions I describe above and will share it here. |
I agree, RID generation should be in the second phase.
I also see no strong need for this.
We need to do it in the second phase.
I don't expect us to get in that situation. When I upgrade from Fedora 32 to 33, that will change my system rid, but I should also receive updated
I'm fine if we can specify a single parent. Distros can be added in the upstream dotnet/runtime repo. |
This package was built for Fedora 34: https://koji.fedoraproject.org/koji/buildinfo?buildID=1696922 The RID changed and trying to build the next .NET SDK patch release using that build failed: https://koji.fedoraproject.org/koji/buildinfo?buildID=1708626 But it worked with a hack here: https://koji.fedoraproject.org/koji/buildinfo?buildID=1711461. We didn't patch the SDK we were using to build, just the one we are building. We know something built with the
Here's a dockerfile that shows the 2 SDKs and their graphs: FROM fedora:33
RUN dnf install --setopt tsflags=nodocs --refresh -y \
fedora-packager \
tar \
wget \
which && \
dnf clean all -y
RUN mkdir f34-build && \
cd f34-build && \
koji download-build -a x86_64 dotnet5.0-5.0.102-2.fc34 && \
for r in *; do rpm2cpio "$r" | cpio -id; done
RUN mkdir f35-build && \
cd f35-build && \
koji download-build -a x86_64 dotnet5.0-5.0.103-2.fc35 && \
for r in *; do rpm2cpio "$r" | cpio -id; done
CMD find \( -iname 'Microsoft.NETCore.App.deps.json' -or -iname 'RuntimeIdentifierGraph.json' \) -exec echo {} \; -exec cat {} \; 2>/dev/null
Unfortunately, as packagers of source-build, we encounter this once every Fedora (or any other distro, I suspect) release. We build a package, at some point after our build, Fedora's development branch changes it's version (eg, 34 -> 35). We then have to use the last build to build the next one. Users shouldn't get to see it - unless they are running the development branch - but we, packagers, will. |
With 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. |
@ericstj are you, or is someone else looking at this? |
Yeah, I'm actually preparing a draft PR right now. Should be available in a hour or so. |
FYI: draft PR #50157 Please review user experience here to make sure it meets your needs. |
If I understand the PRs correctly, they infer the current OS's RID, guess the parent RID, and add the current RID to the RID graph (if missing). Going back to the initial examples:
The
Same?
This wouldn't work, would it? It will say |
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
I think I'll rename |
The Independent of the |
Who's going to compute the correct parent? The end user who's running the source build? Might you need to add more than one? Supporting this is pretty trivial: I added a sample here that assumes
I see, I was making the default be the RID of the Packages we build I can change that to the computed RID (though the OutputRID is also derived from the computed RID). I think it's very important to be crisp about the purpose of these properties: we have a number of different RID values in the system already and adding new ones is going to cause confusion and misuse. Today the "computed" RID is retrieved here: Line 103 in 6496624
Is this the value you'd prefer to be the default?
I believe this should work correctly. Lines 24 to 30 in 6496624
|
The source-build user could specify it. It would be a single value.
Yes, this is a scenario we don't need for the distros we target.
It's not clear for me what the differences are between these rids. When we build the source-build tarball, then the output packages would be for the rid of Now when we run source-build to create the tarball, we'd like to be able to create a tarball that works across a range of |
@ericstj does the rid logic make sense?
As future steps, this tarball could be the output of source-build, produced by Microsoft. The tarball can be compiled with a pre-built SDK from Microsoft. Or with an SDK that was already source-build compiled for a previous patch version, or for a previous (compatible) version of the distro. |
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 Here's what I'm imagining the interface with the user. During a source build:
|
This sounds good to me. When we say build, we need to think about two different builds:
For our use-cases. The first build is for |
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 on RHEL 8 (rid derived from os-release is rhel.8):
Build on CentOS 8 (rid derived from os-release is centos.8):
Relates to NuGet/Home#5862, dotnet/source-build#297.
cc @ericstj @omajid @crummel
The text was updated successfully, but these errors were encountered: