【问题标题】:MSBuild targets file doesn't cause outputs to be built, even though inputs are newerMSBuild 目标文件不会导致生成输出,即使输入较新
【发布时间】:2011-12-29 01:11:02
【问题描述】:

我正在尝试为 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,所以我可能做错了什么。但是什么?

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

【问题讨论】:

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


    【解决方案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 文件的属性。从Item Type 下拉列表中选择新的Flex 选项。这似乎促使 Visual Studio 更加注意文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-26
      • 2014-03-04
      相关资源
      最近更新 更多