NREL / OpenStudio

OpenStudio is a cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance.
https://www.openstudio.net/
Other
486 stars 186 forks source link

"OpenStudio does not work correctly on 'AnyCPU' platform. You need to specify platform (x86 or x64)" #5104

Open DaveInCaz opened 4 months ago

DaveInCaz commented 4 months ago

Issue overview

OpenStudio 3.7 prohibits building a C# project which is set to 'AnyCPU' as its target (which is the default). But this was not the case previously (at least not in version 3.2.1).

I haven't come across any other Nuget packages (including some with platform dependencies) that prevent building as AnyCPU. Even when they have platform dependencies; for example, https://github.com/mathnet/mathnet-numerics.

Previously our builds were all set to AnyCPU, the .NET / C# default. Using that setting most Visual Studio / MSBUILD settings and configuration could just be left in their simplest, default state. Because of this restriction against AnyCPU we've had to modify this which makes our builds more complex to maintain.

Current Behavior / Reproduction

To reproduce this, create a new .NET 8 project in Visual Studio 2022 using the "class library" project template. Then go to Nuget in VS and add OpenStudio 3.7. Compile. No code changes needed. The entire project file is listed below:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="OpenStudio" Version="3.7.0" />
  </ItemGroup>

</Project>

This results in the following compilation error:

Severity    Code    Description Project File    Line    Suppression State
Error       OpenStudio does not work correctly on 'AnyCPU' platform. You need to specify platform (x86 or x64). os37test    <edit>\.nuget\packages\openstudio\3.7.0\build\netstandard2.0\OpenStudio.targets 5   

Following the path in the error you can see where this originates, in the OpenStudio.targets file:

  <Target Name="PlatformCheck" BeforeTargets="InjectReference"
    Condition="(('$(Platform)' != 'x86') AND  ('$(Platform)' != 'x64'))">
    <Error  Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' platform. You need to specify platform (x86 or x64)." />
  </Target>

I attached this example: os37test.zip

This is not dependent on the .NET version, for instance it does it in .NET Framework 4.8 also.

Thanks!

Details

Environment

jmarrec commented 4 months ago

Thanks for the report.

IIUC, the mathnet stuff just picks the 32 bit one for the native stuff when "Any CPU" is used: https://github.com/mathnet/mathnet-numerics/blob/f19641843048df073b80f6ecfcbb229d3258049b/MathNet.Numerics.MKL.sln#L79 (This is a very complex project unfortunately, so it's hard to tell what's going on really.)

Does picking x86 or x64 really creates that much of a burden for you though?


I think I've figured a way we can trick dotnet into figuring the PlatformTarget when AnyCPU is picked:

  <PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
    <UseCurrentRuntimeIdentifier>true</UseCurrentRuntimeIdentifier>
  </PropertyGroup>

I'll exercise the code up there: https://github.com/dotnet/sdk/blob/af4967de46a87229c49f6d567028791c4c4683d0/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.RuntimeIdentifierInference.targets#L110-L155

I tested it on linux and windows with dotnet 6 and 8 and it seems to work, but this feels very fragile/hackish

DaveInCaz commented 4 months ago

Thanks for looking into alternatives for this.

This is the only Nuget package that behaves this way (that I've come across). So its an outlier in the .NET ecosystem. And the thing that stood out was that it was a change... the older OpenStudio versions didn't do this. (What was the reason for the change?)

Aside from the customization that I needed to do on our projects, I assume it would affect anyone else using OpenStudio from .NET the same way; ease-of-use seems like it is important for OpenStudio adoption, especially say in a case where someone wants to try a quick proof of concept to evaluate it. If the first thing that happens is that they run into an error (which no other Nuget package has ever caused them) they might stop right there.

Also, if OpenStudio might ever be compiled for another architecture (like ARM64 for instance) I think this would get in the way. (I can see the draft .targets file accounts for this).

As for the .targets file changes you proposed - I wish I knew more about msbuild to provide helpful comments ☹.