Add ability to exclude files or directories from wrapped output
This commit is contained in:
parent
fb2acc752a
commit
a9887cc6b2
6 changed files with 70 additions and 15 deletions
|
|
@ -41,12 +41,16 @@ https://github.com/nimterop/nimterop/compare/v0.5.9...v0.6.3
|
|||
|
||||
- `xxxJBB` now allows for customizing the base location to search packages with the `jbbFlags` param to `getHeader()`. Specifying `giturl=xxx` where `xxx` could be a full Git URL or just the username for Github.com allows changing the default Git repo. In addition, `url=xxx` is also supported to download project info and binaries compiled with BinaryBuilder.org but hosted at another non-Git location. (since v0.6.3)
|
||||
|
||||
- It is now possible to exclude the contents of specific files or entire directories from the wrapped output using `--exclude | -X` with `toast` or `cExclude()` from a wrapper. This might be required when a header uses `#include` to pull in external dependencies. E.g. `sciter` has a `#include <gtk/gtk.h>` which pulls in the entire GTK ecosystem which is needed for successful preprocessing but we do not want to include those headers in the wrapped output when using `--recurse | -r`.
|
||||
|
||||
### Other improvements
|
||||
|
||||
- Generated wrappers no longer depend on nimterop being present - no more `import nimterop/types`. Supporting code is directly included in the wrapper output and only when required. E.g. enum macro is only included if wrapper contains enums. [#125][i125] (since v0.6.1)
|
||||
|
||||
- `cImport()` now includes wrapper output from a file rather than inline. Errors in generated wrappers will no longer point to a line in `macros.nim` making debugging easier. (since v0.6.1)
|
||||
|
||||
- `cIncludeDir()` can now accept a `seq[string]` of directories and an optional `exclude` param which sets those include directories to not be included in the wrapped output.
|
||||
|
||||
|
||||
## Version 0.5.0
|
||||
|
||||
|
|
|
|||
|
|
@ -132,6 +132,7 @@ cDefine("HAS_ABC") # Set #defines for preprocessor and compiler
|
|||
cDefine("HAS_ABC", "DEF")
|
||||
|
||||
cIncludeDir("clib/include") # Setup any include directories
|
||||
cExclude("clib/file.h") # Exclude file from wrapped output
|
||||
|
||||
cImport("clib.h") # Generate wrappers for header specified
|
||||
|
||||
|
|
@ -219,6 +220,7 @@ Options:
|
|||
-d, --debug bool false enable debug output
|
||||
-D=, --defines= strings {} definitions to pass to preprocessor
|
||||
-l=, --dynlib= string "" {.dynlib.} pragma to import symbols - Nim const string or file path
|
||||
-X=, --exclude= strings {} files or directories to exclude from the wrapped output
|
||||
-f=, --feature= Features {} flags to enable experimental features
|
||||
-I=, --includeDirs= strings {} include directory to pass to preprocessor
|
||||
-m=, --mode= string "" language parser: c or cpp
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ proc getToast(fullpaths: seq[string], recurse: bool = false, dynlib: string = ""
|
|||
for i in gStateCT.includeDirs:
|
||||
cmd.add &" --includeDirs+={i.sanitizePath}"
|
||||
|
||||
for i in gStateCT.exclude:
|
||||
cmd.add &" --exclude+={i.sanitizePath}"
|
||||
|
||||
if not noNimout:
|
||||
cmd.add &" --pnim"
|
||||
|
||||
|
|
@ -415,21 +418,52 @@ proc cAddSearchDir*(dir: string) {.compileTime.} =
|
|||
if dir notin gStateCT.searchDirs:
|
||||
gStateCT.searchDirs.add(dir)
|
||||
|
||||
macro cIncludeDir*(dir: static string): untyped =
|
||||
macro cIncludeDir*(dirs: static seq[string], exclude: static[bool] = false): untyped =
|
||||
## Add include directories that are forwarded to the C/C++ preprocessor if
|
||||
## called within `cImport()` or `c2nImport()` as well as to the C/C++
|
||||
## compiler during Nim compilation using `{.passC: "-IXXX".}`.
|
||||
##
|
||||
## Set `exclude = true` if the contents of these include directories should
|
||||
## not be included in the wrapped output.
|
||||
for dir in dirs:
|
||||
var dir = interpPath(dir)
|
||||
result = newNimNode(nnkStmtList)
|
||||
|
||||
let fullpath = findPath(dir)
|
||||
if fullpath notin gStateCT.includeDirs:
|
||||
gStateCT.includeDirs.add(fullpath)
|
||||
if exclude:
|
||||
gStateCT.exclude.add(fullpath)
|
||||
let str = &"-I{fullpath.quoteShell}"
|
||||
result.add quote do:
|
||||
{.passC: `str`.}
|
||||
if gStateCT.debug:
|
||||
gecho result.repr
|
||||
|
||||
macro cIncludeDir*(dir: static[string], exclude: static[bool] = false): untyped =
|
||||
## Add an include directory that is forwarded to the C/C++ preprocessor if
|
||||
## called within `cImport()` or `c2nImport()` as well as to the C/C++
|
||||
## compiler during Nim compilation using `{.passC: "-IXXX".}`.
|
||||
var dir = interpPath(dir)
|
||||
result = newNimNode(nnkStmtList)
|
||||
##
|
||||
## Set `exclude = true` if the contents of this include directory should
|
||||
## not be included in the wrapped output.
|
||||
return quote do:
|
||||
cIncludeDir(@[`dir`], `exclude` == 1)
|
||||
|
||||
let fullpath = findPath(dir)
|
||||
if fullpath notin gStateCT.includeDirs:
|
||||
gStateCT.includeDirs.add(fullpath)
|
||||
let str = &"-I{fullpath.quoteShell}"
|
||||
result.add quote do:
|
||||
{.passC: `str`.}
|
||||
if gStateCT.debug:
|
||||
gecho result.repr
|
||||
macro cExclude*(paths: static seq[string]): untyped =
|
||||
## Exclude specified paths - files or directories from the wrapped output
|
||||
##
|
||||
## Full path to file or directory is required.
|
||||
result = newNimNode(nnkStmtList)
|
||||
for path in paths:
|
||||
gStateCT.exclude.add path
|
||||
|
||||
macro cExclude*(path: static string): untyped =
|
||||
## Exclude specified path - file or directory from the wrapped output.
|
||||
##
|
||||
## Full path to file or directory is required.
|
||||
return quote do:
|
||||
cExclude(@[`path`])
|
||||
|
||||
proc cAddStdDir*(mode = "c") {.compileTime.} =
|
||||
## Add the standard `c` [default] or `cpp` include paths to search
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ type
|
|||
debug*: bool # `cDebug()` or `--debug | -d` to enable debug mode
|
||||
defines*: seq[string] # Symbols added by `cDefine()` and `--define | -D` for C/C++ preprocessor/compiler
|
||||
dynlib*: string # `cImport(dynlib)` or `--dynlib | -l` to specify variable containing library name
|
||||
exclude*: seq[string] # files or directories to exclude from the wrapped output
|
||||
feature*: seq[Feature] # `--feature | -f` feature flags enabled
|
||||
includeDirs*: seq[string] # Paths added by `cIncludeDir()` and `--includeDirs | -I` for C/C++ preprocessor/compiler
|
||||
mode*: string # `cImport(mode)` or `--mode | -m` to override detected compiler mode - c or cpp
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ var
|
|||
preMainOut = ""
|
||||
|
||||
proc process(gState: State, path: string) =
|
||||
doAssert existsFile(path), &"Invalid path {path}"
|
||||
doAssert fileExists(path), &"Invalid path {path}"
|
||||
|
||||
if gState.mode.Bl:
|
||||
gState.mode = getCompilerMode(path)
|
||||
|
|
@ -38,6 +38,7 @@ proc main(
|
|||
debug = false,
|
||||
defines: seq[string] = @[],
|
||||
dynlib: string = "",
|
||||
exclude: seq[string] = @[],
|
||||
feature: seq[Feature] = @[],
|
||||
includeDirs: seq[string] = @[],
|
||||
mode = "",
|
||||
|
|
@ -65,6 +66,7 @@ proc main(
|
|||
debug: debug,
|
||||
defines: defines,
|
||||
dynlib: dynlib,
|
||||
exclude: exclude,
|
||||
feature: feature,
|
||||
includeDirs: includeDirs,
|
||||
mode: mode,
|
||||
|
|
@ -222,6 +224,7 @@ when isMainModule:
|
|||
"debug": "enable debug output",
|
||||
"defines": "definitions to pass to preprocessor",
|
||||
"dynlib": "{.dynlib.} pragma to import symbols - Nim const string or file path",
|
||||
"exclude": "files or directories to exclude from the wrapped output",
|
||||
"feature": "flags to enable experimental features",
|
||||
"includeDirs": "include directory to pass to preprocessor",
|
||||
"mode": "language parser: c or cpp",
|
||||
|
|
@ -247,6 +250,7 @@ when isMainModule:
|
|||
"debug": 'd',
|
||||
"defines": 'D',
|
||||
"dynlib": 'l',
|
||||
"exclude": 'X',
|
||||
"feature": 'f',
|
||||
"includeDirs": 'I',
|
||||
"noComments": 'c',
|
||||
|
|
|
|||
|
|
@ -286,7 +286,16 @@ proc getKeyword*(kind: NimSymKind): string =
|
|||
proc getCurrentHeader*(fullpath: string): string =
|
||||
("header" & fullpath.splitFile().name.multiReplace([(".", ""), ("-", "")]))
|
||||
|
||||
proc isIncluded(gState: State, file: string): bool {.inline.} =
|
||||
# Check if the specified file should be excluded from wrapped output
|
||||
if gState.exclude.nBl:
|
||||
for excl in gState.exclude:
|
||||
if file.startsWith(excl):
|
||||
return
|
||||
result = true
|
||||
|
||||
proc getPreprocessor*(gState: State, fullpath: string) =
|
||||
# Get preprocessed output from the C/C++ compiler
|
||||
var
|
||||
args: seq[string]
|
||||
start = false
|
||||
|
|
@ -332,14 +341,15 @@ proc getPreprocessor*(gState: State, fullpath: string) =
|
|||
start = true
|
||||
elif gState.recurse:
|
||||
if (pDir.Bl or pDir in line) and line notin gState.headersProcessed:
|
||||
start = true
|
||||
newHeaders.incl line
|
||||
start = gState.isIncluded(line)
|
||||
else:
|
||||
for inc in includeDirs:
|
||||
if line.startsWith(inc) and line notin gState.headersProcessed:
|
||||
start = true
|
||||
newHeaders.incl line
|
||||
break
|
||||
start = gState.isIncluded(line)
|
||||
if start:
|
||||
break
|
||||
elif ": fatal error:" in line:
|
||||
doAssert false,
|
||||
"\n\nFailed in preprocessing, check if `cIncludeDir()` is needed or compiler `mode` is correct (c/cpp)" &
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue