Skip to content
This repository has been archived by the owner on Jun 23, 2023. It is now read-only.

Commit

Permalink
feat(allow-symbols): Better symbol selection
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `allow` flag moved to `allow-file`
  • Loading branch information
bengreenier committed Jan 5, 2022
1 parent cc2d35b commit 2365a5c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 16 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "lerna workspace for clangffi, libclang-bindings tools",
"scripts": {
"clangffi": "node packages/clangffi/dist/bin/clangffi.js",
"generate-dogfood": "npm run clangffi -- -i vendor/llvm-project/clang/include/clang-c/Index.h -I vendor/llvm-project/clang/include/ -o packages/libclang-bindings/src/libclang.ts",
"generate-dogfood": "npm run clangffi -- -i vendor/llvm-project/clang/include/clang-c/Index.h -I vendor/llvm-project/clang/include/ -o packages/libclang-bindings/src/libclang.ts --allow-symbol time_t --allow-symbol __time32_t --allow-symbol __time64_t",
"bootstrap": "lerna bootstrap",
"build": "lerna run build --stream",
"test": "lerna run test --stream -- -- --passWithNoTests"
Expand Down
12 changes: 10 additions & 2 deletions packages/clangffi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ Options:
-I, --include-directory Additional include directories to use during parsing
[array] [default: []]
--lib-path The path to the libclang binary to load. [string]
--allow Additional file paths to allow symbols from
--allow-file Additional file paths to allow symbols from
[array] [default: []]
--allow-symbol Additional symbol name to allow regardless of it's
location [array] [default: []]
--crlf Use crlf endings instead of lf
[boolean] [default: false]
--no-sibling Does not include sibling file symbols in the
Expand All @@ -49,7 +51,13 @@ Options:
Generate typescript ffi-napi bindings for any c/c++ library using libclang.
```

Note that by default, only symbols that are directly sourced from the `input` header or included files that are next to the input header on disk (e.g. "sibling" files) will be included in the bindings. To include other symbols, specify the `--allow` flag, passing other source files. E.g. `--input path/to/initial/header.h --allow path/to/included/header.h`.
## Selecting symbols

By default, only symbols that are directly sourced from the `input` header or included files that are next to the input header on disk (e.g. "sibling" files) will be included in the bindings.

To include other symbols, specify the `--allow-file` flag, passing other source files. E.g. `--input path/to/initial/header.h --allow-file path/to/included/header.h`. It is also possible to allow specific symbols with the `--allow-symbol` flag, which includes symbols with a particular name regardless of their source location. E.g. `--input path/to/initial/header.h --allow-symbol YourSymbolName`.

When both `--allow-file` and `--allow-symbol` are used, all symbols from the `--allow-file` files are included, as well as any symbols that are specified from `--allow-symbol`. Further - Just to clarify - if a symbol matches both `--allow-file` and `--allow-symbol` it's included (hopefully that's what you'd expect).

## Logging

Expand Down
19 changes: 14 additions & 5 deletions packages/clangffi/src/bin/clangffi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,18 @@ const args = yargs(hideBin(process.argv))
.string("I")
.array("I")
.alias("I", "include-directory")
.string("allow")
.array("allow")
.string("allow-file")
.array("allow-file")
.string("allow-symbol")
.array("allow-symbol")
.default({
crlf: false,
"no-prettier": false,
"no-sibling": false,
L: "c",
I: [],
allow: [],
"allow-file": [],
"allow-symbol": [],
})
.demandOption("input")
.demandOption("output")
Expand All @@ -51,7 +54,9 @@ const args = yargs(hideBin(process.argv))
L: "Language to parse input as",
I: "Additional include directories to use during parsing",
"lib-path": "The path to the libclang binary to load.",
allow: "Additional file paths to allow symbols from",
"allow-file": "Additional file paths to allow symbols from",
"allow-symbol":
"Additional symbol name to allow regardless of it's location",
crlf: "Use crlf endings instead of lf",
"no-sibling":
"Does not include sibling file symbols in the generated bindings",
Expand All @@ -66,6 +71,7 @@ if (!(args instanceof Promise)) {
const fileDir = path.dirname(args.input);
const lang: Language = args.language == "c" ? Language.C : Language.Cpp;
const includeDirectories: string[] = args.includeDirectory ?? [];
const additionalSymbols: string[] = args.allowSymbol ?? [];

const includeFiles = includeDirectories.flatMap((includeDir) =>
fs
Expand All @@ -81,7 +87,9 @@ if (!(args instanceof Promise)) {
.map((f) => path.join(fileDir, f))
.filter((f) => path.extname(f) == ".h");

const additionalFiles = siblingFiles.concat(includeFiles);
const additionalFiles = siblingFiles
.concat(includeFiles)
.concat(args.allowFile ?? []);

const defaultLibPath =
process.platform == "win32" ? "libclang.dll" : "libclang";
Expand All @@ -96,6 +104,7 @@ if (!(args instanceof Promise)) {
language: lang,
additionalFiles,
includeDirectories,
additionalSymbols,
generator: new TsGen({
lineEndings: args.crlf ? LineEndings.CRLF : LineEndings.LF,
usePrettier: args["no-prettier"] ? false : true,
Expand Down
22 changes: 14 additions & 8 deletions packages/clangffi/src/lib/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ export interface ParserOptions extends Omit<ParseOptions, "index"> {
*/
additionalFiles: string[];

/**
* Additional symbols to include (by name)
*/
additionalSymbols: string[];

/**
* The source generator to use
*/
Expand Down Expand Up @@ -97,18 +102,19 @@ export class Parser {
}

const sp = formatPath(decl.sourcePath);
const logSymbolName = resolveName(decl);
const symbolName = resolveName(decl);

const isAllowedSymbol =
this.opts.additionalFiles.some((f) => formatPath(f) == sp) ||
this.opts.additionalSymbols.some((s) => s == symbolName);

// skip symbols that aren't in our purview
if (
sp != this.opts.path &&
!this.opts.additionalFiles.some((f) => formatPath(f) == sp)
) {
log(`skip '${logSymbolName}' from '${sp}'.`);
if (sp != this.opts.path && !isAllowedSymbol) {
log(`skip '${symbolName}' from '${sp}'.`);
return CXChildVisitResult.CXChildVisit_Continue;
}

log(`processing '${logSymbolName}'`);
log(`processing '${symbolName}'`);

// openers
if (decl instanceof EnumDecl) {
Expand Down Expand Up @@ -164,7 +170,7 @@ export class Parser {
this.opts.generator.closeFunctionParam(decl as ParamDecl);
}

log(`finished '${logSymbolName}'`);
log(`finished '${symbolName}'`);
} catch (e) {
log(e);

Expand Down

0 comments on commit 2365a5c

Please sign in to comment.