使用比目标框架更新的dotnet SDK构建C++/CLI。

huangapple go评论66阅读模式
英文:

Use newer dotnet sdk than TargetFramework when building C++/CLI

问题

可能使用比目标框架更新的dotnet SDK构建C++/CLI vcxproj吗?

我们有一个包含C#、C++和少量C++/CLI项目的大型解决方案。目标框架设置为.NET 6(最新的LTS版本等等)。同时,我想要使用C# 11,这需要在构建时使用.NET 7 SDK。

对于普通的C#项目,我可以简单地使用global.json来指定.NET 7(在使用足够新的Visual Studio时),同时保持TargetFramework=6.0。

但是,对于C++/CLI项目进行相同操作时,我会遇到NETSDK1145错误

错误 NETSDK1145 未安装Apphost包,并且不支持NuGet包恢复。请升级Visual Studio,如果它指定了某个SDK版本,请删除global.json,并卸载更新的SDK。欲了解更多选项,请访问https://aka.ms/targeting-apphost-pack-missing Pack Type:Apphost,Pack directory: C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64,targetframework: net6.0,Pack PackageId: Microsoft.NETCore.App.Host.win-x64,Pack Package Version: 6.0.16 C:\Program Files\dotnet\sdk\7.0.203\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.FrameworkReferenceResolution.targets 135

链接提到了设置以下内容:

<ItemGroup>
  <KnownAppHostPack Update="@(KnownAppHostPack)">
    <AppHostPackVersion Condition="'%(TargetFramework)' == 'TARGETFRAMEWORK'">EXISTINGVERSION</AppHostPackVersion>
  </KnownAppHostPack>
</ItemGroup>

但没有提到可能出现的问题或这样做的后果。我也不确定如果人们可能安装了不同的.NET 7 SDK会怎么做(我不想强制使用单一的SDK)。

英文:

Is it possible to use a newer dotnet SDK building C++/CLI vcxproj than their target framework?

We have a large solution containing C#, C++ and a handful of C++/CLI projects. The target framework is set to .NET 6 (latest LTS and all that). At the same time I'd like to use C# 11 and which requires the use of a .NET 7 sdk when building.

For normal C# projects I can simply use a global.json to specify .NET 7 (when using a new enough VS) while keeping TargetFramework=6.0.

When doing the same with C++/CLI projects I get a NETSDK1145 error:

> Error NETSDK1145 The Apphost pack is not installed and NuGet package
> restore is not supported. Upgrade Visual Studio, remove global.json if
> it specifies a certain SDK version, and uninstall the newer SDK. For
> more options visit https://aka.ms/targeting-apphost-pack-missing
> Pack Type:Apphost, Pack directory: C:\Program
> Files\dotnet\packs\Microsoft.NETCore.App.Host.win-x64,
> targetframework: net6.0, Pack PackageId:
> Microsoft.NETCore.App.Host.win-x64, Pack Package Version:
> 6.0.16 <ProjectNAme> C:\Program Files\dotnet\sdk\7.0.203\Sdks\Microsoft.NET.Sdk\targets\Microsoft.NET.Sdk.FrameworkReferenceResolution.targets 135

The link says something about setting

&lt;ItemGroup&gt;
  &lt;KnownAppHostPack Update=&quot;@(KnownAppHostPack)&quot;&gt;
    &lt;AppHostPackVersion Condition=&quot;&#39;%(TargetFramework)&#39; == &#39;TARGETFRAMEWORK&#39;&quot;&gt;EXISTINGVERSION&lt;/AppHostPackVersion&gt;
  &lt;/KnownAppHostPack&gt;
&lt;/ItemGroup&gt;

but does not say anything about possible problems or the consequences of doing so. I'm also not sure how I'd do that if people might have different .NET 7 SDKs installed (I don't want to force a single SDK).

答案1

得分: 1

我可能要传递一些不好的消息。

我理解的是,这可能不适合您。如果您正确地填写了它,我认为它会像这样:

<ItemGroup>
    <KnownAppHostPack Update="@(KnownAppHostPack)">
        <AppHostPackVersion Condition="'%(TargetFramework)' == 'net6.0'">EXISTINGVERSION</AppHostPackVersion>
    </KnownAppHostPack>
</ItemGroup>

因为您正在告诉Apphost要使用的特定版本。如果正确执行,这可能会解决NETSDK1145错误;但是,这只会解决该错误,不会更新整个项目,而整个项目可能充满问题。

即使这样做,您可能只会从一个错误跳到另一个错误。

更新您的项目可能会更快。Visual Studio现在支持Net7目标。

https://developercommunity.visualstudio.com/t/Add-NET70-target-for-CCLI-Projects/10232939

英文:

Im probably going to be the bearer of bad news here.

My understanding of it is that probably wont work for you. If you field it out correctly I think it would look like this

  &lt;ItemGroup&gt;
    &lt;KnownAppHostPack Update=&quot;@(KnownAppHostPack)&quot;&gt;
      &lt;AppHostPackVersion Condition=&quot;&#39;%(TargetFramework)&#39; == &#39;net6.0&#39;&quot;&gt;EXISTINGVERSION&lt;/AppHostPackVersion&gt;
    &lt;/KnownAppHostPack&gt;
  &lt;/ItemGroup&gt;

As your telling Apphost what specific version to use. If done correctly this would potentially solve the NETSDK1145 error; however, it would only solve that error, it wouldnt update it for the whole project which would likely be full of issues.

Your likely just going to be hopping from one bug to another even if that works

It will probably just be quicker to update your project. Visual studios supports Net7 targets now

https://developercommunity.visualstudio.com/t/Add-NET70-target-for-CCLI-Projects/10232939

答案2

得分: 0

迄今为止,只需将应用程序主机包设置为.NET 6变种,同时使用.NET 7构建似乎运行正常。

为了使这个过程更加流畅,我编写了一个简单的内联Roslyn代码工厂,用于查找所需目标框架的最新应用程序主机包(请注意硬编码的运行时标识符 - 您需要查看哪个MSBuild标识符适用于通用解决方案)。

在构建系统中,使用的.NET SDK及其运行时版本都是硬编码的,以保证可重现性。

<UsingTask TaskName="GetAppHostVersionTask"
    TaskFactory="RoslynCodeTaskFactory"
    AssemblyFile="$(MSBuildBinPath)\Microsoft.Build.Tasks.Core.dll">
    <ParameterGroup>
        <NetCoreTargetingPackRoot ParameterType="System.String" Required="true" />
        <KnownAppHostPack ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
        <RuntimeIdentifiers ParameterType="System.String" Required="true" />
        <TargetFramework ParameterType="System.String" Required="true" />
        <HighestSupportedVersion ParameterType="System.String" Output="true" />
    </ParameterGroup>
    <Task>
        <Code Type="Fragment" Language="cs">
<![CDATA[
#pragma warning disable CS0162 // False positive warning
var runtimeName = this.KnownAppHostPack[0].ItemSpec;
var packDirectory = Path.Combine(this.NetCoreTargetingPackRoot, $"{runtimeName}.Host.{this.RuntimeIdentifiers}");
var supportedVersion = this.TargetFramework.Substring("net".Length);
var versionToUse = Directory.EnumerateDirectories(packDirectory)
      .Select(Path.GetFileName)
      .Where(dirName => dirName.StartsWith(supportedVersion, StringComparison.OrdinalIgnoreCase))
      .OrderByDescending(Version.Parse)
      .FirstOrDefault();
if (versionToUse is null)
{
 this.Log.LogError($"'{packDirectory}' does not contain any pack runtime for target framework {this.TargetFramework}.");
 return false;
}
this.Log.LogMessage(MessageImportance.High, $"AppHostPackVersion set to {versionToUse}");
this.HighestSupportedVersion = versionToUse;
return true;
]]>
        </Code>
    </Task>
</UsingTask>

<Target Name="SetAppHostPackVersion" BeforeTargets="ProcessFrameworkReferences">
    <GetAppHostVersionTask
        NetCoreTargetingPackRoot="$(NetCoreTargetingPackRoot)"
        KnownAppHostPack="@(KnownAppHostPack)"
        RuntimeIdentifiers="win-$(Platform)"
        TargetFramework="$(TargetFramework)"
        Condition=" '$(MyAppHostPackVersion)' == '' ">
        <Output TaskParameter="HighestSupportedVersion" PropertyName="MyAppHostPackVersion" />
    </GetAppHostVersionTask>
    <ItemGroup>
        <KnownAppHostPack Update="@(KnownAppHostPack)">
            <AppHostPackVersion>$(MyAppHostPackVersion)</AppHostPackVersion>
        </KnownAppHostPack>
        <KnownFrameworkReference Update="@(KnownFrameworkReference)">
            <TargetingPackVersion>$(MyAppHostPackVersion)</TargetingPackVersion>
        </KnownFrameworkReference>
    </ItemGroup>
</Target>

如果有与此相关的任何错误报告,我将会反馈,但目前看来一切正常。似乎ABI在各个版本之间是稳定的。

英文:

So far just setting the app host package to a .NET 6 variant while building using .NET 7 seems to be working just fine.

To make this streamlined to use, I wrote a simple inline roslyn code factory that finds the newest app host package for the required target framework (nb the hardcoded runtime identifier - you'll have to see what msbuild identifier exists for a general solution).

On the build system the used .NET SDK and its runtime version are hardcoded for reproducability

&lt;UsingTask TaskName=&quot;GetAppHostVersionTask&quot;
TaskFactory=&quot;RoslynCodeTaskFactory&quot;
AssemblyFile=&quot;$(MSBuildBinPath)\Microsoft.Build.Tasks.Core.dll&quot;&gt;
&lt;ParameterGroup&gt;
&lt;NetCoreTargetingPackRoot ParameterType=&quot;System.String&quot; Required=&quot;true&quot; /&gt;
&lt;KnownAppHostPack ParameterType=&quot;Microsoft.Build.Framework.ITaskItem[]&quot; Required=&quot;true&quot; /&gt;
&lt;RuntimeIdentifiers ParameterType=&quot;System.String&quot; Required=&quot;true&quot; /&gt;
&lt;TargetFramework ParameterType=&quot;System.String&quot; Required=&quot;true&quot; /&gt;
&lt;HighestSupportedVersion ParameterType=&quot;System.String&quot; Output=&quot;true&quot; /&gt;
&lt;/ParameterGroup&gt;
&lt;Task&gt;
&lt;Code Type=&quot;Fragment&quot; Language=&quot;cs&quot;&gt;
&lt;![CDATA[
#pragma warning disable CS0162 // False positive warning
var runtimeName = this.KnownAppHostPack[0].ItemSpec;
var packDirectory = Path.Combine(this.NetCoreTargetingPackRoot, $&quot;{runtimeName}.Host.{this.RuntimeIdentifiers}&quot;);
var supportedVersion = this.TargetFramework.Substring(&quot;net&quot;.Length);
var versionToUse = Directory.EnumerateDirectories(packDirectory)
.Select(Path.GetFileName)
.Where(dirName =&gt; dirName.StartsWith(supportedVersion, StringComparison.OrdinalIgnoreCase))
.OrderByDescending(Version.Parse)
.FirstOrDefault();
if (versionToUse is null)
{
this.Log.LogError($&quot;&#39;{packDirectory}&#39; does not contain any pack runtime for target framework {this.TargetFramework}.&quot;);
return false;
}
this.Log.LogMessage(MessageImportance.High, $&quot;AppHostPackVersion set to {versionToUse}&quot;);
this.HighestSupportedVersion = versionToUse;
return true;
]]&gt;
&lt;/Code&gt;
&lt;/Task&gt;
&lt;/UsingTask&gt;
&lt;Target Name=&quot;SetAppHostPackVersion&quot; BeforeTargets=&quot;ProcessFrameworkReferences&quot;&gt;
&lt;GetAppHostVersionTask
NetCoreTargetingPackRoot=&quot;$(NetCoreTargetingPackRoot)&quot;
KnownAppHostPack=&quot;@(KnownAppHostPack)&quot;
RuntimeIdentifiers=&quot;win-$(Platform)&quot;
TargetFramework=&quot;$(TargetFramework)&quot;
Condition=&quot; &#39;$(MyAppHostPackVersion)&#39; == &#39;&#39; &quot;&gt;
&lt;Output TaskParameter=&quot;HighestSupportedVersion&quot; PropertyName=&quot;MyAppHostPackVersion&quot; /&gt;
&lt;/GetAppHostVersionTask&gt;
&lt;ItemGroup&gt;
&lt;KnownAppHostPack Update=&quot;@(KnownAppHostPack)&quot;&gt;
&lt;AppHostPackVersion&gt;$(MyAppHostPackVersion)&lt;/AppHostPackVersion&gt;
&lt;/KnownAppHostPack&gt;
&lt;KnownFrameworkReference Update=&quot;@(KnownFrameworkReference)&quot;&gt;
&lt;TargetingPackVersion&gt;$(MyAppHostPackVersion)&lt;/TargetingPackVersion&gt;
&lt;/KnownFrameworkReference&gt;
&lt;/ItemGroup&gt;
&lt;/Target&gt;

I'll report back if there's any bug reports that can be traced back to this, but so far it looks good. Seems like the ABI is stable across versions.

huangapple
  • 本文由 发表于 2023年7月13日 18:46:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76678495.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定