dotnet / roslyn

The Roslyn .NET compiler provides C# and Visual Basic languages with rich code analysis APIs.
https://docs.microsoft.com/dotnet/csharp/roslyn-sdk/
MIT License
18.78k stars 4k forks source link

Compile as .netmodule fails, but exe is working #58193

Open nedy13 opened 2 years ago

nedy13 commented 2 years ago

Description

Hi,

I am usually not a C# developer, so I'm not really familiar with the C# world, frameworks and the environment, but we have a small integration in our product where we transport data via HTTP. So we have a DLL which has a small C# HTTP1 server and HTTP1 client in it. The main problem is that this solution is too slow and we want to give GRPC a try.

The main problem is that our DLL is a mixed-code assembly (C++ and C#). So I need to compile the C# part in a .netmodule and later on it is linked together to one DLL. This was working fine with .Net 4.8 and the HTTP1 code.

With .Net5 / .Net6 and grpc-dotnet it seems not to work.

The compiler is complaining the following:

error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined or im

I really have no idea how to fix it.

If I build it with "OutputType>exe</OutputType", then it is working.

image

If I build the example greeter server application with "OutputType>module</OutputType", then I got this message.

image

Code parts which are failing:

image

My complete project file looks like this.

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

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <OutputType>module</OutputType>
    <!-- <OutputType>exe</OutputType> -->
    <Utf8Output>true</Utf8Output>
    <!-- <NoConfig>true</NoConfig> -->
    <!-- <NoStandardLib>true</NoStandardLib> -->
    <ProduceReferenceAssembly>false</ProduceReferenceAssembly>
    <ProduceOnlyReferenceAssembly>false</ProduceOnlyReferenceAssembly>
      <!-- <Nullable>disable</Nullable> -->
  </PropertyGroup>

  <ItemGroup>
    <Protobuf Include="..\Protos\prpc.proto" GrpcServices="Server" Link="..\Protos\prpc.proto" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
  </ItemGroup>

</Project>

Has somebody an idea, why this is not working with this project? Is this a .Net5/6 limitation?

Thank you very much in advance.

Reproduction Steps

Expected behavior

compiles to .netmodule

Actual behavior

error CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute' is not defined

I really have no idea how to fix it.

Regression?

Compiling to .netmodule works in .Net 4.8 version. We don't use grpc, this is completely new to our project.

Known Workarounds

no

Configuration

Other information

No response

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

SingleAccretion commented 2 years ago

So I need to compile the C# part in a .netmodule and later on it is linked together to one DLL. This was working fine with .Net 4.8 and the HTTP1 code. With .Net5 / .Net6 and grpc-dotnet it seems not to work.

Multimodule assemblies are not supported in .NET (Core). Probably, the fix here would be to split the C# and C++ code apart into two different assemblies.

nedy13 commented 2 years ago

@SingleAccretion thank you very much for your answer. I also thought this, but I found this bug entry:

https://github.com/dotnet/runtime/issues/10333

I think it should work now.

I am not at this point that I want to build a multimodule assembly. The build fails for a netmodule compile. This is pure C# code. It is right that I need a netmodule for a multimodule- and mixed-mode (C++/C#) assemblies.

huoyaoyuan commented 2 years ago

If netmodule is no longer supported, we should delete everywhere mentioning it in the toolchain, so that you couldn't try to compile as netmodule at all.

ghost commented 2 years ago

Tagging subscribers to this area: @dotnet/area-meta See info in area-owners.md if you want to be subscribed.

Issue Details
### Description Hi, I am usually not a C# developer, so I'm not really familiar with the C# world, frameworks and the environment, but we have a small integration in our product where we transport data via HTTP. So we have a DLL which has a small C# HTTP1 server and HTTP1 client in it. The main problem is that this solution is too slow and we want to give GRPC a try. The main problem is that our DLL is a mixed-code assembly (C++ and C#). So I need to compile the C# part in a .netmodule and later on it is linked together to one DLL. This was working fine with .Net 4.8 and the HTTP1 code. With .Net5 / .Net6 and grpc-dotnet it seems not to work. The compiler is complaining the following: error **CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute'** is not defined or im I really have no idea how to fix it. If I build it with "OutputType>exemodule net5.0 module true false false ``` Has somebody an idea, why this is not working with this project? Is this a .Net5/6 limitation? Thank you very much in advance. ### Reproduction Steps - use example project from here https://github.com/grpc/grpc-dotnet/tree/master/examples/Greeter - change OutputType to "module" in the project file ### Expected behavior compiles to .netmodule ### Actual behavior error **CS0518: Predefined type 'System.Runtime.CompilerServices.NullableAttribute'** is not defined I really have no idea how to fix it. ### Regression? Compiling to .netmodule works in .Net 4.8 version. We don't use grpc, this is completely new to our project. ### Known Workarounds no ### Configuration - tried .Net 5 and .Net 6 - Windows 10 Pro (x64) ### Other information _No response_
Author: nedy13
Assignees: -
Labels: `area-Meta`, `untriaged`
Milestone: -
KalleOlaviNiemitalo commented 2 years ago

.NET SDK 6.0.100 is able to build a netmodule that targets .NET Framework 4.8.

.NET SDK 6.0.100 is also able to build a netmodule that targets .NET 6.0, if you configure <ProduceReferenceAssembly>false</ProduceReferenceAssembly>, but I suspect the .NET Runtime won't be able to load the result. This might still be useful if you only want to generate a PE file with some Win32 resources, e.g. for Icon Table… but you need the Resource Compiler for building the resources, and if you have that, then you probably have LINK as well, and can use that instead.

ericstj commented 2 years ago

Transferring to roslyn as this issue is discussing the compiler behavior/targets.

jaredpar commented 2 years ago

Has somebody an idea, why this is not working with this project? Is this a .Net5/6 limitation?

This is not working because netmodule is not supported on .NET Core. There should be a better error here but overall what your attempting is not going to work. Even if you can get the code to compile, probably can with a bit of work, it's not going to load into the resulting runtime.

@ericstj

Transferring to roslyn as this issue is discussing the compiler behavior/targets.

Yes and no. The compiler doesn't really have a concept of target framework. It just sees a set of references. Hence the compiler can't really say "this is .NET core, hence net modules aren't supported" I think we should consider adding a feature flag to corelib that explicitly states netmodules aren't supported so we can give better errors here.

This could be done in the MSBuild task layer but not sure that will be as good of a solution.

MichalStrehovsky commented 2 years ago

Just want to point out that the runtime would not have trouble with multimodule assemblies because what the customer is trying to do is this:

So I need to compile the C# part in a .netmodule and later on it is linked together to one DLL

I assume link.exe is going to be used to link the .netmodules into a single-module-assembly and at that point the runtime doesn't mind that this was a non-assembly module at some point in the past because it's a single-module assembly now.

ericstj commented 2 years ago

This is the same way we built PresentationCore in early builds of 3.0. Using c++/CLI tool chain to link a c# netmodule worked with some build work and the runtime loaded the assembly fine. It’s not a mainline scenario for sure but it worked.

I’m not sure why references wouldn’t be providing NullableAttribute when output type changes. That’s why I transferred. It’s possible this is a an SDK issue.