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

Add --use-current-runtime option #14093

Merged
merged 4 commits into from
Oct 21, 2020

Conversation

am11
Copy link
Member

@am11 am11 commented Oct 10, 2020

It is a common use-case to use the same runtime during the build and publish. During the development of .NET apps, it is painful to remember the entire - ever growing - --runtime <baseos>-<arch> matrix.

--use-current-runtime, backed by MSBuild property UseCurrentRuntimeIdentifier=True/False, will allow users to keep things neutral in their documentation and deployment scripts.

Fixes #10449
cc @eerhardt @tmds, @dagood

@dagood
Copy link
Member

dagood commented Oct 12, 2020

It has been just over a year since the last comment on #10449, so perhaps worth double checking that this is still valid in 6.0, but it does seem useful to me.

I think @wli3 and @dsplaisted would be the best reviewers for this PR.

Copy link
Member

@dsplaisted dsplaisted left a comment

Choose a reason for hiding this comment

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

Thanks for this!

  • I would prefer calling the switch something like --use-current-runtime over --infer-runtime. @KathleenDollard, thoughts?
  • I would also prefer having this implemented in MSBuild logic. IE setting UseCurrentRuntimeIdentifier to true would set the RuntimeIdentifier property to the current RID (possibly via the NETCoreSdkRuntimeIdentifier property). Then the --use-current-runtme command-line option would set UseCurrentRuntimeIdentifier to true, but the property could also be used outside of the dotnet command line.

@am11 am11 force-pushed the feature/add_--infer-runtime_options branch from 95a7343 to ebc5ea2 Compare October 12, 2020 22:36
@am11 am11 changed the title Add --infer-runtime option Add --use-current-runtime option Oct 12, 2020
@am11
Copy link
Member Author

am11 commented Oct 12, 2020

@dsplaisted, thanks. I have updated the PR with --use-current-runtime and UseCurrentRuntimeIdentifier changes.

@am11 am11 force-pushed the feature/add_--infer-runtime_options branch from ebc5ea2 to 52dfbb6 Compare October 12, 2020 22:54
Copy link
Member

@dsplaisted dsplaisted left a comment

Choose a reason for hiding this comment

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

Sorry for the piecemeal feedback, but thanks again for your contribution.

@@ -141,6 +141,9 @@
<data name="CmdRuntimeOptionDescription" xml:space="preserve">
<value>The target runtime to restore packages for.</value>
</data>
<data name="CmdCurrentRuntimeOptionDescription" xml:space="preserve">
<value>Use host runtime to build the target.</value>
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
<value>Use host runtime to build the target.</value>
<value>Use current runtime as the target runtime.</value>

@KathleenDollard Any further suggestions for this text?

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated in all resx/xlf files. More feedback from @KathleenDollard is welcome. :)

@eerhardt
Copy link
Member

possibly via the NETCoreSdkRuntimeIdentifier property

One thing to be aware of here is that NETCoreSdkRuntimeIdentifier will be the "portable" RIDs like:

  • win-x64
  • linux-x64
  • osx-x64

Is that what we want for --use-current-runtime? Or do we want to use the actual machine's RID?

  • win10-x64
  • ubuntu.18.04-x64
  • osx.14-x64

cc @ericstj @janvorli @tmds

@janvorli
Copy link
Member

@eerhardt I would prefer the portable rids. That's what I pass in to dotnet publish all of the time.

@dagood
Copy link
Member

dagood commented Oct 14, 2020

For source-build, the actual/non-portable RID would make sense here. This lets source-build users use the built-from-source Microsoft.NETCore.App.Host.<non-portable-rid> rather than downloading the portable one from nuget.org as a prebuilt. (Also, once the SDK supports bundling a runtime pack (#14044), they can do the same there (dotnet/source-build#1215).)

Either option would make sense to me as the meaning of the flag as it's currently named. I think the ambiguity might be a problem in itself. 🤔

+cc @omajid

@dagood
Copy link
Member

dagood commented Oct 14, 2020

NETCoreSdkRuntimeIdentifier

In source-build this is actually the non-portable RID, because the SDK is built for a non-portable runtime.

For source-build, either portable or non-portable might be desired. Someone could intentionally download the portable runtime/apphost packs to build an app that will run portable. But it's interesting that the behavior of this PR as-is depends on whether the SDK is built portable or non-portable.

@am11
Copy link
Member Author

am11 commented Oct 14, 2020

Personally, my main use-case was to simplify deployment scripts and instructions (e.g. https://github.com/nst/JSONTestSuite/blob/master/parsers/test_dotnet_system_text_json/README.md), where portable RID would suffice.
However, I agree that non-portable RID has its merits, especially for distro providers in Linux (as well as in illumos) world(s).

An idea: why not both? 😎
e.g.
--use-current-runtime, UseCurrentRuntimeIdentifier for portable RID.
--use-current-machine-runtime, UseCurrentMachineRuntimeIdentifier for non-portable RID.

@tmds
Copy link
Member

tmds commented Oct 14, 2020

--use-current-runtime, UseCurrentRuntimeIdentifier for portable RID.

portable rid would be a meaningful default when publishing a single file.
Maybe we need a flag for single file publish?

dotnet publish --single-file

--use-current-machine-runtime, UseCurrentMachineRuntimeIdentifier for non-portable RID.

This doesn't work yet. source-build doesn't produce the artifacts to do a single-file publish for the machine rid.

@am11
Copy link
Member Author

am11 commented Oct 14, 2020

--single-file is a separate concern. There are other cases and form factors (more coming up in the future, hint: superhost) where --runtime is required. Current single-file argument is -p:PublishSingleFile=true (from docs).

@tmds
Copy link
Member

tmds commented Oct 14, 2020

I meant that maybe we can use portable rid as the default for PublishSingleFile, then we don't need to add a flag and come up with a name.

@am11
Copy link
Member Author

am11 commented Oct 14, 2020

IMO, explicit option is better, as it is also used for restore and other commands (beyond publish). UseCurrentRuntimeIdentifier could be later added to dotnet-new template https://github.com/dotnet/templating.

@dsplaisted
Copy link
Member

Personally, my main use-case was to simplify deployment scripts and instructions (e.g. https://github.com/nst/JSONTestSuite/blob/master/parsers/test_dotnet_system_text_json/README.md), where portable RID would suffice.
However, I agree that non-portable RID has its merits, especially for distro providers in Linux (as well as in illumos) world(s).

An idea: why not both? 😎
e.g.
--use-current-runtime, UseCurrentRuntimeIdentifier for portable RID.
--use-current-machine-runtime, UseCurrentMachineRuntimeIdentifier for non-portable RID.

We need to set the RuntimeIdentifier during MSBuild evaluation. So we can't call into an arbitrary API to get the current, most-specific machine RID. So I'm not sure we have a good way to implement UseCurrentMachineRuntimeIdentifier as an MSBuild property. We might have to have it as a CLI command-line option only.

UseCurrentRuntimeIdentifier works because we have access to the "SDK" RID via the NETCoreSdkRuntimeIdentifier property which is set in Microsoft.NETCoreSdk.BundledVersions.props.

@am11
Copy link
Member Author

am11 commented Oct 14, 2020

We need to set the RuntimeIdentifier during MSBuild evaluation. So we can't call into an arbitrary API to get the current, most-specific machine RID. So I'm not sure we have a good way to implement UseCurrentMachineRuntimeIdentifier as an MSBuild property. We might have to have it as a CLI command-line option only.

If running a pre-evaluation custom task is an option, we could do something like:

using System;
using System.Runtime.InteropServices;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

public class UseCurrentMachineRuntimeIdentifierTask : Task
{
    public override bool Execute() => true;

    [Output]
    public string Value => RuntimeInformation.RuntimeIdentifier;
}
<UseCurrentMachineRuntimeIdentifierTask>
  <Output TaskParameter="Value" PropertyName="UseCurrentMachineRuntimeIdentifier"/>
</UseCurrentMachineRuntimeIdentifierTask>

@dsplaisted
Copy link
Member

If running a pre-evaluation custom task is an option

It's not possible. We would have to add something to MSBuild itself (ie a new intrinsic function).

@eerhardt
Copy link
Member

We would have to add something to MSBuild itself (ie a new intrinsic function).

MSBuild allows for calls to RuntimeInformation directly. I've been using that feature to call RuntimeInformation.RuntimeIdentifier in other places. See

https://github.com/dotnet/installer/blob/efe7c8e566c4c06411d028d8d565cb5f6ef7c3e4/src/redist/targets/GetRuntimeInformation.targets#L4-L5

      <HostRid Condition="'$(HostRid)' == '' and '$(MSBuildRuntimeType)' == 'core'">$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)</HostRid>
      <HostRid Condition="'$(HostRid)' == '' and '$(MSBuildRuntimeType)' != 'core'">win-$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToLowerInvariant)</HostRid>

Note that RuntimeInformation.RuntimeIdentifier only works on .NET 5 and not .NET Framework. So that's why the above checks $(MSBuildRuntimeType) == core.

@marcpopMSFT marcpopMSFT merged commit 347f78f into dotnet:master Oct 21, 2020
@am11 am11 deleted the feature/add_--infer-runtime_options branch October 21, 2020 21:37
'$(OS)' == 'Windows_NT' and
'$(RuntimeIdentifier)' == ''">
<_UsingDefaultRuntimeIdentifier>true</_UsingDefaultRuntimeIdentifier>
<RuntimeIdentifier Condition="'$(PlatformTarget)' == 'x64'">win7-x64</RuntimeIdentifier>
<RuntimeIdentifier Condition="'$(PlatformTarget)' == 'x86' or '$(PlatformTarget)' == ''">win7-x86</RuntimeIdentifier>
</PropertyGroup>

<PropertyGroup Condition="'$(UseCurrentRuntimeIdentifier)' == 'true'">
<RuntimeIdentifier>$(NETCoreSdkRuntimeIdentifier)</RuntimeIdentifier>
Copy link
Member

Choose a reason for hiding this comment

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

@am11 @dsplaisted @eerhardt

On a Microsoft SDK, UseCurrentRuntimeIdentifier is the same as portable rid. So --use-current-runtime means publish portable.
On a source-build SDK, this is the same as the machine rid. So the result may be a more specific publish that doesn't work portable.

I think this difference will bite source-build SDK users, and it is preferable to have a flag that means portable-rid consistently.

Copy link
Member Author

Choose a reason for hiding this comment

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

I do not know the full background why source-build chose to override it, but.. if the value of NETCoreSdkRuntimeIdentifier is overridden in source-build repo for set of reasons, do those same reasons not apply to RuntimeIdentifier?

In other words, --use-current-runtime's docs are stating "Use current runtime as the target runtime.", the one SDK is executing on. This is what we have implemented. It is not strictly calling out portable-rid, that's an internal detail of general (non-overridden, non-source-build) case.

Copy link
Member

Choose a reason for hiding this comment

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

I do not know the full background why source-build chose to override it, but.. if the value of NETCoreSdkRuntimeIdentifier is overridden in source-build repo for set of reasons, do those same reasons not apply to RuntimeIdentifier?

source-build does it to indicate the resulting artifacts are not portable.

In other words, --use-current-runtime's docs are stating "Use current runtime as the target runtime.", the one SDK is executing on. This is what we have implemented. It is not strictly calling out portable-rid, that's an internal detail of general (non-overridden, non-source-build) case.

The main use-case is to enable easy publish for the portable rid.
If this flag enables that on Microsoft sdk, that is what it will be used for.
So I'd like this to have the same behavior on source-build sdk, and we can update the docs/implementation accordingly.

Copy link
Member

@dagood dagood Oct 22, 2020

Choose a reason for hiding this comment

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

From my perspective, the source-build scenario was being discussed earlier, and this proposal came up that I think was very nice (except maybe the word "machine" in particular, since it doesn't line up with any other concept I'm aware of):

--use-current-runtime, UseCurrentRuntimeIdentifier for portable RID.
--use-current-machine-runtime, UseCurrentMachineRuntimeIdentifier for non-portable RID.

Docs could then consistently use --use-current-runtime, and source-build users can elect to use the non-portable RID if they so choose.

But then this PR was merged without resolving that discussion, abruptly--it seems to me. 😕 (There were also no approvals.)

Copy link
Member Author

@am11 am11 Oct 22, 2020

Choose a reason for hiding this comment

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

except maybe the word "machine"

It was adapted from @eerhardt's question #14093 (comment) (and maybe derived from the fact that 'machine config' is a thing in .NET Framework) 😉

@nagilson
Copy link
Member

nagilson commented Oct 21, 2022

@am11 Did we never document this feature publically? Like https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-build, and the publish page, or somewhere like that?

@nagilson
Copy link
Member

FYI dotnet/docs#31970 adding it here. @am11. We also changed it to become an opt out for implicit rids.

@am11
Copy link
Member Author

am11 commented Oct 22, 2022

FYI dotnet/docs#31970 adding it here

Thanks.

Did we never document this feature publically?

PR added dotnet build --help documentation. It is not obvious that the docs repo requires a manual update each time we modify an option.

@nagilson
Copy link
Member

We forget to document stuff all the time. Don't sweat it, I agree it would be better if we had something in place for this.

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

Successfully merging this pull request may close these issues.

dotnet-publish with --use-current-rid or --infer-rid option
9 participants