Как заставить MSBuild правильно отслеживать файлы, созданные с помощью внешнего инструмента в проектах, на которые делается ссылка?

У меня есть код MSBuild, который принимает файлы с определенным действием сборки (CompileFoo в этом примере) и генерирует выходные файлы (с другим расширением). Это код, который у меня есть до сих пор:

<Target Name="BuildFoo" BeforeTargets="Compile"
    Inputs="@(CompileFoo)"
    Outputs="@(CompileFoo -> '$(OutputPath)%(RelativeDir)%(Filename).bin' )" >

    <!-- makefoo doesn't know how to create directories: -->
    <MakeDir Directories="$(OutputPath)%(CompileFoo.RelativeDir)"/>
    <Exec Command="makefoo -o &quot;$(OutputPath)%(CompileFoo.RelativeDir)%(CompileFoo.Filename).bin&quot; &quot;%(CompileFoo.Identity)&quot;" />

    <ItemGroup>
        <!-- Required so we can handle Clean: -->
        <FileWrites Include="@(CompileFoo -> '$(OutputPath)%(RelativeDir)%(Filename).bin' )"/>
    </ItemGroup>
</Target>

Это отлично работает, если я включаю его в проект, который генерирует окончательный EXE.

Но теперь я хочу, чтобы он работал в проекте, который генерирует DLL, на которую ссылается EXE (С# с ссылкой на сборку), и мне нужно получить эти сгенерированные элементы (файлы .bin в примере) из выходной каталог DLL, в выходной каталог EXE.

Я пытаюсь получить что-то похожее на эффект этого, когда это происходит в проекте DLL:

<Content Include="Test\Test.txt"><CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory></Content>

В этом случае файл Test\Test.txt попадает в выходную папку EXE. Хотя я не уверен, что это совсем одно и то же. (Он копируется из исходного файла или из папки вывода DLL?)

Я пытаюсь получить что-то довольно совместимое - в частности, это будет работать на VS2010 и VS Mac.

Ответ 1

Трюк здесь заключается в том, чтобы вернуть GetCopyToOutputDirectoryItems дополнительный элемент AllItemsFullPathWithTargetPath:

<Target Name="IncludeFoo" BeforeTargets="GetCopyToOutputDirectoryItems">
  <ItemGroup>
    <CompiledFoos Include="@(CompileFoo -> '$(OutputPath)%(RelativeDir)%(Filename).bin' )">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <TargetPath>%(RelativeDir)%(FileName).bin</TargetPath>
    </CompiledFoos>
    <AllItemsFullPathWithTargetPath Include="@(CompiledFoos->'%(FullPath)')"  />
  </ItemGroup>
</Target>

(testet с использованием текущей версии MSBuild 15) (версия для редактирования с VS2010-AR)