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

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

Open
lock9 opened this issue Feb 8, 2024 · 9 comments

Comments

@lock9
Copy link
Contributor

lock9 commented Feb 8, 2024

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:

  • Shouldn't it be backward compatible?
  • Is this a problem with how we distribute the compiler?
  • If we distribute it as a simple DLL, will a .NET 7 DLL work if invoked using .NET 8?

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
Copy link
Contributor

Jim8y commented Feb 8, 2024

dotnet standard?

@lock9
Copy link
Contributor Author

lock9 commented Feb 8, 2024

image

Could you elaborate? My .NET experience is limited

@cschuchardt88
Copy link
Member

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
Copy link
Contributor Author

lock9 commented Feb 9, 2024

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:

  • Allow .NET to download the compiler automatically (it downloads it when you run build or restore)
  • Allow users to configure the compiler they are using

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
Copy link
Contributor Author

lock9 commented Feb 9, 2024

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
Copy link
Member

cschuchardt88 commented Feb 9, 2024

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
Copy link
Contributor Author

lock9 commented Feb 9, 2024

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:

  • Shouldn't it be backward compatible? Shouldn't .NET 7.0 work with .NET 8.0?
  • .NET 7 is not a LTS version. Should we migrate it to the newest LTS version? (.NET 8)
  • 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?

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

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

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
Copy link
Member

cschuchardt88 commented Feb 9, 2024

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
Copy link
Member

shargon commented Feb 21, 2024

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

Yes. We should move to .net8

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

4 participants