即使输入较新,MSBuild目标文件也不会导致生成输出

时间:2011-12-29 01:11:02

标签: visual-studio-2010 msbuild flex-lexer

我正在尝试为flex创建一个msbuild / VS2010 .targets文件,以便我可以在Visual Studio 2010中使用.l文件。到目前为止,我已经制作了这个:

<?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文件编译正确,并且项目已链接。事情似乎基本上都在发挥作用。

我的期望是,如果.l文件发生更改,Visual Studio将调用flex。目标的Inputs属性包含.l文件,其Outputs属性包含.c文件,Visual Studio可以检查输入是否比输出更新。但事实上,这并没有发生。如果我只是更改.l文件并重建,Visual Studio会告诉我一切都是最新的。

如果删除.c文件并构建项目,则会重新生成.c文件,就像我期望的那样。但是,如果我只是更改.l文件并构建项目,则没有任何反应。事实上,在这种情况下,msbuild似乎甚至没有运行!如果我在构建之前删除构建日志,Visual Studio会告诉我所有内容都是最新的,并且不会生成新的构建日志。这使我很难弄清楚可能发生的事情。

这是我第一次使用msbuild,所以我可能做错了。但是什么?

(N.B。我的目标文件可能会因多个.l文件而崩溃,或者遭受与依赖性检查问题无关的其他一些缺陷 - 在此阶段我并不担心任何此类问题。)

1 个答案:

答案 0 :(得分:1)

为了弄清楚这个问题,我意识到我可以使用.rules文件创建一个Visual Studio 2008项目,将其加载到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更加关注文件。