MSBuild to compile assemblies for Net6.0

972 Views Asked by At

To build our application, we have a structure of several MSBuild proj files, which currently compile libraries on .NET Framework.

Now we want to move the solution to .Net 6.0, however the task we use ("Csc") give us many errors when using the same parameters. Looks that is not made to make Net6.0 assemblies from MSBuild.

To clarify, this is not just one project, but a hierarchy of projects:

  1. Project1 has a Build Target that DependsOn on Project2.

  2. Project2 has a Build Target that DependsOn Project3.

  3. Project3 executes some custom task which generates CS files, and compiles them into a Library, that is then used by Project2.

Everything is done vie msbuild proj files, like:

Project1.proj:

<Project DefaultTargets = "Build">
   <Target Name = "BusinessRuless">
    <MSBuild Projects=".\Project2.proj" Targets="Build" />
  </Target>   
  <Target Name = "Build" DependsOn ="BusinessRuless">
    <CSC Sources = "@(CSFile)"
            References="$(dlls);"
            DebugType="full"
            DefineConstants="TRACE"
            TargetType="library"
            EmitDebugInformation="true"
            TreatWarningsAsErrors="true"
            OutputAssembly = "$(dllFileName).dll">
        </CSC>
  </Target>
...

When the CSC task starts, it invokes the correct csc compiler:

C:\Program Files\Microsoft Visual Studio\2022<version>\MSBuild\Current\Bin\Roslyn\csc.exe

However, it throws errors as if the basic system assemblies are not referenced:

CSC : error CS0518: Predefined type 'System.Void' is not defined or imported [....proj]

So in summary the question is : Is there any recipe to use MSBuild to build projects targeting Net6.0?

Do i need to explicity reference all the foundational dlls from Nuget?

BTW: I tried adding one of them, like "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\6.0.9\ref\net6.0\System.Runtime.dll", but the same error shows up : Predefined type 'System.Void' is not defined or imported

We dont use Visual Studio for the building of our libraries, just MSBuild.

Thanks a Lot!

1

There are 1 best solutions below

2
D.Firka On

Finally i was a able to do it, here is what i found:

1- Get the dotnet location of the assemblies. I use the following fragment to get the dotnet folder:

<Choose>
    <When Condition=" '$(DOTNET_ROOT)'=='' ">
      <PropertyGroup>
        <DotNetRoot>$(ProgramFiles)\dotnet</DotNetRoot>
      </PropertyGroup>
    </When>
    <Otherwise>
      <PropertyGroup>
        <DotNetRoot>$(DOTNET_ROOT)</DotNetRoot>
      </PropertyGroup>
    </Otherwise>
  </Choose>

Then creating a property to the location of the assemblies (dont know still where to get the version number, so it is hardcoded)

<PropertyGroup>
    <TargetFrameworkMoniker>.NETCoreApp,Version=v6.0</TargetFrameworkMoniker>
    <TargetFramework>net6.0</TargetFramework>
    <DotNetAssemblies>$(DotNetRoot)\packs\Microsoft.NETCore.App.Ref\6.0.9\ref\net6.0</DotNetAssemblies>
</PropertyGroup>

2- Prevent CSC task from using the standard libraries, using NoStandardLib="true"

3- Allow nullable by using Nullable="enable"

4- Adding specific references to the standard libraries used by the CS files.

In summary, the CSC Task looks like:

<CSC Sources="@(CSFile)" References="...$(dotNetAssemblies)\System.Runtime.dll;$(dotNetAssemblies)\System.dll;$(dotNetAssemblies)\System.Threading.Tasks.dll;"  
         DebugType="full" TargetType="library" EmitDebugInformation="true" TreatWarningsAsErrors="true" OutputAssembly="$(dllFileName).dll"
         NoStandardLib="true" Nullable="enable">
</CSC>