enable testing -d:nimHasLibFFI mode (#13091)
This commit is contained in:
parent
b20d7e2110
commit
e70294dff2
8 changed files with 110 additions and 96 deletions
|
|
@ -74,10 +74,12 @@ jobs:
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
sudo apt-fast update -qq
|
sudo apt-fast update -qq
|
||||||
|
# `:i386` (e.g. in `libffi-dev:i386`) is needed otherwise you may get:
|
||||||
|
# `could not load: libffi.so` during dynamic loading.
|
||||||
DEBIAN_FRONTEND='noninteractive' \
|
DEBIAN_FRONTEND='noninteractive' \
|
||||||
sudo apt-fast install --no-install-recommends --allow-downgrades -yq \
|
sudo apt-fast install --no-install-recommends --allow-downgrades -yq \
|
||||||
g++-multilib gcc-multilib libcurl4-openssl-dev:i386 libgc-dev:i386 \
|
g++-multilib gcc-multilib libcurl4-openssl-dev:i386 libgc-dev:i386 \
|
||||||
libsdl1.2-dev:i386 libsfml-dev:i386 libglib2.0-dev:i386
|
libsdl1.2-dev:i386 libsfml-dev:i386 libglib2.0-dev:i386 libffi-dev:i386
|
||||||
|
|
||||||
cat << EOF > bin/gcc
|
cat << EOF > bin/gcc
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
|
||||||
|
|
@ -103,3 +103,9 @@ proc initDefines*(symbols: StringTableRef) =
|
||||||
defineSymbol("nimNewShiftOps")
|
defineSymbol("nimNewShiftOps")
|
||||||
defineSymbol("nimHasCursor")
|
defineSymbol("nimHasCursor")
|
||||||
defineSymbol("nimHasExceptionsQuery")
|
defineSymbol("nimHasExceptionsQuery")
|
||||||
|
|
||||||
|
when defined(nimHasLibFFI):
|
||||||
|
# Renaming as we can't conflate input vs output define flags; e.g. this
|
||||||
|
# will report the right thing regardless of whether user adds
|
||||||
|
# `-d:nimHasLibFFI` in his user config.
|
||||||
|
defineSymbol("nimHasLibFFIEnabled")
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ when defined(windows):
|
||||||
const libcDll = "msvcrt.dll"
|
const libcDll = "msvcrt.dll"
|
||||||
elif defined(linux):
|
elif defined(linux):
|
||||||
const libcDll = "libc.so(.6|.5|)"
|
const libcDll = "libc.so(.6|.5|)"
|
||||||
|
elif defined(bsd):
|
||||||
|
const libcDll = "/lib/libc.so.7"
|
||||||
elif defined(osx):
|
elif defined(osx):
|
||||||
const libcDll = "/usr/lib/libSystem.dylib"
|
const libcDll = "/usr/lib/libSystem.dylib"
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
11
koch.nim
11
koch.nim
|
|
@ -485,10 +485,6 @@ proc runCI(cmd: string) =
|
||||||
## build nimble early on to enable remainder to depend on it if needed
|
## build nimble early on to enable remainder to depend on it if needed
|
||||||
kochExecFold("Build Nimble", "nimble")
|
kochExecFold("Build Nimble", "nimble")
|
||||||
|
|
||||||
when false:
|
|
||||||
execFold("nimble install -y libffi", "nimble install -y libffi")
|
|
||||||
kochExecFold("boot -d:release -d:nimHasLibFFI", "boot -d:release -d:nimHasLibFFI")
|
|
||||||
|
|
||||||
if getEnv("NIM_TEST_PACKAGES", "false") == "true":
|
if getEnv("NIM_TEST_PACKAGES", "false") == "true":
|
||||||
execFold("Test selected Nimble packages", "nim c -r testament/testament cat nimble-packages")
|
execFold("Test selected Nimble packages", "nim c -r testament/testament cat nimble-packages")
|
||||||
else:
|
else:
|
||||||
|
|
@ -502,6 +498,13 @@ proc runCI(cmd: string) =
|
||||||
|
|
||||||
# main bottleneck here
|
# main bottleneck here
|
||||||
execFold("Run tester", "nim c -r -d:nimCoroutines testament/testament --pedantic all -d:nimCoroutines")
|
execFold("Run tester", "nim c -r -d:nimCoroutines testament/testament --pedantic all -d:nimCoroutines")
|
||||||
|
block: # CT FFI
|
||||||
|
when defined(posix): # windows can be handled in future PR's
|
||||||
|
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])
|
||||||
|
|
||||||
execFold("Run nimdoc tests", "nim c -r nimdoc/tester")
|
execFold("Run nimdoc tests", "nim c -r nimdoc/tester")
|
||||||
execFold("Run nimpretty tests", "nim c -r nimpretty/tester.nim")
|
execFold("Run nimpretty tests", "nim c -r nimpretty/tester.nim")
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,7 @@ type
|
||||||
CFilePtr* = ptr CFile ## The type representing a file handle.
|
CFilePtr* = ptr CFile ## The type representing a file handle.
|
||||||
|
|
||||||
# duplicated between io and ansi_c
|
# duplicated between io and ansi_c
|
||||||
const stdioUsesMacros = defined(osx) and not defined(emscripten)
|
const stdioUsesMacros = (defined(osx) or defined(bsd)) and not defined(emscripten)
|
||||||
const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr"
|
const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr"
|
||||||
const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout"
|
const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout"
|
||||||
const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin"
|
const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin"
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ type
|
||||||
# text file handling:
|
# text file handling:
|
||||||
when not defined(nimscript) and not defined(js):
|
when not defined(nimscript) and not defined(js):
|
||||||
# duplicated between io and ansi_c
|
# duplicated between io and ansi_c
|
||||||
const stdioUsesMacros = defined(osx) and not defined(emscripten)
|
const stdioUsesMacros = (defined(osx) or defined(bsd)) and not defined(emscripten)
|
||||||
const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr"
|
const stderrName = when stdioUsesMacros: "__stderrp" else: "stderr"
|
||||||
const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout"
|
const stdoutName = when stdioUsesMacros: "__stdoutp" else: "stdout"
|
||||||
const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin"
|
const stdinName = when stdioUsesMacros: "__stdinp" else: "stdin"
|
||||||
|
|
|
||||||
67
tests/vm/mevalffi.nim
Normal file
67
tests/vm/mevalffi.nim
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# re-enable for windows once libffi can be installed in koch.nim
|
||||||
|
# With win32 (not yet win64), libffi on windows works and this test passes.
|
||||||
|
|
||||||
|
when defined(linux) or defined(bsd):
|
||||||
|
{.passL: "-lm".} # for exp
|
||||||
|
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_malloc(size:uint):pointer {.importc:"malloc", header: "<stdlib.h>".}
|
||||||
|
proc c_free(p: pointer) {.importc:"free", header: "<stdlib.h>".}
|
||||||
|
|
||||||
|
proc fun() =
|
||||||
|
block: # c_exp
|
||||||
|
var x = 0.3
|
||||||
|
let b = c_exp(x)
|
||||||
|
let b2 = int(b*1_000_000) # avoids floating point equality
|
||||||
|
doAssert b2 == 1349858
|
||||||
|
doAssert c_exp(0.3) == c_exp(x)
|
||||||
|
const x2 = 0.3
|
||||||
|
doAssert c_exp(x2) == c_exp(x)
|
||||||
|
|
||||||
|
block: # c_printf
|
||||||
|
c_printf("foo\n")
|
||||||
|
c_printf("foo:%d\n", 100)
|
||||||
|
c_printf("foo:%d\n", 101.cint)
|
||||||
|
c_printf("foo:%d:%d\n", 102.cint, 103.cint)
|
||||||
|
let temp = 104.cint
|
||||||
|
c_printf("foo:%d:%d:%d\n", 102.cint, 103.cint, temp)
|
||||||
|
var temp2 = 105.cint
|
||||||
|
c_printf("foo:%g:%s:%d:%d\n", 0.03, "asdf", 103.cint, temp2)
|
||||||
|
|
||||||
|
block: # c_snprintf, c_malloc, c_free
|
||||||
|
let n: uint = 50
|
||||||
|
var buffer2: pointer = 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
|
||||||
|
|
||||||
|
block: # c_printf bug
|
||||||
|
var a = 123
|
||||||
|
var a2 = a.addr
|
||||||
|
#[
|
||||||
|
bug: different behavior between CT RT in this case:
|
||||||
|
at CT, shows foo2:a=123
|
||||||
|
at RT, shows foo2:a=<address as int>
|
||||||
|
]#
|
||||||
|
if false:
|
||||||
|
c_printf("foo2:a=%d\n", a2)
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
||||||
|
|
@ -1,94 +1,28 @@
|
||||||
discard """
|
discard """
|
||||||
cmd: "nim c --experimental:compiletimeFFI $file"
|
joinable: false
|
||||||
nimout: '''
|
|
||||||
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}
|
|
||||||
hello world stderr
|
|
||||||
hi stderr
|
|
||||||
'''
|
|
||||||
output: '''
|
|
||||||
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}
|
|
||||||
hello world stderr
|
|
||||||
hi stderr
|
|
||||||
'''
|
|
||||||
disabled: "true"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# re-enable for windows once libffi can be installed in koch.nim
|
import std/[strformat,os,osproc]
|
||||||
# With win32 (not yet win64), libffi on windows works and this test passes.
|
|
||||||
|
|
||||||
when defined(linux):
|
proc main() =
|
||||||
{.passL: "-lm".} # for exp
|
const nim = getCurrentCompilerExe()
|
||||||
proc c_exp(a: float64): float64 {.importc: "exp", header: "<math.h>".}
|
const file = currentSourcePath().parentDir / "mevalffi.nim"
|
||||||
|
# strangely, --hint:cc:off was needed
|
||||||
|
let cmd = fmt"{nim} c -f --experimental:compiletimeFFI --hints:off --hint:cc:off {file}"
|
||||||
|
let (output, exitCode) = execCmdEx(cmd)
|
||||||
|
let expected = """
|
||||||
|
hello world stderr
|
||||||
|
hi stderr
|
||||||
|
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}
|
||||||
|
"""
|
||||||
|
doAssert output == expected, output
|
||||||
|
doAssert exitCode == 0
|
||||||
|
|
||||||
proc c_printf(frmt: cstring): cint {.importc: "printf", header: "<stdio.h>", varargs, discardable.}
|
when defined(nimHasLibFFIEnabled):
|
||||||
|
main()
|
||||||
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_malloc(size:uint):pointer {.importc:"malloc", header: "<stdlib.h>".}
|
|
||||||
proc c_free(p: pointer) {.importc:"free", header: "<stdlib.h>".}
|
|
||||||
|
|
||||||
proc fun() =
|
|
||||||
block: # c_exp
|
|
||||||
var x = 0.3
|
|
||||||
let b = c_exp(x)
|
|
||||||
let b2 = int(b*1_000_000) # avoids floating point equality
|
|
||||||
doAssert b2 == 1349858
|
|
||||||
doAssert c_exp(0.3) == c_exp(x)
|
|
||||||
const x2 = 0.3
|
|
||||||
doAssert c_exp(x2) == c_exp(x)
|
|
||||||
|
|
||||||
block: # c_printf
|
|
||||||
c_printf("foo\n")
|
|
||||||
c_printf("foo:%d\n", 100)
|
|
||||||
c_printf("foo:%d\n", 101.cint)
|
|
||||||
c_printf("foo:%d:%d\n", 102.cint, 103.cint)
|
|
||||||
let temp = 104.cint
|
|
||||||
c_printf("foo:%d:%d:%d\n", 102.cint, 103.cint, temp)
|
|
||||||
var temp2 = 105.cint
|
|
||||||
c_printf("foo:%g:%s:%d:%d\n", 0.03, "asdf", 103.cint, temp2)
|
|
||||||
|
|
||||||
block: # c_snprintf, c_malloc, c_free
|
|
||||||
let n: uint = 50
|
|
||||||
var buffer2: pointer = c_malloc(n)
|
|
||||||
var s: cstring = "foobar"
|
|
||||||
var age: cint = 25
|
|
||||||
let j = 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
|
|
||||||
|
|
||||||
block: # c_printf bug
|
|
||||||
var a = 123
|
|
||||||
var a2 = a.addr
|
|
||||||
#[
|
|
||||||
bug: different behavior between CT RT in this case:
|
|
||||||
at CT, shows foo2:a=123
|
|
||||||
at RT, shows foo2:a=<address as int>
|
|
||||||
]#
|
|
||||||
if false:
|
|
||||||
c_printf("foo2:a=%d\n", a2)
|
|
||||||
|
|
||||||
|
|
||||||
static:
|
|
||||||
fun()
|
|
||||||
fun()
|
|
||||||
|
|
||||||
when true:
|
|
||||||
import system/ansi_c
|
|
||||||
proc fun2()=
|
|
||||||
c_fprintf(cstderr, "hello world stderr\n")
|
|
||||||
write(stderr, "hi stderr\n")
|
|
||||||
static: fun2()
|
|
||||||
fun2()
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue