Skip to content

.NET Core can't build AnyCPU exes #1906

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

Closed
davidmatson opened this issue Jan 26, 2018 · 7 comments
Closed

.NET Core can't build AnyCPU exes #1906

davidmatson opened this issue Jan 26, 2018 · 7 comments
Milestone

Comments

@davidmatson
Copy link

davidmatson commented Jan 26, 2018

(I may be misunderstanding how things are supposed to work here; apologies if this is more of a question than a bug.)

Consider the following project file:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net47</TargetFramework>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <RuntimeIdentifier>win</RuntimeIdentifier>
  </PropertyGroup>

</Project>

This project builds/runs correctly and generates an AnyCPU exe. Now change the target framework to .NET Core:

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

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <RuntimeIdentifier>win</RuntimeIdentifier>
  </PropertyGroup>

</Project>

This project generates a build error:
Project is targeting runtime 'win' but did not resolve any runtime-specific packages for the 'Microsoft.NETCore.App' package. This runtime may not be supported by .NET Core.

If RuntimeIdentifier is win-x86 or win-x64, it builds, but at publish time I suspect (though couldn't confirm) that the assemblies it generates are not AnyCPU, even though the Platform in the project file was explicitly AnyCPU.

I believe .NET Core still supports AnyCPU for DLLs. But does it really support AnyCPU for EXEs? It looks like today there isn't a clear answer - you can say you're building an AnyCPU exe, but you don't actually get an exe unless you do publish on a Self-Contained Deployment by using a RuntimeIdentifier, and no AnyCPU RuntimeIdentifier (aka just "win"?) is currently supported.

How should this work? Should .NET Core allow creating AnyCPU EXEs? If not, should the build generate an error when OutputType=Exe and Platform=AnyCPU?

@livarcocc
Copy link
Contributor

.NET Core does not have a notion of a AnyCPU executable. For .NET Core, the executable is a copy of the dotnet.exe, with some things changed and it must be either x86 or x64.

Given that, you are right, I am not sure it makes much sense to have a AnyCPU .NET Core application and maybe we should error out in that case.

@dsplaisted @nguerrera do you have an option on whether we should error out in this case?

@livarcocc livarcocc added this to the Discussion milestone Jan 26, 2018
@dasMulli
Copy link
Contributor

Truly platform independent apps should never target a specific runtime (=> RuntimeIdentifier).

Even if the resulting windows assembly could be loaded in both 32 and 64 bit environments, the RuntimeIdentifier is also used to resolve NuGet assets.

So if a NuGet package contains 32 and 64 bit assemblies, it needs to know which ones are needed.

@livarcocc
Copy link
Contributor

After talking over this with @nguerrera, I think we should consider this behavior by design and we should not error out when PlatformTarget is set to AnyCPU for a .NET Core App.

A couple of reasons for this:

  1. The issue you see above is independent of the PlatformTarget. That error indicates that you are targeting a RID without any native assets.
  2. We want the deployment of your application to be a choice that you can make during deployment time (when publshing) and not development time (project file). For instance, if a user has a Framework Dependent application with AnyCPU, which is completely valid and the simpler csproj format. He can decide, during deployment, to run `dotnet publish --rid win-x64' to publish his app as a self-contained app targeting windows x64 bits.
  3. The effort to make a managed exe that is architecture independent for .NET Core is just considerable and something that involves a lot more than the SDK team. I am not aware of any plans to support this at the moment.

Given that, I am going to go ahead and close this issue. However, we recognize that there may be space here for a improved experience when you are building an application that you want to work across different architectures of a OS. While, as I said above having a managed exe is something that I don't see us tackling any time soon, we could produce a publish experience for a "All CPUs" case, that would publish one app per CPU type (x86 and x64, arm, etc). I leave it up to you to file a separate issue for that, if you feel like necessary, but I don't know when we would get to it either.

Hope this makes sense and thanks for filling this issue.

@davidmatson
Copy link
Author

FWIW, I think the separation between build & deployment is one of the bigger disconnects between .NET Core and it's use of MSBuild - things like PlatformTarget were largely the equivalent ways to set things in the past during build time that .NET Core now wants to handle at deployment time. The fact that .NET Core MSBuild projects keep most/all the same build-time mechanisms and then add (potentially duplicate or conflicting) deployment-time mechanisms leads to some surprising/inconsistent behavior. I think this overall design issue is largely capture by #1553, and this is one of many manifestations, but let me know if there's a better way to provide input on the broader difficulties here.

@davidmatson
Copy link
Author

BTW, should we prohibit setting PlatformTarget altogether for .NET Core? That could help support goal 2 above (make this a deployment-time decision). I'll add this idea to #1553 as well.

@livarcocc
Copy link
Contributor

This is supported for Framework Dependent Applications. You can set AnyCpu, publish your app and execute it with either the x86 dotnet.exe or the x64 dotnet.exe.

@davidmatson
Copy link
Author

davidmatson commented Jan 29, 2018

Understood. However, is there a need for PlatformTarget to control that knob? If we only had RuntimeIdentifier(s), would that achieve the same result? (Perhaps that's equivalent to saying AnyCPU is the only PlatformTarget, but you can have architecture-specific RuntimeIdentifiers.)

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

No branches or pull requests

3 participants