Файл целей MSBuild не приводит к созданию выходных данных, даже если входные данные являются более новыми - PullRequest
1 голос
/ 29 декабря 2011

Я пытаюсь создать файл msbuild / VS2010 .targets для flex, чтобы я мог использовать .l файлы в Visual Studio 2010. До сих пор я создал следующее:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <LFiles Include="$(MSBuildProjectDirectory)\**\*.l"/>
  </ItemGroup>

  <Target Name="Flex"
          BeforeTargets="ClCompile"
          Inputs="@(LFiles)"
          Outputs="@(LFiles->'%(RootDir)%(Directory)%(Filename).c')"
          Returns="@(LFiles->'%(RootDir)%(Directory)%(Filename).c')">
    <Exec Command="flex.exe &quot;-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c&quot; &quot;%(LFiles.FullPath)&quot; 2>&amp;1 | sed -e &quot;s/. line \([0-9]\+\)/(\1)/&quot; | sed -e s/\&quot;//g"/>
  </Target>
</Project>

Я добавилэтот файл в мой проект, используя диалог Build Customizations....Затем я добавил свой .l файл scan.l и собрал проект - scan.l был создан в ожидаемом месте, предполагая, что преобразования имени файла работают.Затем я добавил scan.c в проект и собрал его заново.Сгенерированный файл .c скомпилирован правильно, а проект связан.Таким образом, кажется, что все в основном работает.

Я ожидал, что Visual Studio затем вызовет flex, если файл .l изменится.Атрибут Inputs цели включает в себя файл .l, а его атрибут Outputs включает файл .c, и Visual Studio может проверить, является ли ввод более новым, чем вывод.Но на самом деле этого не происходит.Если я просто изменяю файл .l и перестраиваюсь, Visual Studio сообщает, что все обновлено.

Если я удаляю файл .c и собираю проект, файл .c воссоздается, как ябуду ожидать.Но если я просто изменю файл .l и соберу проект, ничего не произойдет.На самом деле, в этом случае msbuild даже не запускается!Если я удаляю журнал сборки перед сборкой, Visual Studio сообщает, что все обновлено, и новый журнал сборки не создается.Это затрудняет мне понимание того, что может происходить.

Это мой первый опыт использования msbuild, поэтому я, вероятно, что-то делаю не так.Но что?

(Обратите внимание, что мой целевой файл может упасть с несколькими .l файлами или иметь некоторые другие недостатки, не связанные с проблемой проверки зависимостей - меня это не беспокоит на данном этапе.)

1 Ответ

1 голос
/ 29 декабря 2011

Чтобы выяснить это исправление, я понял, что могу создать проект Visual Studio 2008 с файлом .rules, загрузить его в Visual Studio 2010, позволить Visual Studio 2010 автоматически преобразовать его и проверить результат. Так я и сделал.

Чтобы устранить проблему, добавьте файл XML с тем же базовым именем, что и у файла назначения. Это будет делать для этого примера:

<?xml version="1.0" encoding="utf-8"?>
<ProjectSchemaDefinitions xmlns="clr-namespace:Microsoft.Build.Framework.XamlTypes;assembly=Microsoft.Build.Framework" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:transformCallback="Microsoft.Cpp.Dev10.ConvertPropertyCallback">
  <ItemType
      Name="Flex"
      DisplayName="Flex" />
  <FileExtension
    Name="*.l"
    ContentType="Flex" />
  <ContentType
    Name="Flex"
    DisplayName="Flex"
    ItemType="Flex" />
</ProjectSchemaDefinitions>

Далее, обратитесь к этому файлу в разделе ItemGroup. Файл .targets довольно маленький, поэтому вот новая версия в полном объеме:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <PropertyPageSchema Include="$(MSBuildThisFileDirectory)$(MSBuildThisFileName).xml"></PropertyPageSchema>
    <LFiles Include="$(MSBuildProjectDirectory)\**\*.l"/>
  </ItemGroup>

  <Target Name="Flex"
          BeforeTargets="ClCompile"
          Inputs="@(LFiles)"
          Outputs="@(LFiles->'%(RootDir)%(Directory)%(Filename).c')"
          Returns="@(LFiles->'%(RootDir)%(Directory)%(Filename).c')">
    <Exec Command="flex.exe &quot;-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c&quot; &quot;%(LFiles.FullPath)&quot; 2>&amp;1 | sed -e &quot;s/. line \([0-9]\+\)/(\1)/&quot; | sed -e s/\&quot;//g"/>
  </Target>
</Project>

Теперь перезагрузите проект и откройте свойства файла .l. Выберите новый параметр Flex из раскрывающегося списка Item Type. Похоже, это побуждает Visual Studio немного больше заботиться о файле.

...