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

Net5.0 RC2: When building a solution with a target runtime ID an error is given #14281

Open
zontreck opened this issue Oct 22, 2020 · 43 comments
Milestone

Comments

@zontreck
Copy link

In previous versions of dotnet core, you could build a solution with the runtime flag -r and it would build for that target (ex. dotnet build -c Release -r win-x64. Now however with RC2 it appears to echo out the error:

error NETSDK1134: Building a solution with a specific RuntimeIdentifier is not supported. If you would like to publish for a single RID, specifiy the RID at the individual project level instead. 

If this is the new normal, is there a replacement method for cross-compiling an entire solution for multiple platforms?

@marcpopMSFT marcpopMSFT added the untriaged Request triage from a team member label Oct 23, 2020
@wli3 wli3 added this to the Backlog milestone Oct 27, 2020
@wli3 wli3 added the needs team triage Requires a full team discussion label Oct 27, 2020
@marcpopMSFT marcpopMSFT removed needs team triage Requires a full team discussion untriaged Request triage from a team member labels Oct 28, 2020
@marcpopMSFT
Copy link
Member

Here's the history on why we ended up blocking this: #863

@ghost
Copy link

ghost commented Nov 11, 2020

Agree, the same issue with release build of .net 5

@norgie
Copy link

norgie commented Nov 12, 2020

So how do we compile for e.g. both win10-x64 and linux-x64 in the same build process?

@svdHero
Copy link

svdHero commented Nov 13, 2020

Same question here. I need to compile a Solution for both Windows and Linux. How would I do that?

southernwind added a commit to southernwind/HomeDashboardBackend that referenced this issue Nov 15, 2020
解決策不明。issueはあがっていたので、これが解決したらもとに戻す。dotnet/sdk#14281
southernwind added a commit to southernwind/HomeDashboardBackend that referenced this issue Nov 15, 2020
解決策不明。issueはあがっていたので、これが解決したらもとに戻す。dotnet/sdk#14281
southernwind added a commit to southernwind/HomeDashboardBackend that referenced this issue Nov 15, 2020
解決策不明。issueはあがっていたので、これが解決したらもとに戻す。dotnet/sdk#14281
@svdHero
Copy link

svdHero commented Nov 16, 2020

Interestingly enough a
dotnet test MySolution.sln -c Release -r win-x64
works fine without any error. It also builds the whole solution with the specified runtime before executing all unit tests. How is that different from
dotnet build MySolution.sln -c Release -r win-x64??? 😕

Both should be possible.

@michael-damatov
Copy link

Similar issue: we are using .NET Core 3.1, the CI fails (since yesterday) with the following debug output:

##[debug]Processed: ##vso[task.logdetail id=0b1a9c29-b168-43d6-a78f-b4b2faadcb38;parentid=;name=Microsoft.NET.Sdk.Solution.targets;type=Build;starttime=2020-11-20T14:52:05.6730082Z;state=InProgress;]
##[error]C:\Program Files\dotnet\sdk\5.0.100\Current\SolutionFile\ImportAfter\Microsoft.NET.Sdk.Solution.targets(27,5): Error NETSDK1134: Building a solution with a specific RuntimeIdentifier is not supported. If you would like to publish for a single RID, specifiy the RID at the individual project level instead.

We are using Azure pipelines with hosted agents.

@JohnFedorchak
Copy link

Same. .NET Core 3.1 on Azure DevOps Server (self-hosted) is getting this when attempting to use the 5.0.100 SDK.

erwan-joly pushed a commit to NosCoreIO/NosCore that referenced this issue Nov 21, 2020
erwan-joly added a commit to NosCoreIO/NosCore that referenced this issue Nov 21, 2020
@jameswoodley
Copy link

Same, CI has just failed after updating to sdk 5.0.. Bit annoying to have to specify each project individually!

@zontreck
Copy link
Author

When building against the 5.0 release version on my CI server using the command:

dotnet publish -c release -r win-x64 -o bin

The resulting binaries give an error about unable to execute reference assemblies.

C:\Users\User\Desktop\New folder>wait.exe
Unhandled exception. System.BadImageFormatException: Could not load file or assembly 'C:\Users\User\Desktop\New folder\wait.dll'. Reference assemblies should not be loaded for execution.  They can only be loaded in the Reflection-only loader context. (0x80131058)
File name: 'C:\Users\Wait\Desktop\New folder\wait.dll' ---> System.BadImageFormatException: Cannot load a reference assembly for execution.

When running the compilation process on a windows machine, the resulting binaries do not give off this same error and instead execute as you would expect them to. The CI server's operating system is Linux, so had to manually re-compile on a windows machine.

atruskie added a commit to QutEcoacoustics/audio-analysis that referenced this issue Dec 1, 2020
Apparently using a rid as a build target for a solution has been deprecated: dotnet/sdk#14281
@CumpsD
Copy link

CumpsD commented Dec 17, 2020

I would love to have this back too. We pass in the desired architecture in our CI pipeline and build scripts because we have both windows and Linux machines.

@lGSMl
Copy link

lGSMl commented Dec 23, 2020

so how can we build solution for particular RID now? If I do not specify RID - it builds for default RID, and then publishing for specific RID fails. All I can do now is to build each single project one by one with RID specified - which sucks tbh

@wi-ry
Copy link

wi-ry commented Dec 23, 2020 via email

@beatcracker
Copy link

beatcracker commented Dec 30, 2020

Well, this is unexpected. I've an AzD pipeline template that is used to build dozens of similar projects and it relies on the solution level actions + rid. E.g. (extra simplified):

dotnet restore -r RID
dotnet build -r RID
dotnet publish -r RID

The RID is passed via CI. The resulting artifacts are used to build docker images for different OS (glibc/musl based) in the subsequent pipeline steps.

@beatcracker
Copy link

beatcracker commented Jan 5, 2021

I've 2 workarounds for now:

  1. Since we use Azure DevOps' .NET Core CLI task in the templates, specifying projects as **/*.csproj works. Previously we had *.sln there. This is not exactly the same, since we lose the ability to control project builds via solution (e.g. devs could easily disable them there if needed), but it's a start.
  2. The error is generated in the SolutionFile/ImportAfter/Microsoft.NET.Sdk.Solution.targets. By specifying -p:ImportByWildcardBeforeSolution=false targets from there wouldn't be imported and the solution level build with runtime identifier will work.
    Example: dotnet build --runtime linux-x64 -p:ImportByWildcardBeforeSolution=false
    Please note that this will disable the import of the other targets which might be needed. On my local machine I also have Microsoft.NuGet.ImportAfter.targets there. I'm not sure if it's needed, my quick tests with build and pack commands work fine even if it's not imported.

@marcpopMSFT
Copy link
Member

Sorry for the slow reply on this as my notifications were not set up to see the replies here until the mention a couple weeks ago. I've synced with a couple of people offline about this.

Per the issue I originally mentioned (#863), when a library is included in a solution and referenced by another project in that solution AND you build the solution with a RID, we end up building the library twice. Once without the RID (as part of the referenced project build) and once with the RID (as part of the root solution build) to the same location. This can cause issues like build failures if there is a timing issue and the file is locked. This can also cause issues if the application has behavior chnages dependent on the RID. The issues that will arise when doing this won't always happen since the primary issue is a race condition. It also won't happen if every project already has RIDs specified in the project.

A long-term solution would be to put the IsRidAgnostic logic into the solution handling logic which would avoid the duplicate build. At the moment, it's not high on our priority list to enable that but CCing @KathleenDollard and @richlander in case they have prioritization opinions.

One alternative that's relatively cheap would be to just change the error to a warning (with a modified message). Would that work for folks who were utilizing this behavior before? You can then suppress the warning if desired but wouldn't be blocked.

@Kaelum
Copy link

Kaelum commented Jul 8, 2021

@marcpopMSFT there are multiple issues, and not all of them are being discussed here, even though they are what is causing part of the issue(s). Publishing projects that only use the core .NET SDK are not handled in the same way as projects that use ASP.NET, due to how the dotnet command works internally, and sends those commands in different ways to MSBuild. While it is now possible to build and publish using the dotnet command, the publish option still doesn't work correctly, but you can still publish using the build option with additional command line parameters.

The end goal is for building solutions and projects to work correctly with the build option, and for publishing solutions and projects to work correctly with the publish option, correct? And when publishing, using either the .pubxml files, or specifying all of those options on the command line, is also the goal, correct? If so, then whatever furthers those goals should be done, and anything that hampers, or delays those goals, should be reconsidered.

If changes are going to made that only delay the inevitable, they should be labeled as such and seriously thought needs to go into, are they helping? Or are they making things worse? Creating new temporary code paths will cause future problems, because that is how we got to where we are now. .pubxml files are extremely easy to work with, but the documentation and examples are SEVERELY lacking.

@marcpopMSFT marcpopMSFT removed the needs team triage Requires a full team discussion label Jul 14, 2021
@IvarWithoutBones
Copy link

One alternative that's relatively cheap would be to just change the error to a warning (with a modified message). Would that work for folks who were utilizing this behavior before? You can then suppress the warning if desired but wouldn't be blocked.

I would really appreciate this!

@olafur-palsson
Copy link

@marcpopMSFT Just ran into this one where I want to build + run a debug server on WSL. CLI parameters should just override the configs and warn people if both are specified. I prefer not changing code I have to remember to change back.

@zontreck
Copy link
Author

I would also really appreciate just temporarily, until a more long term solution is put in place to actually solve the other issue which caused this to be blocked, swap this into a warning that could be suppressed instead. @marcpopMSFT

@marcpopMSFT marcpopMSFT added the needs team triage Requires a full team discussion label Sep 13, 2022
@marcpopMSFT
Copy link
Member

marcpopMSFT commented Sep 14, 2022

We did recently add IsRidAgnostic but unfortunately, we were not able to enable it for solution files. We found that it was either going to greatly impact performance for solutions but essentially doing multiple builds or require a significant amount of logic.

Daniel's workaround here is still the only solution at the moment: #14281 (comment) We'll take another look at our options in 8.0.1xx

@marcpopMSFT marcpopMSFT modified the milestones: Backlog, 8.0.1xx Sep 14, 2022
@marcpopMSFT marcpopMSFT added Area-NetSDK and removed needs team triage Requires a full team discussion labels Sep 14, 2022
@askazakov
Copy link

askazakov commented Jan 20, 2023

Interestingly enough a
dotnet test MySolution.sln -c Release -r win-x64

(from comment)

as for sdk 6.0.402 dotnet test just ignore -r – it's build to /bin/Release/net6.0/ regardless of specified RID instead of /bin/Release/net6.0/win-x64

@turowicz
Copy link

Here is another workaround which may be better than creating publish profiles for each project. Create a Directory.Build.props file in the root of your repo with the following contents:

<Project>
  <PropertyGroup>
    <RuntimeIdentifier>$(MyRuntimeIdentifier)</RuntimeIdentifier>
  </PropertyGroup>
</Project>

Then when you build or publish, specify the RuntimeIdentifier with the MyRuntimeIdentifier property instead of the --runtime parameter. For example:

dotnet build MySolution.sln -p:MyRuntimeIdentifier=linux-x64

How can we tie that up with multiplatform (arm64 + x86) buildx dockerfile? They inject amd64 and arm64 as variables. Linux I could hardcode.

@kabili207
Copy link

kabili207 commented Jul 13, 2023

@turowicz From what I can tell, it looks like buildx passes the platform as TARGETARCH, so you should be able to do something like this:

dotnet build MySolution -p:TargetArch=$TARGETARCH
<Project>
  <PropertyGroup Condition="'$(TargetArch)' == 'x86'">
    <RuntimeIdentifier>linux-x86</RuntimeIdentifier>
  </PropertyGroup>
  <!-- Note! Docker buildx uses amd64 instead of x64! -->
  <PropertyGroup Condition="'$(TargetArch)' == 'amd64'">
    <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
  </PropertyGroup>
  <PropertyGroup Condition="'$(TargetArch)' == 'arm64'">
    <RuntimeIdentifier>linux-arm64</RuntimeIdentifier>
  </PropertyGroup>
</Project>

@marcpopMSFT marcpopMSFT modified the milestones: 8.0.1xx, Backlog Sep 15, 2023
@voroninp
Copy link

@marcpopMSFT , same error in .NET 8 (8.0.100)

@turowicz
Copy link

@kabili207 looks pretty good

@slxdy
Copy link

slxdy commented Oct 22, 2024

This seems like the most pointless limitation ever that still hasn't been fixed.

@zontreck
Copy link
Author

I am still waiting for a fix to this. I have been unable to set up cross platform compilations on my jenkins server since this change. I know the fix was planned for Net 8, but seeing as it has yet to be fixed @marcpopMSFT, what is the new ETA on a fix? Workarounds are great and all, but are not so simple to set up.

@quentinformatique
Copy link

quentinformatique commented Dec 31, 2024

I've encountered the same problem and found a solution that works in .NET8 (so give it a try and see if it works in other cases):

You need to add a file named Directory.Build.props to the root of your solution folder, containing this:

<Project>
  <PropertyGroup>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
  </PropertyGroup>
</Project>

You can replace the win-x64 with another RID (the list is available here: https://github.com/dotnet/docs/blob/main/docs/core/rid-catalog.md ), for exemple: linux-x64

@marcpopMSFT
Copy link
Member

Retriage
We still have no plans to address this because of the history outlined above on how RID is passed through during a SLN compilation and the fact that it does not work the way it needs to to support this.

The recommendation is still to do the solution outlined by @dsplaisted here: #14281 (comment)

That should work and be relatively inexpensive to implement.

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

No branches or pull requests