使用 MSBuild 构建整个解决方案时使用 ProjectName

Use ProjectName when building an entire solution with MSBuild

而不是像

那样构建默认的文件夹结构
Solution.sln
Project1
    bin    <- project 1 output
    obj    <- project 1 intermediate output
Project2
    bin    <- project 2 output
    obj    <- project 2 intermediate output

我想像

那样构建它
Solution.sln
bin    <- project 1 AND 2 output
obj
    Project1   <- project 1 intermediate output
    Project2   <- project 2 intermediate output

我能做到

msbuild "/p:OutputPath=../bin" "/p:IntermediateOutputPath=../obj/" Test123.sln

但是,使用 "/p:IntermediateOutputPath=../obj/$(ProjectName)/" 不起作用。它不是为每个项目创建一个文件夹,而是创建一个字面上称为 $(ProjectName) 的文件夹(我读过最多,但并非所有这些宏实际上都是 Visual Studio 的东西,而不是 MSBuild 魔术)。

如何在构建时在 属性 值(例如 IntermediateOutputPath)中使用项目特定值(例如 ProjectName)?

(一些背景资料:

在解决方案级别拥有一个 bin 文件夹可以避免不必要的输出文件复制,在大型解决方案中这些文件很快就会积累超过 100 MB。此外,它使源文件夹保持干净,因此它们可以是只读的。

不过我仍然想要单独的 obj 文件夹,因为谁知道里面放的是什么 - 不同项目的文件名可能相同。)

您可以覆盖 CustomAfterMicrosoftCommonTargets property of the Microsoft.Common.targets 文件。它允许将自定义目标注入项目并执行一些操作。


构建过程的入口点是Make.targets:

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; DefaultTargets="EntryMSBuild">

    <ItemGroup>
        <Project Include="**\*.csproj"/>
    </ItemGroup>

    <Target Name="EntryMSBuild">

        <Message Text="-----Entry-----" Importance="high"/>
        <Message Text="    Rebuild    " Importance="high"/>
        <Message Text="-----Entry-----" Importance="high"/>

        <MSBuild Projects="@(Project)" Targets="rebuild" Properties="CustomBeforeMicrosoftCommonTargets=$(MSBuildThisFileDirectory)Setting.targets"/>
    </Target>

</Project>

Setting.targets 中为每个项目定义了 IntermediateOutputPathOutputPath

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <PropertyGroup>
        <IntermediateOutputPath>..\Global\obj$(MSBuildProjectName)</IntermediateOutputPath>
    </PropertyGroup>

    <PropertyGroup>
        <OutputPath>..\Global\bin\</OutputPath>
    </PropertyGroup>

</Project>

结果,您得到了想要的结构:

Solution.sln
bin    <- project 1 AND 2 output
obj
    Project1   <- project 1 intermediate output
    Project2   <- project 2 intermediate output

.net46.netstandard2.0 下的两个项目的解决方案上进行了测试。 MSBuild 15.6.82.30579


您不需要在 C:\Program Files[(x86)]\microsoft visual studio17\xxx\msbuild.0 或任何预定义路径下存储自定义目标。您覆盖已在 Microsoft.Common.targets 中定义并默认注入项目的 CustomBeforeMicrosoftCommonTargets 属性。

来自Microsoft.Common.targets 评论:

This file defines the steps in the standard build process for .NET projects. It contains all the steps that are common among the different .NET languages, such as Visual Basic, and Visual C#.