0

I have a solution that contains a console application with a .csproj file like the this:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp1.1</TargetFramework>
  </PropertyGroup>
</Project>

I also have a library project that uses the console application to generate a heap of C# code that get compiled into the library, the library .csproj file looks like this.

<Project Sdk="Microsoft.NET.Sdk" InitialTargets="RunGenerator">
  <PropertyGroup>
    <TargetFramework>netstandard1.4</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="../generator/generator.csproj">
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
    </ProjectReference>
  </ItemGroup>
  <Target Name="RunGenerator">
    <Exec Command="dotnet run -p &quot;../generator/generator.csproj&quot; input output" /> 
  </Target>
</Project>

This fails because the dependency analysis says that a netstandard1.4 assembly cannot reference a netcoreapp1.1 assembly. That is correct except that I am not referencing the assembly.

I can work around that issue by building the generator project like this:

<Project Sdk="Microsoft.NET.Sdk" InitialTargets="RunGenerator">
  <PropertyGroup>
    <TargetFramework>netstandard1.4</TargetFramework>
  </PropertyGroup>
  <Target Name="RunGenerator">
    <Exec Command="dotnet build &quot;../generator/generator.csproj&quot;" />
    <Exec Command="dotnet run -p &quot;../generator/generator.csproj&quot; input output" /> 
  </Target>
</Project>

The problem is that the generator project no longer takes part in the dependency analysis when these projects are built using the containing solution file and the explicit build of the generator project sometimes runs concurrently with another build of the same project initiated by the solution build and this results in errors because files are locked etc.

Is it possible to have a project dependency without checking the target framework?

Can anyone suggest a workaround?

Thanks.

Gary
  • 5,642
  • 1
  • 21
  • 41

1 Answers1

1

Here are some MSBuild tips. You might need to combine a few of these ideas.

  1. You can use your solution file to add an explicit project dependency. See https://learn.microsoft.com/en-us/visualstudio/ide/how-to-create-and-remove-project-dependencies (This question was originally asked here: Visual Studio 2010: How to enforce build order of projects in a solution?). Unfortunately, this is really hard to do if you don't have VS. The format is .sln files is kinda a nightmare.

  2. To avoid the concurrent build issue, use the MSBuild task instead of the Exec task. See https://learn.microsoft.com/en-us/visualstudio/msbuild/msbuild-task


    <Target Name="CompileAnotherProject">
       <MSBuild Projects="../generator/generator.csproj" Targets="Build" />
    </Target>
  1. dotnet-run invokes "dotnet build" automatically. This is actually problematic in concurrent builds. You can instead add a target to your generator.csproj that runs the app after it has been built. "dotnet filepath.dll" runs the compiled app without building it.

    <Target Name="RunCodeGen" AfterTargets="Build">
         <Exec Command="dotnet $(AssemblyName).dll input output"
           WorkingDirectory="$(OutDir)" />    
    </Target>
Community
  • 1
  • 1
natemcmaster
  • 25,673
  • 6
  • 78
  • 100