Skip to content

Support mutually exclusive header groupings in wdk-build (reusable and version-aware) #514

@wmmc88

Description

@wmmc88

Background

Including all headers in a single pass for bindgen in WDK projects is known to cause redefinition and conflicting definition errors, as not all headers are designed to be included together. Common scenarios include GUID redefinitions (e.g., initguid.h), type aliasing based on inclusion order (e.g., ntifs.h vs ntddk.h), and overlapping driver header sets (storport.h, scsi.h, srb.h). These issues are well-documented online and in developer discussions, highlighting the need for a more robust approach to handling mutually exclusive headers.

Proposed Solution

  1. Mutually Exclusive Grouping Mechanism:

    • Define groupings of mutually exclusive headers in a single place (e.g., a config or data structure) to facilitate reuse and easy maintenance.
    • These groupings should be adjustable based on the WDK version, as header compatibility and contents may change.
  2. Bindgen Invocation Strategy:

    • Rather than including all headers at once, run bindgen first on a set of base types (e.g., A.h in the example) to establish foundational types.
    • For each mutually exclusive header (e.g., B.h, C.h), run bindgen separately, including the base types but only one mutually exclusive header per run.
    • Use bindgen's allowlist_file and set allowlist_recursively to false for subsequent runs, ensuring only new definitions from the exclusive header are considered, and avoiding duplicate definitions.
    • This also applies to constants, types, and API-subset-specific modules.
  3. Generalization & Reusability:

    • The mechanism for facilitating mutually exclusive header groups should be reusable across different entry points in the codebase (not just bindgen invocations), minimizing duplication and centralizing maintenance.

Example

// A.h
typedef struct {
    int x;
} Common;

// B.h
#include "A.h"
typedef enum {
    A,
} EnumA;

// C.h
#include "A.h"
typedef enum {
    A,
} EnumB;
  • B.h and C.h cannot be included together due to global enum name collisions.
  • Solution: Run bindgen on A.h, then separately on each of B.h and C.h (each with allowlisting and correct base includes).

References

  • Internet discussions about WDK header incompatibilities and required subset inclusion
  • Examples of GUID redefinition errors and type aliasing issues

Sub-issues

  1. Support for mutually exclusive header groupings in start_wdf_symbol_export_tasks (for generating __declspec(selectany) symbols)
  2. Support for mutually exclusive header groupings in bindgen invocations (constants, types, api-subsets)

This issue tracks the overall design, implementation, and generalization of mutually exclusive header handling in wdk-build. Please see sub-issues for implementation details.

Sub-issues

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions