13

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

这是号召性用语,如果您遇到同样的问题,请与 Microsoft 联系支持电话,以便他们了解应该修复它。我知道至少有人遇到了同样的问题,因为我在Chrome 的源代码中找到了这条评论:

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


原始问题:

我有以下文件结构:

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

其中Bar.idl包含以下行:

import "first/Foo.idl";

编译时如何让midl编译?Bar.idlC:\second

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

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

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

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

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

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

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

4

3 回答 3

4

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"

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

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

因此,要指示 MIDL 编译器在编译时搜索Folder1包含文件, YourSecondCustomFile.idl请修改 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进一步简化代码。AnItemDefinitionGroup用于将元数据添加到 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>
于 2020-12-04T09:32:59.187 回答
2

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

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

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

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

2.使用符号链接

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

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

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

3. 使用额外的构建步骤

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

于 2012-06-16T10:17:28.560 回答
1

这是武装的召唤……

12 年零 6 个月后,我带着干草叉来到这里,准备出发。

同时,为了更容易修复,您可以转到项目属性 -> MIDL -> 常规 -> 附加包含目录。将其设置为“$(MSBuildProjectDirectory)\YourSubFolder”就可以了。

于 2022-02-12T16:54:14.350 回答