Add exclude to cCompile, fix duplicate filename compilation, mkDir fix, cp/mvFile, full relativePath
This commit is contained in:
parent
61eb045744
commit
10aef55dad
3 changed files with 109 additions and 28 deletions
|
|
@ -146,7 +146,7 @@ proc printNim*(fullpath: string, root: TSNode, astTable: AstTable) =
|
||||||
nimState.identifiers = newTable[string, string]()
|
nimState.identifiers = newTable[string, string]()
|
||||||
|
|
||||||
nimState.currentHeader = getCurrentHeader(fullpath)
|
nimState.currentHeader = getCurrentHeader(fullpath)
|
||||||
nimState.constStr &= &"\n {nimState.currentHeader} = \"{fp}\""
|
nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\""
|
||||||
|
|
||||||
root.searchAst(astTable, nimState)
|
root.searchAst(astTable, nimState)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const CIMPORT {.used.} = 1
|
||||||
|
|
||||||
include "."/globals
|
include "."/globals
|
||||||
|
|
||||||
import "." / [types, paths]
|
import "."/[git, paths, types]
|
||||||
export types
|
export types
|
||||||
|
|
||||||
proc interpPath(dir: string): string=
|
proc interpPath(dir: string): string=
|
||||||
|
|
@ -359,7 +359,7 @@ proc cAddStdDir*(mode = "c") {.compileTime.} =
|
||||||
if inc:
|
if inc:
|
||||||
cAddSearchDir line.strip()
|
cAddSearchDir line.strip()
|
||||||
|
|
||||||
macro cCompile*(path: static string, mode = "c"): untyped =
|
macro cCompile*(path: static string, mode = "c", exclude = ""): untyped =
|
||||||
## Compile and link C/C++ implementation into resulting binary using ``{.compile.}``
|
## Compile and link C/C++ implementation into resulting binary using ``{.compile.}``
|
||||||
##
|
##
|
||||||
## ``path`` can be a specific file or contain wildcards:
|
## ``path`` can be a specific file or contain wildcards:
|
||||||
|
|
@ -376,6 +376,13 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
||||||
## .. code-block:: nim
|
## .. code-block:: nim
|
||||||
##
|
##
|
||||||
## cCompile("path/to/dir", "cpp")
|
## cCompile("path/to/dir", "cpp")
|
||||||
|
##
|
||||||
|
## ``exclude`` can be used to exclude files by partial string match. Comma separated to
|
||||||
|
## specify multiple exclude strings
|
||||||
|
##
|
||||||
|
## .. code-block:: nim
|
||||||
|
##
|
||||||
|
## cCompile("path/to/dir", exclude="test2.c")
|
||||||
|
|
||||||
result = newNimNode(nnkStmtList)
|
result = newNimNode(nnkStmtList)
|
||||||
|
|
||||||
|
|
@ -383,7 +390,8 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
||||||
stmt = ""
|
stmt = ""
|
||||||
|
|
||||||
proc fcompile(file: string): string =
|
proc fcompile(file: string): string =
|
||||||
let fn = file.splitFile().name
|
let
|
||||||
|
(_, fn, ext) = file.splitFile()
|
||||||
var
|
var
|
||||||
ufn = fn
|
ufn = fn
|
||||||
uniq = 1
|
uniq = 1
|
||||||
|
|
@ -391,32 +399,53 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
||||||
ufn = fn & $uniq
|
ufn = fn & $uniq
|
||||||
uniq += 1
|
uniq += 1
|
||||||
|
|
||||||
|
# - https://github.com/nim-lang/Nim/issues/10299
|
||||||
|
# - https://github.com/nim-lang/Nim/issues/10486
|
||||||
gStateCT.compile.add(ufn)
|
gStateCT.compile.add(ufn)
|
||||||
if fn == ufn:
|
if fn == ufn:
|
||||||
return "{.compile: \"$#\".}" % file.replace("\\", "/")
|
return "{.compile: \"$#\".}\n" % file.replace("\\", "/")
|
||||||
else:
|
else:
|
||||||
return "{.compile: (\"../$#\", \"$#.o\").}" % [file.replace("\\", "/"), ufn]
|
# - https://github.com/nim-lang/Nim/issues/9370
|
||||||
|
let
|
||||||
|
hash = file.hash().abs()
|
||||||
|
tmpFile = file.parentDir() / &"_nimterop_{$hash}_{ufn}{ext}"
|
||||||
|
if not tmpFile.fileExists() or file.getFileDate() > tmpFile.getFileDate():
|
||||||
|
cpFile(file, tmpFile)
|
||||||
|
return "{.compile: \"$#\".}\n" % tmpFile.replace("\\", "/")
|
||||||
|
|
||||||
proc dcompile(dir: string, ext=""): string =
|
# Due to https://github.com/nim-lang/Nim/issues/9863
|
||||||
|
# cannot use seq[string] for excludes
|
||||||
|
proc notExcluded(file, exclude: string): bool =
|
||||||
|
result = true
|
||||||
|
if "_nimterop_" in file:
|
||||||
|
result = false
|
||||||
|
elif exclude.len != 0:
|
||||||
|
for excl in exclude.split(","):
|
||||||
|
if excl in file:
|
||||||
|
result = false
|
||||||
|
|
||||||
|
proc dcompile(dir, exclude: string, ext=""): string =
|
||||||
let
|
let
|
||||||
files = walkDirImpl(dir, ext)
|
files = walkDirImpl(dir, ext)
|
||||||
|
|
||||||
for f in files:
|
for f in files:
|
||||||
if f.len != 0:
|
if f.len != 0 and f.notExcluded(exclude):
|
||||||
result &= fcompile(f) & "\n"
|
result &= fcompile(f)
|
||||||
|
|
||||||
if path.contains("*") or path.contains("?"):
|
if path.contains("*") or path.contains("?"):
|
||||||
stmt &= dcompile(path)
|
stmt &= dcompile(path, exclude.strVal())
|
||||||
else:
|
else:
|
||||||
let fpath = findPath(path)
|
let fpath = findPath(path)
|
||||||
if fileExists(fpath):
|
if fileExists(fpath) and fpath.notExcluded(exclude.strVal()):
|
||||||
stmt &= fcompile(fpath) & "\n"
|
stmt &= fcompile(fpath)
|
||||||
elif dirExists(fpath):
|
elif dirExists(fpath):
|
||||||
if mode.strVal().contains("cpp"):
|
if mode.strVal().contains("cpp"):
|
||||||
for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]:
|
for i in @["*.cpp", "*.c++", "*.cc", "*.cxx"]:
|
||||||
stmt &= dcompile(fpath, i)
|
stmt &= dcompile(fpath, exclude.strVal(), i)
|
||||||
|
when not defined(Windows):
|
||||||
|
stmt &= dcompile(fpath, exclude.strVal(), "*.C")
|
||||||
else:
|
else:
|
||||||
stmt &= dcompile(fpath, "*.c")
|
stmt &= dcompile(fpath, exclude.strVal(), "*.c")
|
||||||
|
|
||||||
result.add stmt.parseStmt()
|
result.add stmt.parseStmt()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,71 @@ proc execAction*(cmd: string, nostderr=false): string =
|
||||||
doAssert false, msg
|
doAssert false, msg
|
||||||
|
|
||||||
proc mkDir*(dir: string) =
|
proc mkDir*(dir: string) =
|
||||||
|
if not dirExists(dir):
|
||||||
let
|
let
|
||||||
flag = when not defined(Windows): "-p" else: ""
|
flag = when not defined(Windows): "-p" else: ""
|
||||||
discard execAction(&"mkdir {flag} {dir.quoteShell}")
|
discard execAction(&"mkdir {flag} {dir.quoteShell}")
|
||||||
|
|
||||||
|
proc cpFile*(source, dest: string, move=false) =
|
||||||
|
let
|
||||||
|
source = source.replace("/", $DirSep)
|
||||||
|
dest = dest.replace("/", $DirSep)
|
||||||
|
cmd =
|
||||||
|
when defined(Windows):
|
||||||
|
if move:
|
||||||
|
"move /y"
|
||||||
|
else:
|
||||||
|
"copy /y"
|
||||||
|
else:
|
||||||
|
if move:
|
||||||
|
"mv -f"
|
||||||
|
else:
|
||||||
|
"cp -f"
|
||||||
|
|
||||||
|
discard execAction(&"{cmd} {source.quoteShell} {dest.quoteShell}")
|
||||||
|
|
||||||
|
proc mvFile*(source, dest: string) =
|
||||||
|
cpFile(source, dest, move=true)
|
||||||
|
|
||||||
|
when (NimMajor, NimMinor, NimPatch) < (0, 19, 9):
|
||||||
|
proc relativePath*(path, base: string; sep = DirSep): string =
|
||||||
|
## Copied from `os.relativePath` ; remove after nim >= 0.19.9
|
||||||
|
if path.len == 0: return ""
|
||||||
|
var f, b: PathIter
|
||||||
|
var ff = (0, -1)
|
||||||
|
var bb = (0, -1) # (int, int)
|
||||||
|
result = newStringOfCap(path.len)
|
||||||
|
while f.hasNext(path) and b.hasNext(base):
|
||||||
|
ff = next(f, path)
|
||||||
|
bb = next(b, base)
|
||||||
|
let diff = ff[1] - ff[0]
|
||||||
|
if diff != bb[1] - bb[0]: break
|
||||||
|
var same = true
|
||||||
|
for i in 0..diff:
|
||||||
|
if path[i + ff[0]] !=? base[i + bb[0]]:
|
||||||
|
same = false
|
||||||
|
break
|
||||||
|
if not same: break
|
||||||
|
ff = (0, -1)
|
||||||
|
bb = (0, -1)
|
||||||
|
|
||||||
|
while true:
|
||||||
|
if bb[1] >= bb[0]:
|
||||||
|
if result.len > 0 and result[^1] != sep:
|
||||||
|
result.add sep
|
||||||
|
result.add ".."
|
||||||
|
if not b.hasNext(base): break
|
||||||
|
bb = b.next(base)
|
||||||
|
|
||||||
|
while true:
|
||||||
|
if ff[1] >= ff[0]:
|
||||||
|
if result.len > 0 and result[^1] != sep:
|
||||||
|
result.add sep
|
||||||
|
for i in 0..ff[1] - ff[0]:
|
||||||
|
result.add path[i + ff[0]]
|
||||||
|
if not f.hasNext(path): break
|
||||||
|
ff = f.next(path)
|
||||||
|
|
||||||
proc extractZip*(zipfile, outdir: string) =
|
proc extractZip*(zipfile, outdir: string) =
|
||||||
var cmd = "unzip -o $#"
|
var cmd = "unzip -o $#"
|
||||||
if defined(Windows):
|
if defined(Windows):
|
||||||
|
|
@ -62,18 +123,9 @@ proc gitReset*(outdir: string) =
|
||||||
sleep(1000)
|
sleep(1000)
|
||||||
echo " Retrying ..."
|
echo " Retrying ..."
|
||||||
|
|
||||||
proc relativePathNaive*(file, base: string): string =
|
|
||||||
## naive version of `os.relativePath` ; remove after nim >= 0.19.9
|
|
||||||
runnableExamples:
|
|
||||||
doAssert "/foo/bar/baz/log.txt".relativePathNaive("/foo/bar") == "baz/log.txt"
|
|
||||||
var base = base
|
|
||||||
if not base.endsWith "/": base.add "/"
|
|
||||||
doAssert file.startsWith base
|
|
||||||
result = file[base.len .. ^1]
|
|
||||||
|
|
||||||
proc gitCheckout*(file, outdir: string) =
|
proc gitCheckout*(file, outdir: string) =
|
||||||
echo "Resetting " & file
|
echo "Resetting " & file
|
||||||
let file2 = file.relativePathNaive outdir
|
let file2 = file.relativePath outdir
|
||||||
let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}"
|
let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}"
|
||||||
while execAction(cmd).contains("Permission denied"):
|
while execAction(cmd).contains("Permission denied"):
|
||||||
sleep(500)
|
sleep(500)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue