Search code examples
c#visual-studio-2017constantsvsprops

VS2017 Directory.Build.props doesn't load for whole solution


OK here is my problem I have 2 library and 2 project that include their .csproj (1 for Dev, 1 for Client Delivery).

I need a Defined constant to set accessible most of my class when we are with the Dev purpose (internal -> public). I used a Directory.Build.props in my dev project directory that defined a variable and my Libraries .csproj define a constant if this variable exists.

<PropertyGroup Condition ="$(ActiveIHMMode)=='true'">
    <DefineConstants>$(DefineConstants);DEV_IHM_MODE</DefineConstants>
</PropertyGroup>

I can see everything work well for my dev proj but it doesn't for my Libraries (they don't see my .props variable)

I assume there is a simple reason for it, it's because of dependencies compile order. My directory Hierarchie is the following :

LibA
LibB
ProjectDelivery
ProjectDev

My LibA is compiled first and doesn't find any Directory.Build.props because my file is in my ProjectDev Directory, but my ProjectDev as the last element to compile finds it, but it's too late for my Lib.

First time using .props and I can't see a way to resolve it. Thanks for your future help.


Solution

  • First of all, to clarify a possible confusion inferred from your title, automatically importing Directory.Build.props is not a Visual Studio 2017 feature, but a MSBuild 15 feature (which is included with VS2019).

    With my nitpicking out of the way, let's get technical:

    The problem is not your build order. The reason Directory.Build.props is only picked up in your ProjectDev project, is because MSBuild looks in the directory of the .csproj for a file called Directory.Build.props and imports it if it finds it. If it is not found, the file is searched in the parent directory. And it keeps looking for the Directory.Build.props in the parent directory until it reaches the root, or it actually finds that file and then stops, so it only automatically imports the first Directory.Build.props found.

    Your project structure, as described above, looks like this:

    /LibA/
    /LibA/LibA.csproj
    
    /LibB/
    /LibB/LibB.csproj
    
    /ProjectDelivery/
    /ProjectDelivery/ProjectDelivery.csproj
    
    /ProjectDev/
    /ProjectDev/ProjectDev.csproj
    /ProjectDev/Directory.Build.props
    

    Only ProjectDev gets the Directory.Build.props automatically imported; none of the other projects have a Directory.Build.props neither in their directory nor in any of their parent directories.

    To fix your issue you can either move the Directory.Build.props one folder up, so that it gets automatically imported by all of your projects, or you may import the Directory.Build.props manually by adding an Import element to your .csproj:

    <Project>
      <Import Project="..\ProjectDev\Directory.Build.props" />
    </Project>
    

    You can read up on more details about Directory.Build.props in the documentation.