bottlenoselabs / c2cs

Generate C# bindings from a C header.
MIT License
245 stars 18 forks source link

Header files are not excluded when they do not declare any types #71

Closed waldnercharles closed 2 years ago

waldnercharles commented 2 years ago

If a file is included in excludedHeaderFiles but doesn't declare any types or functions, it will not be excluded. This is a problem when the header file is including other header files that do declare types.

A good example of this is windows.h. It doesn't declare any types itself, but includes quite a few headers that will be visited during ExploreTranslationUnit.

An easy way to replicate the issue is to do the following:

// Library.h
#include "ParentHeader.h"

// ParentHeader.h
#include "ChildHeader.h"

// ChildHeader.h
struct MyStruct
{
    int x;
    int y;
}

// config.json
{
  "inputFilePath": "Library.h",
  "outputFilePath": "Library.cs",
  "excludedHeaderFiles": ["ParentHeader.h"]
}

In the example above, MyStruct will be generated in Library.cs.

Alternatively on windows, just try to #include <windows.h> and "excludeHeaderFiles": ["windows.h"]

lithiumtoast commented 2 years ago

I'll add the test case to the integration test when the multi-pass branch is merged.

lithiumtoast commented 2 years ago

Merged the branch in. I'll take a look at this tomorrow.

lithiumtoast commented 2 years ago

This requires a re-design for knowing which "nodes" (function, type, etc) are dependent on other nodes. Trimming one node (trimming all nodes of a specific file) should cascade and remove any other nodes in other files which have no "parent" (leaf nodes). In other words, a node should always have a parent node unless it is an entry point for P/Invoke such as a function or variable.

lithiumtoast commented 2 years ago

I think I came up with a possible idea for a simpler solution. It sounds janky but...

"Pre-pass":

"Normal-pass":

lithiumtoast commented 2 years ago

@waldnercharles I fixed this and added a test for it for regression. See pull request #94.