我有一个MSBuild项目文件,它会生成一些自己的目标,然后导入它们。它运行良好,除了msbuild
必须运行两次才能执行构建一次以生成规则,并再次使它们可见以完成构建。 (逻辑是从一个本身只需要一次运行的Makefile
移植而来的。)
是否可以运行生成目标然后 Import
,然后运行其中一个生成的目标?
以下列表是实际用例的一个简单版本,它表现出相同的行为。 (除此之外,实际案例从模式*-to-*.xsl
的文件名列表生成目标,使用名称自动确定依赖关系和目标。)
目标是让msbuild /t:SecondTarget
在第一次尝试时起作用,而不是需要一秒钟。
<Project
xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
InitialTargets="AdditionalTargets"
ToolsVersion="4.0">
<!--
A trivial target-generating task. Presume something more useful for
the actual case.
-->
<UsingTask
TaskName="GenerateAdditionalTargets"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Result ParameterType="System.String" Output="true"/>
</ParameterGroup>
<Task>
<Reference Include="System.Xml"/>
<Reference Include="System.Xml.Linq"/>
<Using Namespace="System"/>
<Using Namespace="System.Xml.Linq"/>
<Code Type="Fragment" Language="cs"><![CDATA[
var ns = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");
var collected = new XElement(ns + "Project",
new XAttribute("ToolsVersion", "4.0"),
new XElement(ns + "Target",
new XAttribute("Name", "SecondTarget"),
new XElement(ns + "Message",
new XAttribute("Text", "1.21GW?!")
)
)
);
Result = collected.ToString(SaveOptions.DisableFormatting);
]]></Code>
</Task>
</UsingTask>
<PropertyGroup>
<AdditionalTargets>additional.targets</AdditionalTargets>
</PropertyGroup>
<Target Name="AdditionalTargets">
<GenerateAdditionalTargets>
<Output TaskParameter="Result" PropertyName="Targets"/>
</GenerateAdditionalTargets>
<WriteLinesToFile File="$(AdditionalTargets)" Lines="$(Targets)" Overwrite="true"/>
</Target>
<Import Project="$(AdditionalTargets)" Condition="Exists('$(AdditionalTargets)')"/>
</Project>
答案 0 :(得分:1)
我不认为这是可能的。通过设计调用任务时,它没有项目的整个上下文。它只是传递给它的东西。它是以这种方式设计的(至少有一个原因),因此任务调用不会产生难以识别的无法预料的后果。