4
votes

I have a .NET Core 3 project that references several other projects. My main root project has a Release-X build configuration, but the other projects only have a Release configuration, no matching Release-X configuration.

When I try to publish my main root project using this...

dotnet publish MyProject.csproj -c Release-X

... It appears to use some mysterious non-existing default build configuration for all the referenced projects. (I can tell because the referenced projects allow unsafe code in all of their build configurations, but building with the above command results in unsafe code errors.)

I want to be able to build my main root project using its Release-X build configuration but build all referenced projects using their Release configurations. How do I do this?

1

1 Answers

1
votes

The configuration value is set as a global property which is enforced on the entire project graph until a project-to-project reference explicitly changes this.

There are three ways to deal with this, but do note that this may cause inconsistent results when building from inside Visual Studio or building the .sln file from command line due to differences in NuGet restore logic (but should be fine if you have no Conditionattribute on package or project references in your csproj that depend on $(Configuration))

  1. Set an explicit configuration for the referenced project (I suggest using this):

     <Project Sdk="Microsoft.NET.Sdk">
       ....
       <PropertyGroup>
         <ReferencedConfiguration>$(Configuration)</ReferencedConfiguration>
         <ReferencedConfiguration Condition="'$(Configuration)' == 'Release-X'">Release</ReferencedConfiguration>
       </PropertyGroup>
       <ItemGroup>
         <ProjectReference Include="..\other\project.csproj" AdditionalProperties="Configuration=$(ReferencedConfiguration)" />
       </ItemGroup>
     </Project>
    
  2. Prevent the global configuration from flowing across project-to-project references. This is not good because it will default to 'Debug' in the target project, but it is a possible way of dealing with it:

     <Project Sdk="Microsoft.NET.Sdk">
       ...
       <ItemGroup>
         <ProjectReference Include="..\other\project.csproj" UndefineProperties ="Configuration" />
       </ItemGroup>
     </Project>
    
  3. Change the referenced project to not treat "Configuration" as global property if set and overwrite it. This needs to happen before the SDK import in order to properly affect all logic that depends on it:

     <Project TreatAsLocalProperty="Configuration">
       <PropertyGroup Condition="'$(Configuration)' != '' and '$(Configuration)' != 'Debug' and '$(Configuration)' != 'Release'">
         <Configuration>Release</Configuration>
       </PropertyGroup>
       <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
    
       .... (other project content)
    
       <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
     </Project>