如何从 MSBUILD 覆盖 .NET 中引用的 CopyLocal(私有)设置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1682096/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:32:06  来源:igfitidea点击:

How do I override CopyLocal (Private) setting for references in .NET from MSBUILD

.netmsbuild

提问by David Hay

I have been wrestling with this for a few days and after tons of searching I can't find the path I should be on.

我已经为此苦苦挣扎了几天,经过大量搜索后,我找不到应该走的路。

What I want to do is set up an MSBUILD project that will build our entire .NET application (constst of 8 solutions, and maybe 250 projects split up between them) with a number of settings overridden from the individual project files to make a debug build for myself.

我想要做的是建立一个 MSBUILD 项目,该项目将构建我们的整个 .NET 应用程序(8 个解决方案的组合,并且可能在它们之间拆分 250 个项目),并从单个项目文件中覆盖许多设置以进行调试构建为了我自己。

Specifically I want to build our release configuration with optimizations off and full debug info / pdbs generated. Also, in order to reduce our currently ultra-long build time I want "copy local" (or private in the actual proj file xml) false for every reference of every project.

具体来说,我想通过关闭优化和生成完整的调试信息/pdbs 来构建我们的发布配置。此外,为了减少我们目前超长的构建时间,我希望每个项目的每个引用都“复制本地”(或实际项目文件 xml 中的私有)为 false。

The first things were fairly easy, I can override a project level property fairly easily (you can even do this from the MSBuild command line using /p), but what I can't figure out is how to override a property on a reference. I have tried several things I saw here on StackOverflow and around the web, but nothing is a solution yet.

第一件事相当简单,我可以很容易地覆盖项目级别的属性(您甚至可以使用 /p 从 MSBuild 命令行执行此操作),但我无法弄清楚如何覆盖引用上的属性。我已经尝试了一些我在 StackOverflow 和网络上看到的东西,但还没有解决方案。

I can do what I want by altering Microsoft.Common.targets, commenting out the code in the _CopyFilesMarkedCopyLocal target completely skips the copying of these files. But I don't want to alter my global configuration and do this in all circumstances. I created my own alternate targets file -- which works if I alter an individual project file to point to it -- but I can't figure out how to specify this to be used at the top level (my .proj file that just builds all 8 solutions). It would be great if I could somehow override just the _CopyFilesMarkedCopyLocal target at the top level so that if MS changes the default targets file my build isn't screwed up, but I can't figure out how to make this work either.

我可以通过更改 Microsoft.Common.targets 来做我想做的事,注释掉 _CopyFilesMarkedCopyLocal 目标中的代码完全跳过这些文件的复制。但我不想改变我的全局配置并在所有情况下都这样做。我创建了我自己的备用目标文件——如果我改变一个单独的项目文件来指向它,它就可以工作——但我不知道如何指定它在顶层使用(我刚刚构建的 .proj 文件所有 8 个解决方案)。如果我能以某种方式覆盖顶层的 _CopyFilesMarkedCopyLocal 目标,那么如果 MS 更改默认目标文件,我的构建不会搞砸,那就太好了,但我也无法弄清楚如何进行这项工作。

The best possible thing would be if there was a way to just override reference level properties like you can project level properties, without having to rewrite/override the build targets stuff -- but I have found no information indicating this is possible.

最好的办法是,如果有一种方法可以像您可以投影级别属性那样仅覆盖参考级别属性,而不必重写/覆盖构建目标的内容——但我没有发现任何信息表明这是可能的。

Thanks in advance for any help on this.

提前感谢您对此的任何帮助。

P.S. It is not possible for me to actually just go through all the projects files and change them; I need a solution that leaves the existing code in place as is.

PS 我不可能真正浏览所有项目文件并更改它们;我需要一个解决方案,让现有代码保持原样。

回答by Sayed Ibrahim Hashimi

Try this:

尝试这个:

Set the CustomAfterMicrosoftCommonTargetsto C:\foo\filter.targets (or whatever you name the file)and have filter.targets to be:

CustomAfterMicrosoftCommonTargets设置为 C:\foo\ filter.targets (或任何您命名文件的名称)并将 filter.targets 设置为:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <ItemDefinitionGroup>
      <Reference>
        <Private>False</Private>
      </Reference>
    </ItemDefinitionGroup>
</Project>

回答by radical

In a file like filter.targets add a target:

在像 filter.targets 这样的文件中添加一个目标:

<Target Name="BeforeBuild">
  <ItemGroup>
        <ReferenceNew Include="@(Reference)">
           <Private>False</Private>
        </ReferenceNew>
        <Reference Remove="@(Reference)"/>
        <Reference Include="@(ReferenceNew)"/>
  </ItemGroup>
</Target>

This will recreate the @(Reference) list to have the metadata 'Private' set to false, which will ensure that the reference doesn't get copied. Then run build your solution or project with the property $(CustomAfterMicrosoftCommonTargets) set to the path to this filter.targets file.

这将重新创建 @(Reference) 列表,将元数据“Private”设置为 false,这将确保引用不会被复制。然后运行构建您的解决方案或项目,并将属性 $(CustomAfterMicrosoftCommonTargets) 设置为此 filter.targets 文件的路径。

msbuild foo.sln /p:CustomAfterMicrosoftCommonTargets=c:\foo\filter.targets

This way, the BeforeBuild target will get invoked before building the project, and all references will be set accordingly. If you want more control over when or whether Private should be false or true, you can alter the BeforeBuild target and control that via properties.

这样,在构建项目之前将调用 BeforeBuild 目标,并且将相应地设置所有引用。如果您想更多地控制 Private 何时或是否应为 false 或 true,您可以更改 BeforeBuild 目标并通过属性控制它。

Edit: There might be a better way to set the metadata in the BeforeBuild target.

编辑:可能有更好的方法来设置 BeforeBuild 目标中的元数据。

回答by gReX

Starting with msbuild v 15 you can copy a single file called Directory.Build.propsin the root folder that contains your source.

从 msbuild v 15 开始,您可以在包含源的根文件夹中复制一个名为Directory.Build.props的文件。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemDefinitionGroup>
  <Reference>
    <Private>False</Private>
  </Reference>
</ItemDefinitionGroup>
</Project>

This works well with Visual Studio 2017 and the vNext Build. May you have to close Visual Studio and than open your solution again to take the file effect.

这适用于 Visual Studio 2017 和 vNext Build。可能您必须关闭 Visual Studio,然后再次打开您的解决方案才能使文件生效。

https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-and-directorybuildtargets

https://docs.microsoft.com/en-us/visualstudio/msbuild/customize-your-build#directorybuildprops-and-directorybuildtargets