【问题标题】:How can I get MIDL to search additional include directories for qualified paths如何让 MIDL 在其他包含目录中搜索合格路径
【发布时间】:2010-11-18 02:21:55
【问题描述】:

更新:在向 Microsoft 发起支持电话后仅六个月,它就被拒绝了,他们声称这不是错误(因为文档没有明确说明所看到的行为不是) t 正确的)。他们拒绝了DCR,说因为他们在过去 10 年没有听到任何投诉,这显然不是一个常见的用例。

这是号召性用语,如果您遇到同样的问题,请向 Microsoft 发起支持电话,以便他们了解应该修复它。我知道至少有人遇到了同样的问题,因为我在Chrome's source code找到了这条评论:

# 构建 .idl 文件。
# 这真是一团糟。 MIDL 需要从 $OPEN_DIR 运行,因为它太
# 愚蠢地将其包含路径应​​用于“ui/ie/bla.idl”之类的相对路径
#(它只在当前目录)。因此,我们必须越过障碍来修复
# 我们的相对包含路径和输出文件。


原问题:

我的文件结构如下:

  • C:\first\Foo.idl
  • C:\second\Bar.idl

其中Bar.idl 包含以下行:

import "first/Foo.idl";

C:\second 编译时,如何让midl 编译Bar.idl

如果我直接导​​入了Foo.idl(不指定first/),那么将first 指定为附加的包含目录就足够了(midl /I c:\first Bar.idl),它会找到Foo.idl

或者,如果我从C:\ (midl second\Bar.idl) 编译也可以。

问题是当使用命令行midl /I C:\ Bar.idlC:\second 内编译时,出现以下编译错误:

c1 : 致命错误 C1083: 无法打开源文件: 'first\Foo.idl': 没有这样的文件或目录

看起来 midl 只愿意搜索相对路径,前提是它们相对于当前目录而不是指定的附加包含目录之一,并且仅将附加包含目录用于不合格的文件名,此行为特定于 import 关键字,当使用 include 时,结果符合预期。

我希望能够添加两个不同的附加包含目录,这样如果我的本地计算机上有文件 midl 将采用该版本,否则它将从服务器获取文件(所以chdiring 到根文件夹不是一个选项)。

有没有办法解决这个问题?

【问题讨论】:

  • 自上次更新后,您找到解决此问题的方法了吗?
  • @HenryMerriam 不,我联系了 Microsoft 支持,他们说他们认为这不是错误,因为它没有明确违反文档。因为他们在觉得改变当前行为不够重要之前没有听到这个请求:(

标签: relative-path include-path midl


【解决方案1】:

正如您所注意到的,虽然这很愚蠢,但 Microsoft 支持人员已确认这不是错误。以下是可能的解决方法。

1。使用 /I 开关。很多。

使用/I 开关同时指定c:\firstc:\second,并指定import "Foo.idl" 而不是相对路径。

如果命令行变得太长,请指定一个响应文件。

2。使用符号链接

使用包含目录的符号链接或连接将它们全部引用到已知目录下的单个层次结构中。然后您可以使用相对于该目录的路径。

可以使用预构建步骤来维护符号链接。

MKLINK.exe 可以创建联结或符号链接。

3。使用额外的构建步骤

创建一个额外的构建步骤,将所需文件复制到已知位置,然后从那里导入它们。

【讨论】:

  • 现实生活中的情况比firstsecond要多一点,其实我相信如果我把所有可能的目录都加起来会超过最大命令行长度。
  • @Motti,这就是响应文件的用途。
  • 这可能有效,但对于大型项目而言,它远非可维护。如果 Microsoft 支持 /I 的健全语义,那就更好了。
【解决方案2】:

2020 年底,MIDL 3.0 已经发布。但是,OP描述的问题仍然存在。但是,如果您使用的是 Visual Studio,则有一种直接的方法可以解决该问题。

如果您将 .idl 文件添加到项目中,则会在添加 .idl 文件的项目文件中生成以下 MSBuild 代码:

<ItemGroup>
  <Midl Include="Folder1\YourCustomFile.idl" />
</ItemGroup>

如果您在另一个文件夹中添加第二个文件并引用第一个文件,则会生成另一个条目:

<ItemGroup>
  <Midl Include="Folder1\YourCustomFile.idl" />
  <Midl Include="Folder2\YourSecondCustomFile.idl" />
</ItemGroup>

问题在于,如果您编译该代码,MIDL 编译器将不知道任何额外的包含目录。因此,如果你添加

#include "YourCustomFile.idl"

YourSecondCustomFile.idl 的开头,MIDL 编译器不会在Folder1 中搜索要包含的任何 .idl 文件,编译将失败。

但是,通过添加 AdditionalIncludeDirectories MSBuild 项元数据,您可以影响将哪些文件夹作为附加包含目录传递给 MIDL 编译器。

因此,为了指示 MIDL 编译器在编译 YourSecondCustomFile.idl 时搜索 Folder1 以查找包含文件,请修改 MSBuild 代码,如下所示:

<ItemGroup>
  <Midl Include="Folder1\YourCustomFile.idl" />
  <Midl Include="Folder2\YourSecondCustomFile.idl">
    <AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)Folder1</AdditionalIncludeDirectories>
  </Midl>
</ItemGroup>

ProjectDir 是一个 MSBuild 属性,它指向包含当前项目的目录(至少在 C++ 项目中是这样)。 ; 用于分隔不同的目录。这些目录中的每一个都将作为单独的目录传递给 MIDL 编译器以搜索包含文件。

这应该可以解决编译问题。我不认为 AdditionalIncludeDirectories 项目元数据可以使用 Visual Studio 的用户界面添加,因此您应该直接在文本编辑器中编辑 Visual Studio 项目。

请注意,项目元数据每个项目都是有效的,即对于每个单独的 MIDL 文件。因此,您必须将AdditionalIncludeDirectories 添加到每个引用其他 MIDL 文件的 MIDL 文件中。

如果您需要多个 AdditionalIncludeDirectories 中的相同内容,您可以在项目文件的其他位置定义一个属性,如下所示:

<PropertyGroup>
  <AdditionalMidlIncludeDirectories>$(ProjectDir);$(ProjectDir)Folder1;$(ProjectDir)Folder2</AdditionalMidlIncludeDirectories>
</PropertyGroup>

然后你在任何地方都使用该属性。您可以将相同的 AdditionalIncludeDirectories 语句添加到每个 MIDL,这将确保每个 MIDL 编译器调用都使用相同的包含目录:

<ItemGroup>
  <Midl Include="Folder1\YourCustomFile.idl">
    <AdditionalIncludeDirectories>$(AdditionalMidlIncludeDirectories)</AdditionalIncludeDirectories>
  </Midl>
  <Midl Include="Folder2\YourSecondCustomFile.idl">
    <AdditionalIncludeDirectories>$(AdditionalMidlIncludeDirectories)</AdditionalIncludeDirectories>
  </Midl>
</ItemGroup>

编辑:

正如下面评论中提到的,可以通过应用 MSBuild 的ItemDefinitionGroup 进一步简化代码。 ItemDefinitionGroup 用于将元数据添加到 MSBuild 项,这意味着 AdditionalIncludeDirectories 元数据可以自动添加到每个 Midl 元素。 ItemDefinitionGroup 定义如下:

<ItemDefinitionGroup>
  <Midl>
    <AdditionalIncludeDirectories>
      $(ProjectDir);
      $(ProjectDir)Folder1;
      $(ProjectDir)Folder2
    </AdditionalIncludeDirectories>
  </Midl>
</ItemDefinitionGroup>

这将Midl ItemGroup 简化如下:

<ItemGroup>
  <Midl Include="Folder1\YourCustomFile.idl" />
  <Midl Include="Folder2\YourSecondCustomFile.idl" />
</ItemGroup>

【讨论】:

  • 您可以使用&lt;ItemDefinitionGroup&gt; 为项目中的所有Midl 项目设置默认的AdditionalIncludeDirectories 值,这样您就不需要为每个项目单独指定它。跨度>
  • 感谢您的意见。我不知道 MSBuild 的 ItemDefinitionGroup 元素。你的提议确实有效,我已经相应地更新了我的答案。
猜你喜欢
  • 2019-02-22
  • 2010-09-22
  • 1970-01-01
  • 2015-03-31
  • 2012-09-03
  • 2018-06-06
  • 1970-01-01
  • 2021-01-16
相关资源
最近更新 更多