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

发布于 2024-12-23 12:07:52 字数 1591 浏览 5 评论 0原文

我正在尝试为 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 将此文件添加到我的项目中自定义... 对话框。然后,我添加了 .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 文件而崩溃,或者遭受与依赖性检查问题无关的其他一些缺陷 - 现阶段我并不担心这些问题。)

I am trying to create a msbuild/VS2010 .targets file for flex, so that I can use .l files in Visual Studio 2010. So far, I have produced this:

<?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 "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
  </Target>
</Project>

I added this file to my project, using the Build Customizations... dialog. I then added my .l file, scan.l, and built the project - scan.l was created in the expected place, suggesting that the file name transformations are working. Next, I added scan.c to the project, and built the project again. The generated .c file compiled correctly, and the project linked. So it seems that things are basically working.

My expectation was that Visual Studio would then invoke flex if the .l file changes. The target's Inputs attribute includes the .l file, and its Outputs attribute includes the .c file, and Visual Studio can check whether the input is newer than the output. But in fact, this doesn't happen. If I just change the .l file and rebuild, Visual Studio tells me everything is up to date.

If I delete the .c file and build the project, the .c file is regenerated, just as I'd expect. But if I just change the .l file and build the project, nothing happens. In fact, in this case, msbuild doesn't even seem to run! If I delete the build log before building, Visual Studio tells me that everything is up to date, and no new build log is produced. This makes it rather hard for me to work out what might be going on.

This is my first go with msbuild, so I am probably doing something wrong. But what?

(N.B. my targets file might fall over with multiple .l files, or suffer from some other flaw(s) unrelated to the dependency checking issue - I am not bothered about any of this at this stage.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月染过的梦 2024-12-30 12:07:52

为了解决这个问题,我意识到我可以使用 .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 "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
  </Target>
</Project>

现在重新加载项目,并访问 .l 文件的属性。从Item Type 下拉列表中选择新的Flex 选项。这似乎促使 Visual Studio 对文件更加小心。

To figure out the fix, I realised I could create a Visual Studio 2008 project with a .rules file, load it into Visual Studio 2010, let Visual Studio 2010 convert it automatically, and examine the result. So I did that.

To fix the problem, add an XML file with the same base name as the targets file. This one will do for this example:

<?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>

Next, refer to this file in the ItemGroup section. The .targets file is pretty small so here's the new version in its entirety:

<?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 "-o%(LFiles.RootDir)%(LFiles.Directory)%(LFiles.Filename).c" "%(LFiles.FullPath)" 2>&1 | sed -e "s/. line \([0-9]\+\)/(\1)/" | sed -e s/\"//g"/>
  </Target>
</Project>

Now reload the project, and visit the properties for the .l file. Select the new Flex option from the Item Type dropdown. This seems to prod Visual Studio into taking a little more care over the file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文