首页 > 解决方案 > 如何让 MSBuild 检测输出输入工具链依赖关系

问题描述

tl;博士

我将一个工具(MIDL)的输出作为输入添加到项目中的另一个工具(我的)。现在 MSBuild 不再正确跟踪 MIDL 输出。

很长的故事

我添加PIATest.idl了一个 Visual Studio C++ 项目。该文件PIATest.tlb使用 MIDL 编译成。如果我删除PIATest.tlb并构建项目(不重新构建!),则 MIDL 会自动再次调用以构建缺少的PIATest.tlb,如预期的那样。此后,该项目将保持最新状态。

现在我将 PIATest.tlb作为文件添加到项目中,因为我已经设置了 Visual Studio 属性页并构建了允许我自定义调用tlbimp.exe以创建主互操作程序集的目标。这一切都很好;如果我编译 PIATest.tlb然后tlbimp.exe创建一个主互操作 dll,如果我修改PIATest.idl然后 MIDL 并且tlbimp.exe都以正确的顺序调用。

但是,如果我现在删除PIATest.tlb,则不再重建。似乎因为PIATest.tlb已添加到项目中,它已自动从 MIDL 工具的输出列表中删除。 Target Midl不断报告“所有输出都是最新的”。

MSBuild 确实注意到项目包含一个不存在的文件 ( PIATest.tlb),因此它将项目标记为过期并执行build任务。但由于 MIDL 不会重新创建 TLB 文件,它只会继续TlbImp执行因缺少输入而失败的任务。

问题:如何告诉 MIDL/MSbuild 继续将PIATest.tlb其视为输出?

下面是我导入到项目中以添加Primary Interop Assembly工具链的文件。为了这篇文章的简单起见,这些省略了所有参数tlbimp.exe,只是创建了一个假的互操作 dll。

PrimaryInteropAssembly.xml

<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="http://schemas.microsoft.com/build/2009/properties">
  <ItemType Name="PrimaryInteropAssembly" DisplayName="Primary Interop Assembly"/>
  <ContentType Name="PrimaryInteropAssembly" ItemType="PrimaryInteropAssembly" DisplayName="Primary Interop Assembly"/>
  <FileExtension Name=".tlb" ContentType="PrimaryInteropAssembly"/>
</ProjectSchemaDefinitions>

PrimaryInteropAssembly.targets

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <PropertyPageSchema Include="$(MSBuildThisFileDirectory)PrimaryInteropAssembly.xml" />
    <AvailableItemName Include="PrimaryInteropAssembly">
      <Targets>TlbImp</Targets>
    </AvailableItemName>
  </ItemGroup>

  <Target Name="TlbImp" Condition="'@(PrimaryInteropAssembly)' != ''" BeforeTargets="AfterMidl">
    <ItemGroup>
      <PrimaryInteropAssembly>
        <Command>type %(Identity) > %(Filename).interop.dll</Command>
        <Outputs>%(Filename).interop.dll</Outputs>
      </PrimaryInteropAssembly>
    </ItemGroup>

    <CustomBuild
      Sources="@(PrimaryInteropAssembly)"
      MinimalRebuildFromTracking="true"
      TrackerLogDirectory="$(TLogLocation)"
      ErrorListRegex="(?'FILENAME'.+):(?'LINE'\d+):(?'COLUMN'\d+): (?'CATEGORY'error|warning): (?'TEXT'.*)" />
  </Target>
</Project>

编辑

经过一番挖掘,我得出结论,罪魁祸首在于 Visual Studio 的 UpToDateChecker。它会删除或不再将.tlb文件添加到工具的输出中midl;因此没有调用 midl。所以我提交了一个错误报告

有人知道如何通过修改来解决这个问题PrimaryInteropAssembly.targets吗?

标签: visual-studiomsbuild

解决方案


推荐阅读