mesonbuild / meson

The Meson Build System
http://mesonbuild.com
Apache License 2.0
5.57k stars 1.62k forks source link

Feature Request: better support KMDF/UMDF Windows driver builds #11965

Open dvrogozh opened 1 year ago

dvrogozh commented 1 year ago

Windows KMDF/UMDF driver builds require a) special compiler and linker flags, b) special set of libraries to link against, c) special additional steps to generate certain optional/required files for the driver installation (such as .cat files). As of today it is possible to achieve the goal to build KMDF/UMDF with meson if above steps will be carefully crafted. For example, with msys2 meson 1.1.1 installation on Windows 11 with MSVC2022 and 10.0.22621.0 and latest WDK it's possible to do something like this: https://github.com/dvrogozh/Windows-driver-samples/commit/f74b8dfb69d570753b201f88fd203e3a79b3666c (caveat: that's just example how to build with meson, that's not a runtime example). With provided meson.build steps:

# The following will work if you run once. on a 2nd+ run it might fail
# to generate .cat file due to circular dependency to generate .inf files:
#      echo.inx -> {copy} -> echo.inf -> {stampinf} -> echo.inf
$ meson setup --vsenv _build && meson compile -C _build

# The following will FAIL to build KMDF:
$ meson setup --backend vs _build
$ ...and build with MSVC...
fatal error LNK1295: '/MANIFEST' not compatible with '/DRIVER' specification; link without '/MANIFEST

In above I did reuse shared_library() and executable() targets to build UMDF and KMDF respectfully. They both did not actually fully suite the need to build neither of these targets which is the problem. Probably it should be possible to overcome these issues by using custom_target(), but a) this introduces additional complexity, b) it will entirely miss to generated UMDF/KMDF enabled MSVC solution. For the latter - MSVC does support UMDF/KMDF builds via specialized settings, for example:

    <DriverTargetPlatform>Universal</DriverTargetPlatform>
    <DriverType>KMDF</DriverType>
    <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>

As of today with meson it is entirely not possible to generated UMDF/KMDF aware solution.

Summarizing, there are 2 feature requests

  1. Simplify and provide standardized way to build Windows UMDF/KMDF drivers
  2. Support generating of UMDF/KMDF aware MSVC solutions (within the standardized UMDF/KMDF build procedure requested in 1st item)

Note: the fact that building UMDF/KMDF might require special treatment was actually noted in the work done in https://github.com/mesonbuild/meson/issues/7765, but this was not never investigated as it seems.

Notes

In general, this summarizes some of my experience with UMDF/KMDF, hope this helps:

  1. You need special compile/linker flags to build both. For example, mind '/kernel' compiler flag to build KMDF.
  2. You can't use standard libraries (for dll and exe) to link against - meson implies these for libraries and executables
  3. Instead you must use different set of standard libraries for UMDF and KMDF
  4. KMDF requires special entypoint (/ENTRY:FxDriverEntry) and associated standard library to link against
  5. .inx -> .inf -> .cat generation has circular dependency in .inf (due to stampinf.exe not having output)
dvrogozh commented 1 year ago

There are few paths forward with that I think:

  1. Improve existing library() and executable() to actually support building UMDF/KMDF
  2. Provide new dedicated driver() entrypoint to build drivers. At least for Windows. But maybe there are some extensions possible to cover Linux/OSX - I am really not sure here.
  3. Same as 2nd item, but withing "windows" module to restrict this to Windows.

I am in favor of 2nd item even if driver() entrypoint will be Windows-only thing. Such entrypoint would be better visible for users and will cry out that meson does support UMDF/KMDF driver builds.

eli-schwartz commented 1 year ago

Adding

windows = import('windows')
windows.driver('name', 'src.c')

Seems like it should be straightforward enough.

2. But maybe there are some extensions possible to cover Linux/OSX - I am really not sure here.

For the Linux side of things this sounds more or less like "reimplement Kbuild". There is actually a draft PR that teaches meson to run the Kbuild make as part of the external_project module... I'm not sure it's worth planning in advance to make this proposed feature generic enough to handle that.

dvrogozh commented 1 year ago

Seems like it should be straightforward enough.

No, it's not. https://mesonbuild.com/Windows-module.html - this does not mention windows.driver() driver whatsoever. And I did spend ~1-2 weeks looking around having no clue that windows.driver() actually exists. Basically your reply is the first time I am getting aware of the this :)! I'll get it a try tomorrow, but documentation really needs an update.

If my request will transform to the docs update - that will be really good.

eli-schwartz commented 1 year ago

Adding it to the meson language, not adding it to your build file.

dvrogozh commented 1 year ago

Oh, I misunderstood your initial reply thinking this might be some implemented feature I overlooked. Sorry for that. Looks like that's still to be implemented.

dcbaker commented 1 year ago

I'd also prefer to add it to the windows module first, and make it generic later if necessary. It's relatively easy to make the windows module version just an alias of the other if that happens, but having worked on out-of-tree linux modules, there's a lot going on there, and the external project module probably makes more sense

dvrogozh commented 1 year ago

I'd also prefer to add it to the windows module first, and make it generic later if necessary.

I am fine with that.

X547 commented 1 year ago

2. Provide new dedicated driver() entrypoint to build drivers. At least for Windows. But maybe there are some extensions possible to cover Linux/OSX - I am really not sure here.

This would be also useful for Haiku. Haiku kernel modules are regular ELF shared libraries linked with kernel executable and some arch-dependent compiler flags like -mno-red-zone -mcmodel=kernel. Haiku kernel modules must have no any prefixes or suffixed in file name because modules are searched and loaded by file name (wrong: libbfs.so, right: bfs).

eli-schwartz commented 1 year ago

Haiku kernel modules must have no any prefixes or suffixed in file name because modules are searched and loaded by file name

I wanted to say name_suffix: '' is capable of doing that, but no, we specially emit an error message if you do to tell you that acquiring default per-platform behavior should be specified as an empty array.

X547 commented 1 year ago

Haiku kernel modules must have no any prefixes or suffixed in file name because modules are searched and loaded by file name

I wanted to say name_suffix: '' is capable of doing that, but no, we specially emit an error message if you do to tell you that acquiring default per-platform behavior should be specified as an empty array.

I attemted to make patch, but it is not so trivial as I expected: https://github.com/mesonbuild/meson/pull/11001.