Looking at the MSBuild 15.0 documentation and interested in learning more about the following entry:
Directory.Build.props is a user-defined file that provides customizations to projects under a directory
This isn't very specific about what directories are considered for searching for a Directory.Build.props file. Say for example I have the following directory layout:
c:\users\jaredpar\code\testtest.slnwidget\widget.csprojAlso that widget.csproj is referenced in test.sln. When I run msbuild test.sln and widget.csproj is built as a result, what directories are considered for finding Directory.Build.props and Directory.Build.targets files?
MSBuild walks the directory structure upwards from $(MSBuildProjectFullPath), stopping at the first located file in each case. For your example:
c:\users\jaredpar\code\test\widgetc:\users\jaredpar\code\testc:\users\jaredpar\codec:\users\jaredparc:\usersc:\As with most MSBuild behavior, the location of the solution file is irrelevant.
That seems like it is introducing unnecessary fragility into my build environment. Now the output, and possibly success or failure, of my build is dependent upon where on the machine a developer clones the repo. Looking at a repo on Github is no longer enough to understand how a build works, have to consider every single directory structure the code is cloned into.
If there is a stray Directory.Build.props file in their home directory then builds will suddenly, and quite silently, start changing. Will be quite difficult to track down.
This can be done both by simple developer accident or by misunderstood design. For the latter consider the act of including a .NET project via a submodule into your repo. If the outer repo has a root Directory.Build.props then there's really no way to safely submodule in another repo. Unless that repo has explicitly forbidden the use of any Directory.Build.props file.
Consider other tools which have a similar design of searching parent directories like editorconfig. They have a mechanism to stop the madness. Can put root=true to stop the searching. That mean you can at least add an .editorconfig to the root of a repo, set root=true and regain the ability to understand how the repo functions.
Is there such a feature here? Or do we just have to disable it entirely?
@jaredpar that's https://github.com/Microsoft/msbuild/issues/762; I copied your feedback over there.
@jaredpar I'm tracking this kind of feedback at #762. The current feature is on or off and you cannot give it a directory to stop traversing up. MSBuild will take the first one and give up and it would be up to you to import another one above it. You can limit the search by adding a Directory.Build.props to your root folder. If that project does not import anything else then it would assure your import graph to be what you expect.
Directory.Build.props is now documented at https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build. Feedback is welcome!
@rainersigwald
Directory.Build.props is imported very early in Microsoft.Common.props,
Is it imported before or after the 1.0 New SDK props?
That's fairly important as the 1.0 SDK overrides properties unconditionally. Hence if this happens before it's not useful in 1.0 SDK.
@jaredpar More or less "before" -- the Sdk imports Common.props very early which imports D.B.props very early, so the unconditional overriding is indeed a problem there.
What bits do I need in order to enable this feature? I add the file to my solution folder, i.e.
src\**\Some.Source\
src\**\Some.Tests\
MySolution.sln
Directory.Build.props
But to no avail. Does not seem to work.
That or third party tooling does not quite know what to do with it, either.
That is, mine looks like:
<Project>
<PropertyGroup>
<CodeGenerationRoslynPackagesVersion>0.4.49</CodeGenerationRoslynPackagesVersion>
</PropertyGroup>
</Project>
But I get messages like, Property 'CodeGenerationRoslynPackagesVersion' is not defined.
Is there anything else I need to do besides specify the file?
Could we get a sample on that documentation page that shows how to discriminate around the project type?
I'd like to setup my Directory.Build.props with default settings for my csproj/fsproj but I'm not sure how to figure that information from a msbuild file.
@smoothdeveloper Yes, that's a good request. To answer quickly: compare $(MSBuildProjectExtension) against, for example, ".csproj".
@rainersigwald thanks a lot that does the trick!
<PropertyGroup Condition="'$(MSBuildProjectExtension)' == '.fsproj'">
...
@rainersigwald I tried to use Directory.Build.props with .net framework project, but is did not work.
Is it possible to use Directory.Build.props with .net framework? Or maybe I did not use it correctly.
You could refer to https://github.com/ChuckTest/ConcurrentTest/tree/test on branch test , I have tried to work with Directory.Build.props.
@chucklu Yes, you can use Directory.Build.props with that kind of project. However, Version is a property that is used by the .NET Core SDK and isn't respected by the project you have there.
Thanks @rainersigwald, then which property I supposed to use for .net framework to control the version of the compiled assembly? Is there a documentation about the properties list can be used for .net framework or .net core?
@chucklu there is no such property for projects that don't use the .NET Core SDK. Defining it as a property is a feature of that SDK.
Most helpful comment
Directory.Build.propsis now documented at https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build. Feedback is welcome!