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

Creation of .NET executable file broken with .NET 5 SDK #148

Open
jimevans opened this issue Nov 16, 2020 · 6 comments
Open

Creation of .NET executable file broken with .NET 5 SDK #148

jimevans opened this issue Nov 16, 2020 · 6 comments

Comments

@jimevans
Copy link
Contributor

When building an executable assembly (csharp_binary), the C# compiler has changed its behavior with the release of .NET 5.0. Previously, the C# compiler would simply create the executable assembly, with a .exe extension, and it was possible to execute dotnet <assembly name>.exe and have the executable run. This is the pattern used by these C# Bazel rules. This is no longer the case with .NET 5.0.

Now, the compiler emits two assemblies, <assembly name>.dll and <assembly name>.exe with an <assembly name>.deps.json file that references the dll (Note: I do not yet know if the json file is generated by csc.exe, or by MSBuild). With the binaries created by MSBuild/Visual Studio, it is possible to execute the created .dll using dotnet <assembly name>.dll, or to execute <assembly name>.exe directly. Accordingly, the Bazel rules should ideally emit the same file list that the MSBuild task emits, but an acceptable solution would be to just emit the .dll that can be executed via dotnet <assembly name>.dll.

@j3parker
Copy link
Member

Oh neat! Thanks for the report.

@jimevans
Copy link
Contributor Author

Okay, after some further digging, it looks like building the actual .exe will be challenging, because it's not done by the compiler directly. However, I think an executable dll assembly can be emitted, but it needs one, and possibly two, things. First, it the rules need to not set the extension to .exe when running the csharp_binary rule.

Second, it may need an emitted "AssemblyAttributes.cs" source file to be generated that has the framework version attribute. This appears to be generated by Visual Studio under the obj directory, and will have content similar to this:

// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v5.0", FrameworkDisplayName = "")]

What actions need to happen to actually create the executable file (.exe) will need some further investigation.

@jimevans
Copy link
Contributor Author

I'll attempt to generate a PR for at least the temporary (dll-only) solution ASAP.

@j3parker
Copy link
Member

Cool, thanks! That sounds good.
I'd like to investigate what their exe is doing now. For fixing stuff like #9 the WIP fix I have (urg) involves a little stub exe, which is a little similar... I wonder if they're doing something like a little C wrapper + embedding the DLL as a resource at the end of the exe or something like that.

@jimevans
Copy link
Contributor Author

jimevans commented Nov 16, 2020

@j3parker The immediate "cannot execute an executable assembly at all" issue is now fixed with PR #145 (merged in bf24e58). I strongly suspect that you're on the right track as to what the VS-generated executable is actually doing. The .exe generated is not a raw .NET assembly. In the VS build process, there's a CreateAppHost task that gets called. I suspect the magic, such as it is, happens there.

@j3parker
Copy link
Member

Ahh good pointer. That got me to https://github.com/dotnet/runtime/blob/master/src/installer/managed/Microsoft.NET.HostModel/AppHost/HostWriter.cs and yeah it looks something like that.

It sounds like we probably want to mimic CreateAppHost. I wonder if only for .NET 5+ though?

I think probably the app host output would be a separate build output, and we'd probably still need to do special assembly loading stuff to solve something like #9 (where we want to use the DLLs spread out across the disk in the way Bazel likes).

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

2 participants