Skip to content

Commit

Permalink
fix regression: -d:nimHasLibFFI was not being tested anymore (#14234)
Browse files Browse the repository at this point in the history
* * fix regression: -d:nimHasLibFFI was not being tested anymore,
in part because testament was silently treating some errors as easy to overlook messages
* turned that message into an error
* -d:nimHasLibFFI is now being tested with nim cpp
* use correct signatures for importc procs
* workaround for openbsd to unblock ctffi testing
  • Loading branch information
timotheecour authored May 6, 2020
1 parent b8e6ea7 commit 330b3c4
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 26 deletions.
9 changes: 6 additions & 3 deletions koch.nim
Original file line number Diff line number Diff line change
Expand Up @@ -289,11 +289,13 @@ proc findStartNim: string =
proc thVersion(i: int): string =
result = ("compiler" / "nim" & $i).exe

template doUseCpp(): bool = getEnv("NIM_COMPILE_TO_CPP", "false") == "true"

proc boot(args: string) =
var output = "compiler" / "nim".exe
var finalDest = "bin" / "nim".exe
# default to use the 'c' command:
let useCpp = getEnv("NIM_COMPILE_TO_CPP", "false") == "true"
let useCpp = doUseCpp()
let smartNimcache = (if "release" in args or "danger" in args: "nimcache/r_" else: "nimcache/d_") &
hostOS & "_" & hostCPU

Expand Down Expand Up @@ -542,8 +544,9 @@ proc runCI(cmd: string) =
execFold("nimble install -y libffi", "nimble install -y libffi")
const nimFFI = "./bin/nim.ctffi"
# no need to bootstrap with koch boot (would be slower)
execFold("build with -d:nimHasLibFFI", "nim c -d:release -d:nimHasLibFFI -o:$1 compiler/nim.nim" % [nimFFI])
execFold("test with -d:nimHasLibFFI", "$1 c -r testament/testament --nim:$1 r tests/vm/tevalffi.nim" % [nimFFI])
let backend = if doUseCpp(): "cpp" else: "c"
execFold("build with -d:nimHasLibFFI", "nim $1 -d:release -d:nimHasLibFFI -o:$2 compiler/nim.nim" % [backend, nimFFI])
execFold("test with -d:nimHasLibFFI", "$1 $2 -r testament/testament --nim:$1 r tests/trunner.nim" % [nimFFI, backend])

execFold("Run nimdoc tests", "nim c -r nimdoc/tester")
execFold("Run nimpretty tests", "nim c -r nimpretty/tester.nim")
Expand Down
2 changes: 1 addition & 1 deletion testament/categories.nim
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ proc processSingleTest(r: var TResults, cat: Category, options, test: string) =
if existsFile(test):
testSpec r, makeTest(test, options, cat), {target}
else:
echo "[Warning] - ", test, " test does not exist"
doAssert false, test & " test does not exist"

proc isJoinableSpec(spec: TSpec): bool =
result = not spec.sortoutput and
Expand Down
35 changes: 26 additions & 9 deletions tests/trunner.nim
Original file line number Diff line number Diff line change
@@ -1,43 +1,60 @@
discard """
targets: "c cpp"
joinable: false
"""

## tests that don't quite fit the mold and are easier to handle via `execCmdEx`
## A few others could be added to here to simplify code.

import std/[strformat,os,osproc,strutils]
import std/[strformat,os,osproc]

const nim = getCurrentCompilerExe()

const mode =
when defined(c): "c"
elif defined(cpp): "cpp"
else: static: doAssert false

proc runCmd(file, options = ""): auto =
let mode = if existsEnv("NIM_COMPILE_TO_CPP"): "cpp" else: "c"
const testsDir = currentSourcePath().parentDir
let fileabs = testsDir / file.unixToNativePath
doAssert fileabs.existsFile, fileabs
let cmd = fmt"{nim} {mode} {options} --hints:off {fileabs}"
result = execCmdEx(cmd)
when false: # uncomment if you need to debug
echo result[0]
echo result[1]
when false: echo result[0] & "\n" & result[1] # for debugging

when defined(nimHasLibFFIEnabled):
block: # mevalffi
let (output, exitCode) = runCmd("vm/mevalffi.nim", "--experimental:compiletimeFFI")
let expected = """
when defined(openbsd):
#[
openbsd defines `#define stderr (&__sF[2])` which makes it cumbersome
for dlopen'ing inside `importcSymbol`. Instead of adding special rules
inside `importcSymbol` to handle this, we disable just the part that's
not working and will provide a more general, clean fix in future PR.
]#
var opt = "-d:nimEvalffiStderrWorkaround"
let prefix = ""
else:
var opt = ""
let prefix = """
hello world stderr
hi stderr
foo
"""
let (output, exitCode) = runCmd("vm/mevalffi.nim", fmt"{opt} --experimental:compiletimeFFI")
let expected = fmt"""
{prefix}foo
foo:100
foo:101
foo:102:103
foo:102:103:104
foo:0.03:asdf:103:105
ret={s1:foobar s2:foobar age:25 pi:3.14}
ret=[s1:foobar s2:foobar age:25 pi:3.14]
"""
doAssert output == expected, output
doAssert exitCode == 0

else: # don't run twice the same test
import std/[strutils]
template check(msg) = doAssert msg in output, output

block: # mstatic_assert
Expand Down
30 changes: 17 additions & 13 deletions tests/vm/mevalffi.nim
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ proc c_exp(a: float64): float64 {.importc: "exp", header: "<math.h>".}
proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>", varargs, discardable.}

const snprintfName = when defined(windows): "_snprintf" else: "snprintf"
proc c_snprintf*(buffer: pointer, buf_size: uint, format: cstring): cint {.importc: snprintfName, header: "<stdio.h>", varargs .}
proc c_snprintf*(str: cstring, size: csize_t, format: cstring): cint {.importc: snprintfName, header: "<stdio.h>", varargs .}

proc c_malloc(size:uint):pointer {.importc:"malloc", header: "<stdlib.h>".}
proc c_malloc(size: csize_t): pointer {.importc:"malloc", header: "<stdlib.h>".}
proc c_free(p: pointer) {.importc:"free", header: "<stdlib.h>".}

proc fun() =
Expand All @@ -35,12 +35,15 @@ proc fun() =

block: # c_snprintf, c_malloc, c_free
let n: uint = 50
var buffer2: pointer = c_malloc(n)
var buffer2 = cstring(cast[ptr char](c_malloc(n)))

var s: cstring = "foobar"
var age: cint = 25
discard c_snprintf(buffer2, n, "s1:%s s2:%s age:%d pi:%g", s, s, age, 3.14)
c_printf("ret={%s}\n", buffer2)
c_free(buffer2) # not sure it has an effect
let num = c_snprintf(buffer2, n, "s1:%s s2:%s age:%d pi:%g", s, s, age, 3.14)
let numExp = 34
doAssert num == numExp
c_printf("ret=[%s]\n", buffer2)
c_free(buffer2)

block: # c_printf bug
var a = 123
Expand All @@ -58,10 +61,11 @@ static:
fun()
fun()

import system/ansi_c
block:
proc fun2()=
c_fprintf(cstderr, "hello world stderr\n")
write(stderr, "hi stderr\n")
static: fun2()
fun2()
when not defined nimEvalffiStderrWorkaround:
import system/ansi_c
block:
proc fun2()=
c_fprintf(cstderr, "hello world stderr\n")
write(stderr, "hi stderr\n")
static: fun2()
fun2()

0 comments on commit 330b3c4

Please sign in to comment.