neo-project / neo-devpack-dotnet

NEO Development Pack
MIT License
79 stars 101 forks source link

How can we avoid problems with different .NET versions? What's the best way to distribute the compiler? #886

Open lock9 opened 7 months ago

lock9 commented 7 months ago

Hi,

One issue we almost always see when testing C# with new developers is errors related to .NET versions. You may not notice this because you likely have multiple .NET versions installed.

Situation: During a test, a user had .NET 8 installed and had to install .NET 7 to use the compiler. According to his report, he tried to install the compiler using the dotnet tool. It failed because he didn't have .NET 7.0. He had to install it to use the compiler.

Questions:

In order to allow the compiler to be automatically downloaded, we were adding it to the NuGet dependencies and invoking it like this in the post build process:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <NeoCompilerCSharpVersion>3.6.2</NeoCompilerCSharpVersion>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Neo.SmartContract.Framework" Version="$(NeoCompilerCSharpVersion)" />
        <PackageReference Include="Neo.Compiler.CSharp" Version="$(NeoCompilerCSharpVersion)" />
    </ItemGroup>
    <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="dotnet $(NuGetPackageRoot)neo.compiler.csharp/$(NeoCompilerCSharpVersion)/tools/$(TargetFramework)/any/nccs.dll $(ProjectDir)" />
    </Target>
</Project>

Note: I have .NET 7.0 installed. However, this used to work.. I guess? Or we were using some other dll. What I know is that today, it doesn't work:

The error:

Coin.csproj : error NU1202: Package Neo.Compiler.CSharp 3.6.2 is not compatible with net7.0 (.NETCoreApp,Version=v7.0). Package Neo.Compiler.CSharp 3.6.2 supports: net7.0 (.NETCoreApp,Version=v7.0) 

And this error:

error NU1212: Invalid project-package combination for Neo.Compiler.CSharp 3.6.2. DotnetToolReference project style can only contain references of the DotnetTool type

I'm not really sure what the problem is or how to solve it. Even writing this message was hard for me. Can someone enlighten me?

Jim8y commented 7 months ago

dotnet standard?

lock9 commented 7 months ago

image

Could you elaborate? My .NET experience is limited

cschuchardt88 commented 7 months ago

What is this?

<Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="dotnet $(NuGetPackageRoot)neo.compiler.csharp/$(NeoCompilerCSharpVersion)/tools/$(TargetFramework)/any/nccs.dll $(ProjectDir)" />
    </Target>

Create directory called .config where solution file is or project file. and use file below. https://github.com/cschuchardt88/neo-examples-csharp/tree/master/.config

But remove

"neo.express": {
      "version": "3.5.20",
      "commands": [
        "neoxp"
      ]
    }

then add below to your *.csproj

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="dotnet nccs &quot;$(MSBuildProjectFile)&quot; -o &quot;$(SolutionDir)sc&quot;" />
  </Target>
lock9 commented 7 months ago

Hi @cschuchardt88,

This part is important:

...
        <PackageReference Include="Neo.Compiler.CSharp" Version="$(NeoCompilerCSharpVersion)" />
...
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="dotnet $(NuGetPackageRoot)neo.compiler.csharp/$(NeoCompilerCSharpVersion)/tools/$(TargetFramework)/any/nccs.dll $(ProjectDir)" />
    </Target>

There are two reasons for this:

There are problems when we request users to use nccs directly from the command line. 1 - Sometimes, it refuses to install (incompatible .net version) 2 - It's not possible to use different versions of the compiler in different projects. If you or Jimmy are making changes, you won't be able to use it easily using a global nccs instance (unless you replace it globally)

lock9 commented 7 months ago

I've got this error: Run "dotnet tool restore" to make the "nccs" command available.

Then, after using the command, it worked, but it was 'manually' (using the dotnet tool restore command).

I wondered if we could do that without using it as a tool. The compiler is not a .NET tool. It's just a DLL. It would be easier to use the version in the csproj file instead of requiring another folder with a configuration file.

I did another test using this configuration, and it worked. The problem is that the project can't have it as a dependency because it's a tool. I don't know how I installed it using nuget before, but somehow, I did it... and it worked.

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <NeoCompilerCSharpVersion>3.6.2</NeoCompilerCSharpVersion>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Neo.SmartContract.Framework" Version="$(NeoCompilerCSharpVersion)" />
        <!-- <PackageReference Include="Neo.Compiler.CSharp" Version="$(NeoCompilerCSharpVersion)" /> -->
    </ItemGroup>
    <Target Name="PostBuild" AfterTargets="PostBuildEvent">
        <Exec Command="dotnet $(NuGetPackageRoot)neo.compiler.csharp/$(NeoCompilerCSharpVersion)/tools/$(TargetFramework)/any/nccs.dll $(ProjectDir)" />
    </Target>
</Project>

The DLL is there, and this command works. The only line causing issues is the package reference: <!-- <PackageReference Include="Neo.Compiler.CSharp" Version="$(NeoCompilerCSharpVersion)" /> -->

 error NU1212: Invalid project-package combination for Neo.Compiler.CSharp 3.6.2. DotnetToolReference project style can only contain references of the DotnetTool type

Maybe we could release another package that is not shipped as a tool? Or is it possible that the same package can be tweaked to work as a tool and as a DLL? It already works... it just need to let me download it 😂

cschuchardt88 commented 7 months ago

Please Completely Read and Try it

If you listen and do what I am saying. Your problems will go away. You need to create .config folder where your *.csproj or *.sln is. You can do this two ways with dotnet cli or right click and add new folder. Once you have that folder you need dotnet-tools.json file and again you can create with dotnet cli or right click and add new file.....

No need to dotnet tool restore anymore. You can copy and paste .config folder to the root of any project or the root of you drive. You can edit the configuration to whatever version you want, even in different projects; They can have different versions. It uses the .config folder version even if your have it installed globally.

Directory Layout

C:.
|   AppLog.sln
|
+---.config
|       dotnet-tools.json
|
\---AppLog
        AppLog.csproj
        Contract1.cs
> dotnet new tool-manifest

The template "Dotnet local tool manifest file" was created successfully.
> dotnet tool install neo.compiler.csharp

Skipping NuGet package signature verification.
You can invoke the tool from this directory using the following commands: 'dotnet tool run nccs' or 'dotnet nccs'.
Tool 'neo.compiler.csharp' (version '3.6.2') was successfully installed. Entry is added to the manifest file 
> dotnet build

MSBuild version 17.8.3+195e7f5a3 for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  AppLog -> AppLog\bin\Debug\net7.0\AppLog.dll
    Determining projects to restore...
    All projects are up-to-date for restore.
  Compilation completed successfully.

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:03.64

Add to your *.csproj

  <Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <Exec Command="dotnet nccs &quot;$(MSBuildProjectFile)&quot; -o &quot;$(SolutionDir)sc&quot;" />
  </Target>

Welcome to dotnet.

lock9 commented 7 months ago

Hi. I can make it work. The problem is that I've got a report from a user using .NET 8.0 that he was unable to use the compiler without installing .NET 7.0. I'm also unable to use it as a project dependency. It requires extra steps to install / restore a tool.

A few questions:

Another issue is that the compiler is distributed as a tool. You can't add it as a dependency to your project.

When users visit Microsoft to download .NET, it recommends .NET 8.0. The same happens if you install it using the command line. Shouldn't the compiler work with the latest .NET version?

cschuchardt88 commented 7 months ago

Shouldn't it be backward compatible? Shouldn't .NET 7.0 work with .NET 8.0?

Should be, with dotnet core i dont think so.

.NET 7 is not a LTS version. Should we migrate it to the newest LTS version? (.NET 8)

We are moving to standard

About .NET Standard, that can be a good path. However, I've tried a bit, and it seems it will demand major refactoring due to the multiple dependencies. Would it be possible just to include other supported frameworks? Instead of refactoring all projects to use .NET Standard?

We already started the process.... Looks it done already

Would it be possible to create a different release that can be used as a project dependency, not a tool?

We are working on that too.

shargon commented 7 months ago

.NET 7 is not a LTS version. Should we migrate it to the newest LTS version? (.NET 8)

Yes. We should move to .net8