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.currentHeader = getCurrentHeader(fullpath)
|
||||
nimState.constStr &= &"\n {nimState.currentHeader} = \"{fp}\""
|
||||
nimState.constStr &= &"\n {nimState.currentHeader} {{.used.}} = \"{fp}\""
|
||||
|
||||
root.searchAst(astTable, nimState)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ import hashes, macros, os, strformat, strutils
|
|||
|
||||
const CIMPORT {.used.} = 1
|
||||
|
||||
include "." / globals
|
||||
include "."/globals
|
||||
|
||||
import "." / [types, paths]
|
||||
import "."/[git, paths, types]
|
||||
export types
|
||||
|
||||
proc interpPath(dir: string): string=
|
||||
|
|
@ -359,7 +359,7 @@ proc cAddStdDir*(mode = "c") {.compileTime.} =
|
|||
if inc:
|
||||
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.}``
|
||||
##
|
||||
## ``path`` can be a specific file or contain wildcards:
|
||||
|
|
@ -376,6 +376,13 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
|||
## .. code-block:: nim
|
||||
##
|
||||
## 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)
|
||||
|
||||
|
|
@ -383,7 +390,8 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
|||
stmt = ""
|
||||
|
||||
proc fcompile(file: string): string =
|
||||
let fn = file.splitFile().name
|
||||
let
|
||||
(_, fn, ext) = file.splitFile()
|
||||
var
|
||||
ufn = fn
|
||||
uniq = 1
|
||||
|
|
@ -391,32 +399,53 @@ macro cCompile*(path: static string, mode = "c"): untyped =
|
|||
ufn = fn & $uniq
|
||||
uniq += 1
|
||||
|
||||
# - https://github.com/nim-lang/Nim/issues/10299
|
||||
# - https://github.com/nim-lang/Nim/issues/10486
|
||||
gStateCT.compile.add(ufn)
|
||||
if fn == ufn:
|
||||
return "{.compile: \"$#\".}" % file.replace("\\", "/")
|
||||
return "{.compile: \"$#\".}\n" % file.replace("\\", "/")
|
||||
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
|
||||
files = walkDirImpl(dir, ext)
|
||||
|
||||
for f in files:
|
||||
if f.len != 0:
|
||||
result &= fcompile(f) & "\n"
|
||||
if f.len != 0 and f.notExcluded(exclude):
|
||||
result &= fcompile(f)
|
||||
|
||||
if path.contains("*") or path.contains("?"):
|
||||
stmt &= dcompile(path)
|
||||
stmt &= dcompile(path, exclude.strVal())
|
||||
else:
|
||||
let fpath = findPath(path)
|
||||
if fileExists(fpath):
|
||||
stmt &= fcompile(fpath) & "\n"
|
||||
if fileExists(fpath) and fpath.notExcluded(exclude.strVal()):
|
||||
stmt &= fcompile(fpath)
|
||||
elif dirExists(fpath):
|
||||
if mode.strVal().contains("cpp"):
|
||||
for i in @["*.C", "*.cpp", "*.c++", "*.cc", "*.cxx"]:
|
||||
stmt &= dcompile(fpath, i)
|
||||
for i in @["*.cpp", "*.c++", "*.cc", "*.cxx"]:
|
||||
stmt &= dcompile(fpath, exclude.strVal(), i)
|
||||
when not defined(Windows):
|
||||
stmt &= dcompile(fpath, exclude.strVal(), "*.C")
|
||||
else:
|
||||
stmt &= dcompile(fpath, "*.c")
|
||||
stmt &= dcompile(fpath, exclude.strVal(), "*.c")
|
||||
|
||||
result.add stmt.parseStmt()
|
||||
|
||||
|
|
|
|||
|
|
@ -23,9 +23,70 @@ proc execAction*(cmd: string, nostderr=false): string =
|
|||
doAssert false, msg
|
||||
|
||||
proc mkDir*(dir: string) =
|
||||
if not dirExists(dir):
|
||||
let
|
||||
flag = when not defined(Windows): "-p" else: ""
|
||||
discard execAction(&"mkdir {flag} {dir.quoteShell}")
|
||||
|
||||
proc cpFile*(source, dest: string, move=false) =
|
||||
let
|
||||
flag = when not defined(Windows): "-p" else: ""
|
||||
discard execAction(&"mkdir {flag} {dir.quoteShell}")
|
||||
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) =
|
||||
var cmd = "unzip -o $#"
|
||||
|
|
@ -62,18 +123,9 @@ proc gitReset*(outdir: string) =
|
|||
sleep(1000)
|
||||
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) =
|
||||
echo "Resetting " & file
|
||||
let file2 = file.relativePathNaive outdir
|
||||
let file2 = file.relativePath outdir
|
||||
let cmd = &"cd {outdir.quoteShell} && git checkout {file2.quoteShell}"
|
||||
while execAction(cmd).contains("Permission denied"):
|
||||
sleep(500)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue