使用MSBuild生成目标,然后在同一会话中导入它们 [英] Generate targets with MSBuild then import them in same session

查看:170
本文介绍了使用MSBuild生成目标,然后在同一会话中导入它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个MSBuild项目文件,它会生成一些自己的目标,然后导入它们。它运行良好,除了 msbuild 必须运行两次才能执行build-once来生成规则,并再次让它们可见以完成构建。 (逻辑是从 Makefile 移植的,它本身只需要一次运行。)

I have an MSBuild project file that generates some of its own targets, then imports them. It works nicely, except that msbuild has to be run twice to do the build—once to generate the rules and again for them to be visible to finish the build. (The logic was ported from a Makefile that itself only needed one run.)

是否可以运行生成目标,然后 导入然后运行生成的目标之一?

Is it possible to run the generating target, then Import, then run one of the generated targets?

以下列表是实际用例的一个简单版本,它表现出相同的行为。 (除此之外,实际案例从模式 * - to - * .xsl 的文件名列表生成目标,使用该名称自动确定依赖关系和目标。 )

The following listing is a trivialized version of the actual use case which exhibits the same behavior. (Beside the point, the actual case generates targets from a list of filenames of the pattern *-to-*.xsl, using the name to automatically determine the dependency and destination.)

目标是让 msbuild / t:SecondTarget 在第一次尝试时工作而不是需要一秒钟。

The objective is to make msbuild /t:SecondTarget work on the first try instead of requiring a second.

<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>


推荐答案

我认为这不可行。通过设计调用任务时,它没有项目的整个上下文。它只是传递给它的东西。它是以这种方式设计的(至少有一个原因),因此任务调用不会产生难以识别的无法预料的后果。

I don't think this is possible. By design when calling a task it does not have the entire context of the project. It just has what is passed in to it. It's designed this way (at least one reason) so that task invocations cannot have unforeseen consequences which are hard to identify.

这篇关于使用MSBuild生成目标,然后在同一会话中导入它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆