代码之家  ›  专栏  ›  技术社区  ›  Benjamin Baumann

自定义公共目标以构建解决方案

  •  10
  • Benjamin Baumann  · 技术社区  · 16 年前

    error MSB4057: The target "RealClean" does not exist in the project.
    

    下面是我输入的运行MsBuild的命令行

    C:\Windows\Microsoft .NET\Framework\v3.5\MsBuild.exe /p:Configuration="Release";OutputPath="..\..\MSBuild.Referentiel.net35";nowarn="1591,1573" /t:RealClean mySolution.sln
    

    3 回复  |  直到 16 年前
        1
  •  5
  •   Julien Hoarau    16 年前

    为了处理解决方案文件,MSBuild创建一个临时MSBuild项目文件,其中只包含一些目标,如 建造 . 所以不能在解决方案文件中调用自定义目标。

        2
  •  16
  •   Ade Miller    15 年前

    我做了三件事:

    1) 创建了一个自定义目标文件,通过向每个项目文件添加以下内容,将其导入到解决方案中的每个C#和/或VB/F#项目中:

    <!-- Rest of project file -->
    
    <PropertyGroup Condition="'$(SolutionDir)' == '' or '$(SolutionDir)' == '*undefined*'">
        <!-- Relative path to containing solution folder -->
        <SolutionDir>..\</SolutionDir>
    </PropertyGroup>
    <Import Project="$(SolutionDir)CommonSettings.targets" />
    

    2) 添加了一个在真正的clean之后调用的clean目标(使用MSBuild 4.0中的AfterTargets属性):

    <Target Name="CleanCs" AfterTargets="Clean">
        <Message Text="Deep cleaning C# project..." />
        <CreateItem Include="$(OutDir)**\*.*; $(ProjectDir)\obj\**\*.*; $(IntermediateOutputPath)**\*.*"
                                Exclude="**\bin\**\*.vshost.exe; $(IntermediateOutputPath)**\*.log">
            <Output TaskParameter="Include" ItemName="AfterClean_FilesToDelete"/>
        </CreateItem>
        <Delete Files="@(AfterClean_FilesToDelete)" />
        <CreateItem Include="$(ProjectDir)\obj\" >
            <Output TaskParameter="Include" ItemName="AfterClean_DirectoriesToDelete" />
        </CreateItem>
        <CreateItem Include ="$(ProjectDir)\bin\" Condition="'$(TargetExt)' != '.exe'" >
            <Output TaskParameter="Include" ItemName="AfterClean_DirectoriesToDelete"/>
        </CreateItem>
        <RemoveDir ContinueOnError="true" Directories="@(AfterClean_DirectoriesToDelete)" />
    </Target>
    

    3) 在我的持续集成MSBuild项目中,我检查并确保所有项目文件都有#1:

    <ItemGroup>
        <!-- Exclude viewer acceptance tests as they must compile as x86 -->
        <CheckProjects_CsProjects Include="**\*.csproj" />
    </ItemGroup>
    <Target Name="CheckProjects">
        <!-- 
            Look for C# projects that don't import CommonSettingsCs.targets 
        -->
        <XmlRead XPath="//n:Project[count(n:Import[@Project[contains(string(), 'CommonSettingsCs.targets')]]) = 0]/n:PropertyGroup/n:AssemblyName/text() "
            XmlFileName="%(CheckProjects_CsProjects.Identity)"
            Namespace="http://schemas.microsoft.com/developer/msbuild/2003"
            Prefix="n" >
            <Output TaskParameter="Value" ItemName="CheckProjects_CsMissingImports"/>
        </XmlRead>
        <Error Text="Project missing CommonSettingsCs.targets: %(CheckProjects_CsMissingImports.Identity)"
                     Condition="'%(CheckProjects_CsMissingImports.Identity)' != ''" />
    </Target>
    

    这样可以防止开发人员忘记添加#1。您可以创建自己的项目模板,以确保默认情况下所有新项目都具有此模板。

        3
  •  5
  •   Sayed Ibrahim Hashimi    16 年前

    马德格诺也许是对的。但是我想补充一点,您不应该编辑Microsoft.common.targets文件。如果你这样做,你就有可能在那台机器上有一个不同于其他人的构建过程。在您的例子中,您可以创建一个新的MSBuild文件,只使用RealClean目标并将其放置在 或32位 C:\Program Files\MSBuild\v4.0\Custom.After.Microsoft.Common.targets 本质上,这与将该文件放在Microsoft.Common.targets中是一样的,只是您不必修改该文件。