How to use midlrt.exe to compile .idl to .winmd?

爷,独闯天下 提交于 2020-01-14 04:12:26

问题


Background: I need to build a Windows Runtime Component as part of a system that's set up to use CMake to generate its build system. As a preparatory step I'm trying to build it on the command line.


Starting with a bare-bones .idl file (MyType.idl)

namespace NS
{
    [default_interface]
    runtimeclass MyType
    {
    }
}

I'm trying to generate a matching .winmd file using the midlrt.exe tool. The following command line (split across several lines for readability)

midlrt
    /metadata_dir "%WindowsSdkDir%References\%WindowsSDKVersion%Windows.Foundation.FoundationContract\3.0.0.0"
    /reference "%WindowsSdkDir%References\%WindowsSDKVersion%Windows.Foundation.FoundationContract\3.0.0.0\Windows.Foundation.FoundationContract.winmd"
    /winmd MyType.winmd
    /notlb
    /winrt
    /nomidl
    /nologo
    /enum_class
    /ns_prefix
    /client none
    /server none
    MyType.idl

generates the MyType.winmd file just fine, but I don't know why. I'm particularly confused about the /metadata_dir and /reference options. Running midlrt /help offers the following:

/metadata_dir      Specify one or more directories containing platform metadata files
/reference         Specify one or more WinMD files to import

The official documentation on /metadata_dir doesn't add much to that (other than a confusing remark: "Use this switch to specify the location of the main metadata file for Windows, which is named windows.winmd."). There is no documentation for /reference.

Here's what I need help with:

  • What do I really need to pass for the /metadata_dir option? As used in the command line above it looks like a redundant replication of part of the /reference option. Leaving it out produces compiler errors, though.
  • How do I determine the list of required /references including their particular version(s)?

回答1:


/metadata_dir is required to tell MIDLRT where it can find the definitions of foundational types that MIDLRT requires for historical reasons. Practically, this must point to the directory containing the winmd that defines the types from the Windows.Foundation namespace in the Windows SDK, but you can use C:\Windows\System32\WinMetadata if you are in a pinch (as the former is hard to track down). Obviously, you'll only want to do this for testing/experimentation since you'll be at the whim of whatever build of the OS you happen to be running on. The correct form looks something like this:

midlrt sample.idl /metadata_dir "C:\Program Files (x86)\Windows Kits\10\References\10.0.18362.0\Windows.Foundation.FoundationContract\3.0.0.0"

Finding this path is tricky. Start by finding the SDK install path in the registry. Then pick the SDK version you wish to target. Then find the latest version of the foundation contract. You can look at how C++/WinRT does this here:

https://github.com/microsoft/xlang/blob/master/src/library/impl/cmd_reader_windows.h

/reference is a newer feature where you can use it to import the definitions from a winmd rather than having to import/include the definitions using IDL. This is mainly an optimization as this tends to be much faster than including the corresponding IDL definitions.

You still need to use /metadata_dir regardless of whether you use /reference as they are used for different things. This is different to cppwinrt.exe where it only has a single harmonized -reference flag.



来源:https://stackoverflow.com/questions/56823779/how-to-use-midlrt-exe-to-compile-idl-to-winmd

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!