Visual Studio 如何调用msbuild项目的目标而不递归调用子项目上的同一目标

new9mtju  于 2022-12-30  发布在  其他
关注(0)|答案(1)|浏览(178)

我在msbuild项目中创建了一堆目标。让我们称这个项目为TopLevelProject。让我们假设它有一个名为CollectNZip的目标。TopLevelProject依赖于SubProjectA,SubProjectB和SubProjectC。
我有一个解决方案目标文件Directory.solution.targets,它包含了其文件夹下的所有项目,包括TopLevelProject。
作为这个文件中目标的一部分,比如说BuildAll,我喜欢调用TopLevelProject的CollectNZip目标。所以我添加了TopLevelProject:CollectNZip作为依赖项。
当我调用BuildAll时,我确实看到TopLevelProject是用目标CollectNZip调用的。但是这个笨蛋作为依赖的一部分开始调用SubProjectA:CollectNZip、SubProjectB:CollectNZip等。由于这些子项目没有CollectNZip,所以buildall目标失败。
调用项目的目标,但不调用子项目作为调用的一部分,有什么诀窍?

332nm8kg

332nm8kg1#

如果我理解这个场景:

  • 有一个包含一组项目的解决方案文件。假设该解决方案名为"MySolution.sln"。
  • 我假设解决方案文件是由VisualStudio或dotnet工具创建的。
  • 解决方案中的项目集包括:"顶层项目. csproj"、"子项目A. csproj"、"子项目B. csproj"和"子项目C. csproj"。
  • 我假设项目文件是由Visual Studio或dotnet工具创建为C#项目的。
  • 项目"TopLevelProject"与"子项目A"、"子项目B"和"子项目C"之间的距离为ProjectReference
  • 项目"TopLevelProject"还有一个名为"CollectNZip"的目标。
  • 有一个"Directory.Solution.targets"文件是"MySolution.sln"的对等项或位于父目录中。
  • "目录.解决方案.目标"包含"BuildAll"目标。

Visual Studio忽略"Directory.Solution.targets"文件,因此"BuildAll"目标仅在从命令行运行时可用。
项目可以添加到解决方案文件(SLN),但不能添加到MSBuild文件。"Directory. Solution. targets"文件是MSBuild文件。它不能是项目的容器。我不知道以下语句的含义:
我有一个解决方案目标文件Directory.solution.targets,它包含了其文件夹下的所有项目,包括TopLevelProject。
注意,Import元素是一个文本包含,它并不"添加"一个项目;它将Project属性中的文件内容添加到当前项目的内容中。
在命令行中,可以通过解决方案文件调用项目"TopLevelProject"的"CollectNZip"目标。
例如:

msbuild MySolution.sln /t:TopLevelProject:CollectNZip

这将仅对TopLevelProject项目调用"CollectNZip"目标。它不会运行解决方案中的其他项目。
我不知道下面这句话是什么意思:
作为这个文件中目标的一部分,比如说BuildAll,我喜欢调用TopLevelProject的CollectNZip目标。所以我添加了TopLevelProject:CollectNZip作为依赖项。
命令行/target开关支持<ProjectName>:<TargetName>语法。MSBuild文件的代码不支持该语法。TopLevelProject:CollectNZip不能是目标的依赖项。
MSBuild没有任何"子项目"的概念,尽管有两种机制可以在项目之间添加依赖关系。
项目依赖项可以添加到解决方案文件中。解决方案级别的项目依赖项影响生成顺序--不做其他任何事情。它不共享文件。
ProjectReference可以添加到项目文件中。ProjectReference是一个ItemGroup,并且是在常规MSBuild生成引擎上生成的C#项目生成系统的一部分。ProjectReference特定于C#生成系统的某些目标。最重要的是buildclean目标。buildclean将评估ProjectReference ItemGroup,将运行引用的项目,并且在build上将复制到引用项目的产品中。
如果我将名为"Fred"的目标添加到所有项目,并通过解决方案在一个项目上调用"Fred",则不会在ProjectReference ItemGroup中的项目上调用"Fred"。
一个项目是一个封装,它不知道它的"调用者",除了ProjectReference,它不知道其他的项目。
所描述的行为不是MSBuild的工作方式,我猜描述不准确和/或没有显示相关代码。
如果"CollectNZip"应仅在"TopLevelProject"项目中运行,则仅将目标添加到该项目中。如果希望能够使用和不使用"CollectNZip"执行build,请定义可用作标志的属性,例如,添加"EnableCollectNZip"属性,并在测试"EnableCollectNZip"属性值的目标上添加Condition

相关问题