merge from upstream #1

Merged
jyapayne merged 8 commits from master into master 2021-01-23 04:38:37 +00:00
10 changed files with 125 additions and 50 deletions

View file

@ -1,11 +1,11 @@
# Package # Package
version = "0.6.11" version = "0.6.13"
author = "genotrance" author = "genotrance"
description = "C/C++ interop for Nim" description = "C/C++ interop for Nim"
license = "MIT" license = "MIT"
bin = @["nimterop/toast"] bin = @["nimterop/toast", "nimterop/loaf"]
installDirs = @["nimterop"] installDirs = @["nimterop"]
# Dependencies # Dependencies
@ -33,6 +33,9 @@ proc execTest(test: string, flags = "", runDocs = true) =
task buildTimeit, "build timer": task buildTimeit, "build timer":
exec "nim c --hints:off -d:danger tests/timeit" exec "nim c --hints:off -d:danger tests/timeit"
task buildLoaf, "build loaf":
execCmd("nim c --hints:off -d:danger nimterop/loaf.nim")
task buildToast, "build toast": task buildToast, "build toast":
execCmd("nim c --hints:off -d:danger nimterop/toast.nim") execCmd("nim c --hints:off -d:danger nimterop/toast.nim")
@ -46,6 +49,7 @@ task docs, "Generate docs":
buildDocs(@["nimterop/all.nim"], "build/htmldocs") buildDocs(@["nimterop/all.nim"], "build/htmldocs")
task minitest, "Test for Nim CI": task minitest, "Test for Nim CI":
exec "nim c -f -d:danger nimterop/loaf.nim"
exec "nim c -f -d:danger nimterop/toast" exec "nim c -f -d:danger nimterop/toast"
exec "nim c -f -d:checkAbi -r tests/tast2.nim" exec "nim c -f -d:checkAbi -r tests/tast2.nim"
exec "nim c -f -d:checkAbi -d:zlibJBB -d:zlibSetVer=1.2.11 -r tests/zlib.nim" exec "nim c -f -d:checkAbi -d:zlibJBB -d:zlibSetVer=1.2.11 -r tests/zlib.nim"
@ -89,6 +93,7 @@ task test, "Test":
rmFile("tests/timeit.txt") rmFile("tests/timeit.txt")
buildTimeitTask() buildTimeitTask()
buildLoafTask()
buildToastTask() buildToastTask()
basicTask() basicTask()

View file

@ -75,7 +75,7 @@ proc getGccLibPaths*(mode: string): seq[string] =
when defined(osx): when defined(osx):
result.add "/usr/lib" result.add "/usr/lib"
proc getGccInfo*(): tuple[arch, os, compiler, version: string] = proc getGccInfo*(): tuple[arch, os, compiler, version, libc: string] =
let let
(outp, _) = execAction(&"{getCompiler()} -v") (outp, _) = execAction(&"{getCompiler()} -v")
for line in outp.splitLines(): for line in outp.splitLines():
@ -101,3 +101,5 @@ proc getGccInfo*(): tuple[arch, os, compiler, version: string] =
result.compiler = "clang" result.compiler = "clang"
else: else:
result.compiler = "gcc" result.compiler = "gcc"
if "musl" in outp:
result.libc = "musl"

View file

@ -16,6 +16,8 @@ type
channel*: string channel*: string
recipes*: OrderedTableRef[string, seq[ConanBuild]] recipes*: OrderedTableRef[string, seq[ConanBuild]]
arch*, os*, compiler*, compversion*: string
bhash*: string bhash*: string
shared*: bool shared*: bool
sharedLibs*: seq[string] sharedLibs*: seq[string]
@ -89,6 +91,11 @@ proc `==`*(pkg1, pkg2: ConanPackage): bool =
pkg1.user == pkg2.user and pkg1.user == pkg2.user and
pkg1.channel == pkg2.channel and pkg1.channel == pkg2.channel and
pkg1.arch == pkg2.arch and
pkg1.os == pkg2.os and
pkg1.compiler == pkg2.compiler and
pkg1.compversion == pkg2.compversion and
pkg1.bhash == pkg2.bhash and pkg1.bhash == pkg2.bhash and
pkg1.shared == pkg2.shared) pkg1.shared == pkg2.shared)
@ -101,6 +108,15 @@ proc newConanPackage*(name, version, user = "_", channel = "_", bhash = "", shar
result.channel = channel result.channel = channel
result.recipes = newOrderedTable[string, seq[ConanBuild]](2) result.recipes = newOrderedTable[string, seq[ConanBuild]](2)
let
(arch, os, compiler, compversion, libc) = getGccInfo()
doAssert libc != "musl", "Conan does not provide precompiled binaries using musl"
result.arch = arch
result.os = os
result.compiler = compiler
result.compversion = compversion
result.bhash = bhash result.bhash = bhash
result.shared = shared result.shared = shared
@ -189,9 +205,7 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") =
## `filter` can be used to tweak search terms ## `filter` can be used to tweak search terms
## e.g. build_type=Debug&compiler=clang ## e.g. build_type=Debug&compiler=clang
let let
(arch, os, compiler, version) = getGccInfo() vsplit = pkg.compversion.split('.')
vsplit = version.split('.')
vfilter = vfilter =
when defined(OSX): when defined(OSX):
@ -203,18 +217,18 @@ proc getConanBuilds*(pkg: ConanPackage, filter = "") =
if pkg.bhash.Bl: if pkg.bhash.Bl:
block: block:
var var
query = &"?q=arch={arch}&os={os.capitalizeAscii()}" query = &"?q=arch={pkg.arch}&os={pkg.os.capitalizeAscii()}"
if "build_type" notin filter: if "build_type" notin filter:
query &= "&build_type=Release" query &= "&build_type=Release"
if "shared=" notin filter: if "shared=" notin filter:
query &= &"&options.shared={($pkg.shared).capitalizeAscii()}" query &= &"&options.shared={($pkg.shared).capitalizeAscii()}"
if filter.nBl: if filter.nBl:
query &= &"&{filter}" query &= &"&{filter}"
if "compiler=" notin filter and os != "windows": if "compiler=" notin filter and pkg.os != "windows":
query &= &"&compiler={compiler}&compiler.version=" & vfilter query &= &"&compiler={pkg.compiler}&compiler.version=" & vfilter
if "compiler.runtime=" notin filter and os == "windows": if "compiler.runtime=" notin filter and pkg.os == "windows":
query &= &"&compiler.runtime=MD" query &= &"&compiler.runtime=MD"
if "compiler.version=" notin filter and os == "windows": if "compiler.version=" notin filter and pkg.os == "windows":
query &= &"&compiler.version=14" query &= &"&compiler.version=14"
query.replace("&", "%20and%20") query.replace("&", "%20and%20")

View file

@ -208,11 +208,12 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT
var var
lpath = findFile(lname, outdir, regex = true) lpath = findFile(lname, outdir, regex = true)
makePath = outdir makePath = outdir
buildStatus: BuildStatus
errors: seq[string]
if lpath.nBl: if lpath.nBl:
return lpath return lpath
var buildStatus: BuildStatus
for buildType in buildTypes: for buildType in buildTypes:
case buildType case buildType
@ -223,6 +224,8 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT
if buildStatus.built: if buildStatus.built:
break break
elif buildStatus.error.nBl:
errors.add buildStatus.error
if buildStatus.buildPath.len > 0: if buildStatus.buildPath.len > 0:
let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0 let libraryExists = findFile(lname, buildStatus.buildPath, regex = true).len > 0
@ -231,7 +234,7 @@ proc buildLibrary(lname, outdir, conFlags, cmakeFlags, makeFlags: string, buildT
make(buildStatus.buildPath, lname, makeFlags, regex = true) make(buildStatus.buildPath, lname, makeFlags, regex = true)
buildStatus.built = true buildStatus.built = true
let error = if buildStatus.error.len > 0: buildStatus.error else: "No build files found in " & outdir let error = if errors.len > 0: errors.join("\n") else: "No build files found in " & outdir
doAssert buildStatus.built, &"\nBuild configuration failed - {error}\n" doAssert buildStatus.built, &"\nBuild configuration failed - {error}\n"
result = findFile(lname, outdir, regex = true) result = findFile(lname, outdir, regex = true)

View file

@ -17,6 +17,8 @@ type
url*: string # Download URL url*: string # Download URL
arch*, os*, libc*: string # Target
sharedLibs*: seq[string] sharedLibs*: seq[string]
staticLibs*: seq[string] staticLibs*: seq[string]
requires*: seq[JBBPackage] requires*: seq[JBBPackage]
@ -39,7 +41,11 @@ proc `==`*(pkg1, pkg2: JBBPackage): bool =
## Check if two JBBPackage objects are equal ## Check if two JBBPackage objects are equal
(not pkg1.isNil and not pkg2.isNil and (not pkg1.isNil and not pkg2.isNil and
pkg1.name == pkg2.name and pkg1.name == pkg2.name and
pkg1.version == pkg2.version) pkg1.version == pkg2.version and
pkg1.arch == pkg2.arch and
pkg1.os == pkg2.os and
pkg1.libc == pkg2.libc)
proc newJBBPackage*(name, version: string): JBBPackage = proc newJBBPackage*(name, version: string): JBBPackage =
## Create a new JBBPackage with specified name and version ## Create a new JBBPackage with specified name and version
@ -49,6 +55,12 @@ proc newJBBPackage*(name, version: string): JBBPackage =
result.baseUrl = jbbBaseUrl result.baseUrl = jbbBaseUrl
result.isGit = true result.isGit = true
let
(arch, os, _, _, libc) = getGccInfo()
result.arch = arch
result.os = os
result.libc = libc
proc parseJBBProject(pkg: JBBPackage, outdir: string) = proc parseJBBProject(pkg: JBBPackage, outdir: string) =
# Get all dependencies from Project.toml # Get all dependencies from Project.toml
let let
@ -87,8 +99,6 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) =
let let
file = outdir / jbbArtifacts file = outdir / jbbArtifacts
(arch, os, _, _) = getGccInfo()
if fileExists(file): if fileExists(file):
let let
data = readFile(file) data = readFile(file)
@ -109,12 +119,14 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) =
# Match arch, os and glibc on Linux to find download URL # Match arch, os and glibc on Linux to find download URL
case name case name
of "arch": of "arch":
if val == arch and not found: found = true if val == pkg.arch and not found: found = true
of "os": of "os":
if val != os and found: found = false if val != pkg.os and found: found = false
of "libc": of "libc":
when defined(Linux): when defined(Linux):
if val != "glibc" and found: found = false if found:
let libc = if pkg.libc.nBl: pkg.libc else: "glibc"
if val != libc: found = false
of "url": of "url":
if found: if found:
pkg.url = val pkg.url = val
@ -125,7 +137,7 @@ proc parseJBBArtifacts(pkg: JBBPackage, outdir: string) =
proc findJBBLibs(pkg: JBBPackage, outdir: string) = proc findJBBLibs(pkg: JBBPackage, outdir: string) =
pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dylib)[0-9.]*", outdir) pkg.sharedLibs = findFiles("(bin|lib)[\\\\/].*\\.(so|dll|dylib)[0-9.]*", outdir)
for lib in findFiles("lib[\\\\/].*\\.(a|lib)$", outdir): for lib in findFiles("lib[\\\\/].*\\.(a|lib)", outdir):
if not lib.endsWith(".dll.a"): if not lib.endsWith(".dll.a"):
pkg.staticLibs.add lib pkg.staticLibs.add lib

View file

@ -407,29 +407,24 @@ proc gitTags*(outdir: string): seq[string] =
if tag.len != 0: if tag.len != 0:
result.add tag result.add tag
proc loafExePath(): string =
currentSourcePath.parentDir.parentDir / ("loaf".addFileExt ExeExt)
proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[string] = proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[string] =
## Find all matching files in the specified directory ## Find all matching files in the specified directory
## ##
## `file` is a regular expression if `regex` is true ## `file` is a regular expression if `regex` is true
## ##
## Turn off recursive search with `recurse` ## Turn off recursive search with `recurse`
let
loafExe = loafExePath()
doAssert fileExists(loafExe), "loaf not compiled: " & loafExe.sanitizePath &
" make sure 'nimble build' or 'nimble install' built it"
var var
cmd = cmd = loafExe.quoteShell & " find --rexp $1 \"$2\" $3"
when defined(Windows): recursive = if recurse: "--recurse" else: ""
"nimgrep --filenames --oneline --nocolor $1 \"$2\" $3"
elif defined(linux):
"find $3 $1 -regextype egrep -regex $2"
elif defined(osx) or defined(FreeBSD):
"find -E $3 $1 -regex $2"
recursive = ""
if recurse:
when defined(Windows):
recursive = "--recursive"
else:
when not defined(Windows):
recursive = "-maxdepth 1"
var var
dir = dir dir = dir
@ -443,22 +438,14 @@ proc findFiles*(file: string, dir: string, recurse = true, regex = false): seq[s
file = file.extractFilename file = file.extractFilename
cmd = cmd % [recursive, (".*[\\\\/]" & file & "$").quoteShell, dir.sanitizePath] cmd = cmd % [recursive, (".*[\\\\/]" & file & "$"), dir.sanitizePath]
let let
(files, ret) = execAction(cmd, die = false) (files, ret) = execAction(cmd, die = false)
if ret == 0: if ret == 0:
for line in files.splitLines(): for line in files.splitLines():
let f = if line.len != 0:
when defined(Windows): result.add line
if ": " in line:
line.split(": ", maxsplit = 1)[1]
else:
""
else:
line
if f.len != 0:
result.add f
proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string = proc findFile*(file: string, dir: string, recurse = true, first = false, regex = false): string =
## Find the file in the specified directory ## Find the file in the specified directory

39
nimterop/loaf.nim Normal file
View file

@ -0,0 +1,39 @@
import system except find
import os
import cligen
import strutils except find
import regex except find
proc findRec(dir: string, pattern: string | Regex, recurse: bool) =
for kind, path in walkDir(dir):
if kind in [pcDir, pcLinkToDir]:
if recurse: findRec(path, pattern, recurse)
elif pattern in path:
echo path.absolutePath()
proc find(recurse = false, rexp = false, args: seq[string]) =
var
pat = ""
rpat: Regex
for arg in args:
if not arg.startsWith("-"):
if dirExists(arg):
if rexp:
findRec(arg, rpat, recurse)
else:
findRec(arg, pat, recurse)
else:
pat = arg
if rexp: rpat = re(arg)
when isMainModule:
dispatchMulti([
find, help = {
"recurse": "recursive search",
"rexp": "patterns are regular expressions",
"args": "pattern1 dir1 dir2 pattern2 dir3 ..."
}
])

View file

@ -379,18 +379,28 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode)
result.add gState.getIdent(nimSym) result.add gState.getIdent(nimSym)
let leftNode = gState.processTSNode(left, typeofNode) let leftNode = gState.processTSNode(left, typeofNode)
var tyNode = typeofNode
if typeofNode.isNil: if typeofNode.isNil:
typeofNode = nkCall.newTree( typeofNode = nkCall.newTree(
gState.getIdent("typeof"), gState.getIdent("typeof"),
leftNode leftNode
) )
tyNode = typeofNode
let rightNode = gState.processTSNode(right, typeofNode) # Special case of setting the shift left/right type
# to be the type of the direct left operand
if binarySym in [">>", "<<"]:
tyNode = nkCall.newTree(
gState.getIdent("typeof"),
leftNode
)
let rightNode = gState.processTSNode(right, tyNode)
result.add leftNode result.add leftNode
result.add nkCall.newTree( result.add nkCall.newTree(
typeofNode, tyNode,
rightNode rightNode
) )
if binarySym == "/": if binarySym == "/":
@ -399,7 +409,7 @@ proc processBinaryExpression(gState: State, node: TSNode, typeofNode: var PNode)
# So we need to emulate C here and cast the whole # So we need to emulate C here and cast the whole
# expression to the type of the first arg # expression to the type of the first arg
result = nkCall.newTree( result = nkCall.newTree(
typeofNode, tyNode,
result result
) )

View file

@ -35,6 +35,7 @@ extern "C" {
#define EQ4 AVAL < BVAL #define EQ4 AVAL < BVAL
#define EQ5 AVAL != BVAL #define EQ5 AVAL != BVAL
#define EQ6 AVAL == BVAL #define EQ6 AVAL == BVAL
#define SX_NEAR_ZERO (1.0f / (1 << 28))
// testing integer out of long int range // testing integer out of long int range
#define INT_FAST16_MIN (-9223372036854775807L-1) #define INT_FAST16_MIN (-9223372036854775807L-1)

View file

@ -134,6 +134,8 @@ assert EQ4 == (AVAL < BVAL)
assert EQ5 == (AVAL != BVAL) assert EQ5 == (AVAL != BVAL)
assert EQ6 == (AVAL == BVAL) assert EQ6 == (AVAL == BVAL)
assert SX_NEAR_ZERO == 3.725290298461914e-09
assert SIZEOF == 1 assert SIZEOF == 1
assert COERCE == 645635670332'u64 assert COERCE == 645635670332'u64