Skip to content

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.

<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