diff options
Diffstat (limited to 'tests/dll')
-rw-r--r-- | tests/dll/client.nim | 43 | ||||
-rw-r--r-- | tests/dll/client.nim.cfg | 1 | ||||
-rw-r--r-- | tests/dll/nimhcr_0.nim | 4 | ||||
-rw-r--r-- | tests/dll/nimhcr_0_1.nim | 14 | ||||
-rw-r--r-- | tests/dll/nimhcr_0_2.nim | 18 | ||||
-rw-r--r-- | tests/dll/nimhcr_0_3.nim | 19 | ||||
-rw-r--r-- | tests/dll/nimhcr_0_4.nim | 19 | ||||
-rw-r--r-- | tests/dll/nimhcr_0_5.nim | 2 | ||||
-rw-r--r-- | tests/dll/nimhcr_0_6.nim | 4 | ||||
-rw-r--r-- | tests/dll/nimhcr_1.nim | 0 | ||||
-rw-r--r-- | tests/dll/nimhcr_1_1.nim | 51 | ||||
-rw-r--r-- | tests/dll/nimhcr_1_2.nim | 4 | ||||
-rw-r--r-- | tests/dll/nimhcr_1_3.nim | 0 | ||||
-rw-r--r-- | tests/dll/nimhcr_2.nim | 0 | ||||
-rw-r--r-- | tests/dll/nimhcr_2_1.nim | 32 | ||||
-rw-r--r-- | tests/dll/nimhcr_2_2.nim | 7 | ||||
-rw-r--r-- | tests/dll/nimhcr_2_3.nim | 0 | ||||
-rw-r--r-- | tests/dll/nimhcr_basic.nim | 8 | ||||
-rw-r--r-- | tests/dll/nimhcr_integration.nim | 170 | ||||
-rw-r--r-- | tests/dll/nimhcr_unit.nim | 149 | ||||
-rw-r--r-- | tests/dll/nimhcr_unit.nim.cfg | 2 | ||||
-rw-r--r-- | tests/dll/server.nim | 27 | ||||
-rw-r--r-- | tests/dll/server.nim.cfg | 2 | ||||
-rw-r--r-- | tests/dll/test_nimhcr_integration.bat | 10 | ||||
-rwxr-xr-x | tests/dll/test_nimhcr_integration.sh | 17 | ||||
-rw-r--r-- | tests/dll/visibility.nim | 43 |
26 files changed, 646 insertions, 0 deletions
diff --git a/tests/dll/client.nim b/tests/dll/client.nim new file mode 100644 index 000000000..62697569f --- /dev/null +++ b/tests/dll/client.nim @@ -0,0 +1,43 @@ +discard """ + cmd: "nim $target --debuginfo --hints:on --define:useNimRtl $options $file" +""" + +type + TNodeKind = enum nkLit, nkSub, nkAdd, nkDiv, nkMul + TNode = object + case k: TNodeKind + of nkLit: x: int + else: a, b: ref TNode + + PNode = ref TNode + + +when defined(windows): + const dllname = "server.dll" +elif defined(macosx): + const dllname = "libserver.dylib" +else: + const dllname = "libserver.so" + +proc newLit(x: int): PNode {.importc: "newLit", dynlib: dllname.} +proc newOp(k: TNodeKind, a, b: PNode): PNode {. + importc: "newOp", dynlib: dllname.} +proc buildTree(x: int): PNode {.importc: "buildTree", dynlib: dllname.} + +proc eval(n: PNode): int = + case n.k + of nkLit: result = n.x + of nkSub: result = eval(n.a) - eval(n.b) + of nkAdd: result = eval(n.a) + eval(n.b) + of nkDiv: result = eval(n.a) div eval(n.b) + of nkMul: result = eval(n.a) * eval(n.b) + +# Test the GC: +for i in 0..100_000: + discard eval(buildTree(2)) + +# bug https://forum.nim-lang.org/t/8176; Error: ambiguous identifier: 'nimrtl' +import std/strutils +doAssert join(@[1, 2]) == "12" +doAssert join(@[1.5, 2.5]) == "1.52.5" +doAssert join(@["a", "bc"]) == "abc" diff --git a/tests/dll/client.nim.cfg b/tests/dll/client.nim.cfg new file mode 100644 index 000000000..0e044a829 --- /dev/null +++ b/tests/dll/client.nim.cfg @@ -0,0 +1 @@ +--define:useNimRtl diff --git a/tests/dll/nimhcr_0.nim b/tests/dll/nimhcr_0.nim new file mode 100644 index 000000000..fe0b29a36 --- /dev/null +++ b/tests/dll/nimhcr_0.nim @@ -0,0 +1,4 @@ + +let g_0 = 1000 # new value! but also a "new" global :) + +proc getInt*(): int = return g_0 diff --git a/tests/dll/nimhcr_0_1.nim b/tests/dll/nimhcr_0_1.nim new file mode 100644 index 000000000..620050be3 --- /dev/null +++ b/tests/dll/nimhcr_0_1.nim @@ -0,0 +1,14 @@ + +import hotcodereloading + +let g_0 = 42 # lets start with the ultimate answer + +proc getInt*(): int = return g_0 + +programResult = 0 # should be accessible + +beforeCodeReload: + echo " 0: before" +afterCodeReload: + echo " 0: after" + \ No newline at end of file diff --git a/tests/dll/nimhcr_0_2.nim b/tests/dll/nimhcr_0_2.nim new file mode 100644 index 000000000..9ce228dc1 --- /dev/null +++ b/tests/dll/nimhcr_0_2.nim @@ -0,0 +1,18 @@ + +import hotcodereloading + +import nimhcr_1 # new import! + +# global scope for this module was executed when loading the program +# with a previous version which didn't contain this print statement +echo " 0: I SHOULDN'T BE PRINTED!" + +var g_0 = 0 # changed value but won't take effect + +proc getInt*(): int = return g_0 + g_1 + f_1() + +beforeCodeReload: + echo " 0: before - improved!" # changed handlers! +afterCodeReload: + echo " 0: after - improved!" + g_0 = 100 # we cannot change it in its initialization but we can in the 'after' handler! diff --git a/tests/dll/nimhcr_0_3.nim b/tests/dll/nimhcr_0_3.nim new file mode 100644 index 000000000..183424e11 --- /dev/null +++ b/tests/dll/nimhcr_0_3.nim @@ -0,0 +1,19 @@ + +import hotcodereloading + +import nimhcr_1 +import nimhcr_2 # a new and different import! + +proc makeCounter*(): auto = + return iterator: int {.closure.} = + for i in countup(0, 10, 1): + yield i + +let c = makeCounter() + +afterCodeReload: + echo " 0: after - closure iterator: ", c() + echo " 0: after - closure iterator: ", c() + echo " 0: after - c_2 = ", c_2 + +proc getInt*(): int = return g_1 + g_2.len diff --git a/tests/dll/nimhcr_0_4.nim b/tests/dll/nimhcr_0_4.nim new file mode 100644 index 000000000..4471782a7 --- /dev/null +++ b/tests/dll/nimhcr_0_4.nim @@ -0,0 +1,19 @@ + +import hotcodereloading + +import nimhcr_1 # only importing 1 + +let g_0 = 1000 # new value! but also a "new" global :) + +proc getInt*(): int = return g_0 + +proc makeCounter*(): auto = + return iterator: int {.closure.} = + for i in countup(0, 10, 1): + yield i + +let c = makeCounter() + +afterCodeReload: + echo " 0: after - closure iterator! after reload! does it remember? :", c() + echo " 0: after - closure iterator! after reload! does it remember? :", c() diff --git a/tests/dll/nimhcr_0_5.nim b/tests/dll/nimhcr_0_5.nim new file mode 100644 index 000000000..aff4014ca --- /dev/null +++ b/tests/dll/nimhcr_0_5.nim @@ -0,0 +1,2 @@ + +proc getInt*(): int = return 42 # back to the answer... diff --git a/tests/dll/nimhcr_0_6.nim b/tests/dll/nimhcr_0_6.nim new file mode 100644 index 000000000..fe0b29a36 --- /dev/null +++ b/tests/dll/nimhcr_0_6.nim @@ -0,0 +1,4 @@ + +let g_0 = 1000 # new value! but also a "new" global :) + +proc getInt*(): int = return g_0 diff --git a/tests/dll/nimhcr_1.nim b/tests/dll/nimhcr_1.nim new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/dll/nimhcr_1.nim diff --git a/tests/dll/nimhcr_1_1.nim b/tests/dll/nimhcr_1_1.nim new file mode 100644 index 000000000..299c52baa --- /dev/null +++ b/tests/dll/nimhcr_1_1.nim @@ -0,0 +1,51 @@ + +echo " 1: print me once!" + +import hotcodereloading + +let g_1* = 8 # devilish! + +proc f_1*(): int = + var a {.global.} = 1 + a.inc + return a + + +# all these constructs should compile +let some_glob_1 = 1 +echo " 1: ", some_glob_1 +if true: + let some_glob_2 = 2 + echo " 1: ", some_glob_2 + if true: + let some_glob_3 = 3 + echo " 1: ", some_glob_3 +block: + let some_glob_4 = 4 + proc inBlock(num: int) = + echo " 1: ", num + inBlock(some_glob_4) +var counter = 3 +while counter > 0: + let some_glob_5 = 5 + echo " 1: ", some_glob_5 + counter.dec + +type + Type1 = object + a: int + b: int +var t = Type1(a: 42, b: 11) +echo " 1: Type1.a:", t.a + +type + obj = ref object + dat: int + str: string + +proc foo(): (int, obj) = (1, obj(dat: 3, str: "bar")) + +let (aa, bb) = foo() +afterCodeReload: + echo aa + echo bb.str diff --git a/tests/dll/nimhcr_1_2.nim b/tests/dll/nimhcr_1_2.nim new file mode 100644 index 000000000..caf772450 --- /dev/null +++ b/tests/dll/nimhcr_1_2.nim @@ -0,0 +1,4 @@ + +import nimhcr_2 + +proc f_1*(): int = return f_2() diff --git a/tests/dll/nimhcr_1_3.nim b/tests/dll/nimhcr_1_3.nim new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/dll/nimhcr_1_3.nim diff --git a/tests/dll/nimhcr_2.nim b/tests/dll/nimhcr_2.nim new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/dll/nimhcr_2.nim diff --git a/tests/dll/nimhcr_2_1.nim b/tests/dll/nimhcr_2_1.nim new file mode 100644 index 000000000..705ed6d5a --- /dev/null +++ b/tests/dll/nimhcr_2_1.nim @@ -0,0 +1,32 @@ + +import hotcodereloading + +type + Type2 = ref object of RootObj + data*: int + +let g_2* = @[Type2(data: 2), Type2(data: 3)][1..^1] # should have a length of 1 + +const c_2* = [1, 2, 3] # testing that a complext const object is properly exported + +var a: tuple[str: string, i: int] +a.str = " 2: random string" +echo a.str + +beforeCodeReload: + echo " 2: before!" + +# testing a construct of 2 functions in the same module which reference each other +# https://github.com/nim-lang/Nim/issues/11608 +proc rec_1(depth: int) +proc rec_2(depth: int) = + rec_1(depth + 1) +proc rec_1(depth: int) = + if depth < 3: + rec_2(depth) + else: + echo("max mutual recursion reached!") + +# https://github.com/nim-lang/Nim/issues/11996 +let rec_2_func_ref = rec_2 +rec_2_func_ref(0) diff --git a/tests/dll/nimhcr_2_2.nim b/tests/dll/nimhcr_2_2.nim new file mode 100644 index 000000000..04ab2d3bb --- /dev/null +++ b/tests/dll/nimhcr_2_2.nim @@ -0,0 +1,7 @@ + +import hotcodereloading + +proc f_2*(): int = return 1 + +afterCodeReload: + echo " 2: after!" diff --git a/tests/dll/nimhcr_2_3.nim b/tests/dll/nimhcr_2_3.nim new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/dll/nimhcr_2_3.nim diff --git a/tests/dll/nimhcr_basic.nim b/tests/dll/nimhcr_basic.nim new file mode 100644 index 000000000..2e1f39ae0 --- /dev/null +++ b/tests/dll/nimhcr_basic.nim @@ -0,0 +1,8 @@ +discard """ + output: ''' +Hello world +''' +""" +# for now orc only tests successful compilation + +echo "Hello world" diff --git a/tests/dll/nimhcr_integration.nim b/tests/dll/nimhcr_integration.nim new file mode 100644 index 000000000..ac34f1f85 --- /dev/null +++ b/tests/dll/nimhcr_integration.nim @@ -0,0 +1,170 @@ +discard """ + disabled: "true" + output: ''' +main: HELLO! +main: hasAnyModuleChanged? true +main: before + 0: after +main: after + The answer is: 1000 +main: hasAnyModuleChanged? false + The answer is: 1000 +main: hasAnyModuleChanged? true + 0: before +main: before + 1: print me once! + 1: 1 + 1: 2 + 1: 3 + 1: 4 + 1: 5 + 1: 5 + 1: 5 + 1: Type1.a:42 +1 +bar + 0: after - improved! +main: after + The answer is: 110 +main: hasAnyModuleChanged? true + 0: before - improved! +main: before + 2: random string +max mutual recursion reached! +1 +bar + 0: after - closure iterator: 0 + 0: after - closure iterator: 1 + 0: after - c_2 = [1, 2, 3] +main: after + The answer is: 9 +main: hasAnyModuleChanged? true + 2: before! +main: before + 2: after! + 0: after - closure iterator! after reload! does it remember? :2 + 0: after - closure iterator! after reload! does it remember? :3 +main: after + The answer is: 1000 +main: hasAnyModuleChanged? true +main: before +main: after + The answer is: 42 +done +''' +""" + +#[ +xxx disabled: "openbsd" because it would otherwise give: +/home/build/Nim/lib/nimhcr.nim(532) hcrInit +/home/build/Nim/lib/nimhcr.nim(503) initModules +/home/build/Nim/lib/nimhcr.nim(463) initPointerData +/home/build/Nim/lib/nimhcr.nim(346) hcrRegisterProc +/home/build/Nim/lib/pure/reservedmem.nim(223) setLen +/home/build/Nim/lib/pure/reservedmem.nim(97) setLen +/home/build/Nim/lib/pure/includes/oserr.nim(94) raiseOSError +Error: unhandled exception: Not supported [OSError] + +After instrumenting code, the stacktrace actually points to the call to `check mprotect` +]# + +## This is perhaps the most complex test in the nim test suite - calling the +## compiler on the file itself with the same set or arguments and reloading +## parts of the program at runtime! In the same folder there are a few modules +## with names such as `nimhcr_<number>.nim`. Each of them has a few versions which +## are in the format of `nimhcr_<number>_<version>.nim`. The below code uses the +## `update` proc to say which of the modules should bump its version (and that +## is done by copying `nimhcr_<number>_<version>.nim` onto `nimhcr_<number>.nim`). +## The files should refer to each other (when importing) without the versions. +## A few files can be updated by calling `update` for each of their indexes +## and after that with a single call to `compileReloadExecute` the new version +## of the program will be compiled, reloaded, and the only thing the main module +## calls from `nimhcr_0.nim` (the procedure `getInt` proc) is called for a result. +## +## This test is expected to be executed with arguments - the full nim compiler +## command used for building it - so it can rebuild iself the same way - example: +## +## compiling: +## nim c --hotCodeReloading:on --nimCache:<folder> <this_file>.nim +## executing: +## <this_file>.exe nim c --hotCodeReloading:on --nimCache:<folder> <this_file>.nim + +import os, osproc, strutils, hotcodereloading + +import nimhcr_0 # getInt() - the only thing we continually call from the main module + +proc compileReloadExecute() = + # Remove the `--forceBuild` option - is there in the first place because: + # - when `koch test` is ran for the first time the nimcache is empty + # - when each of the variants are built (debug, release after that, different GCs) + # the main executable that gets built into the appropriate nimcache folder + # gets copied to the originally intended destination and is executed + # (this behaviour is only when the --hotCodeReloading option is used). + # - when `koch test` is ran again and the nimcache is full the executable files + # in the nimcache folder aren't relinked and therefore aren't copied to the + # originally intended destination - so when the binary at the intended + # destination is executed - it is actually a remnant from a previous execution. + # That is a problem because it points to shared objects to load from its own + # nimcache folder - the one used for building it - a previous run! And when + # this test changes other modules it references but the main module (this file) + # remains intact - the binary isn't replaced. `--forceBuild` fixes this but has + # to be applied only for the main build - the one done from koch, but when this + # binary triggers rebuilding itself here it shouldn't rebuild the main module - + # that would lead to replacing the main binary executable which is running! + let cmd = commandLineParams()[0..^1].join(" ").replace(" --forceBuild") + doAssert cmd.len > 0 + let (stdout, exitcode) = execCmdEx(cmd) + if exitcode != 0: + echo "COMPILATION ERROR!" + echo "COMMAND: ", cmd + echo "STDOUT: ", stdout + quit 1 + echo "main: hasAnyModuleChanged? ", hasAnyModuleChanged() + performCodeReload() + echo " The answer is: ", getInt() + +# there are 3 files and all of them start from their 1st version +var vers = [1, 1, 1] +proc update(file: int) = + proc getfile(mid: string): string = + let (path, _, _) = splitFile(currentSourcePath()) + return path & "/nimhcr_" & mid & ".nim" + copyFile(getfile($file & "_" & $vers[file]), getfile($file)) + inc vers[file] + +beforeCodeReload: + echo "main: before" + +afterCodeReload: + echo "main: after" + +echo "main: HELLO!" + +update 0 +compileReloadExecute() # versions are: 1 - - + +compileReloadExecute() # no change + +update 0 +update 1 +compileReloadExecute() # versions are: 2 1 - + +update 0 +update 2 +compileReloadExecute() # versions are: 3 1 1 + +update 0 +update 1 +update 2 +compileReloadExecute() # versions are: 4 2 2 + +update 0 +compileReloadExecute() # versions are: 5 2 2 + +# final update so there are no git modifications left after everything +# (the last versions are like the first files without a version suffix) +update 0 +update 1 +update 2 + +echo "done" \ No newline at end of file diff --git a/tests/dll/nimhcr_unit.nim b/tests/dll/nimhcr_unit.nim new file mode 100644 index 000000000..249f3f9f1 --- /dev/null +++ b/tests/dll/nimhcr_unit.nim @@ -0,0 +1,149 @@ +discard """ +disabled: "openbsd" +disabled: "netbsd" +output: ''' +fastcall_proc implementation #1 10 +11 +fastcall_proc implementation #2 20 +22 +fastcall_proc implementation #2 20 +22 +fastcall_proc implementation #3 30 +33 +fastcall_proc implementation #3 30 +33 +fastcall_proc implementation #3 30 +33 +fastcall_proc implementation #3 40 +43 +cdecl_proc implementation #1 10 +11 +cdecl_proc implementation #2 20 +22 +cdecl_proc implementation #2 20 +22 +cdecl_proc implementation #3 30 +33 +cdecl_proc implementation #3 30 +33 +cdecl_proc implementation #3 30 +33 +cdecl_proc implementation #3 40 +43 +stdcall_proc implementation #1 10 +11 +stdcall_proc implementation #2 20 +22 +stdcall_proc implementation #2 20 +22 +stdcall_proc implementation #3 30 +33 +stdcall_proc implementation #3 30 +33 +stdcall_proc implementation #3 30 +33 +stdcall_proc implementation #3 40 +43 +noconv_proc implementation #1 10 +11 +noconv_proc implementation #2 20 +22 +noconv_proc implementation #2 20 +22 +noconv_proc implementation #3 30 +33 +noconv_proc implementation #3 30 +33 +noconv_proc implementation #3 30 +33 +noconv_proc implementation #3 40 +43 +inline_proc implementation #1 10 +11 +inline_proc implementation #2 20 +22 +inline_proc implementation #2 20 +22 +inline_proc implementation #3 30 +33 +inline_proc implementation #3 30 +33 +inline_proc implementation #3 30 +33 +inline_proc implementation #3 40 +43 +''' +""" + +import macros + +macro carryOutTests(callingConv: untyped): untyped = + let + procName = $callingConv & "_proc" + globalName = $callingConv & "_global" + callingConv = callingConv + p1 = ident(procName & "1") + p2 = ident(procName & "2") + p3 = ident(procName & "3") + g1 = ident(globalName & "1") + g2 = ident(globalName & "2") + + result = quote do: + var `g1`: pointer = nil + if hcrRegisterGlobal("dummy_module", `globalName`, sizeof(int), nil, addr `g1`): + cast[ptr int](`g1`)[] = 10 + + var `g2`: pointer = nil + if hcrRegisterGlobal("dummy_module", `globalName`, sizeof(int), nil, addr `g2`): + cast[ptr int](`g2`)[] = 20 + + doAssert `g1` == `g2` and cast[ptr int](`g1`)[] == 10 + + type + F = proc (x: int): int {.placeholder.} + + proc `p1`(x: int): int {.placeholder.}= + echo `procName`, " implementation #1 ", x + return x + 1 + + let fp1 = cast[F](hcrRegisterProc("dummy_module", `procName`, cast[pointer](`p1`))) + echo fp1(10) + + proc `p2`(x: int): int {.placeholder.} = + echo `procName`, " implementation #2 ", x + return x + 2 + + let fp2 = cast[F](hcrRegisterProc("dummy_module", `procName`, cast[pointer](`p2`))) + echo fp1(20) + echo fp2(20) + + proc `p3`(x: int): int {.placeholder.} = + echo `procName`, " implementation #3 ", x + return x + 3 + + let fp3 = cast[F](hcrRegisterProc("dummy_module", `procName`, cast[pointer](`p3`))) + echo fp1(30) + echo fp2(30) + echo fp3(30) + + let fp4 = cast[F](hcrGetProc("dummy_module", `procName`)) + echo fp4(40) + + proc replacePlaceholderPragmas(n: NimNode) = + if n.kind == nnkPragma: + n[0] = callingConv + else: + for i in 0 ..< n.len: + replacePlaceholderPragmas n[i] + + replacePlaceholderPragmas result + # echo result.treeRepr + +hcrAddModule("dummy_module") + +carryOutTests fastcall +carryOutTests cdecl +carryOutTests stdcall +carryOutTests noconv +carryOutTests inline + diff --git a/tests/dll/nimhcr_unit.nim.cfg b/tests/dll/nimhcr_unit.nim.cfg new file mode 100644 index 000000000..b13c310d9 --- /dev/null +++ b/tests/dll/nimhcr_unit.nim.cfg @@ -0,0 +1,2 @@ +-d:useNimRtl +-d:testNimHcr diff --git a/tests/dll/server.nim b/tests/dll/server.nim new file mode 100644 index 000000000..dd4606298 --- /dev/null +++ b/tests/dll/server.nim @@ -0,0 +1,27 @@ +discard """ +action: compile + cmd: "nim $target --debuginfo --hints:on --define:useNimRtl --app:lib $options $file" +batchable: false +""" + +type + TNodeKind = enum nkLit, nkSub, nkAdd, nkDiv, nkMul + TNode = object + case k: TNodeKind + of nkLit: x: int + else: a, b: ref TNode + + PNode = ref TNode + +proc newLit(x: int): PNode {.exportc: "newLit", dynlib.} = + result = PNode(k: nkLit, x: x) + +proc newOp(k: TNodeKind, a, b: PNode): PNode {.exportc: "newOp", dynlib.} = + assert a != nil + assert b != nil + result = PNode(k: nkSub, a: a, b: b) + # now overwrite with the real value: + result.k = k + +proc buildTree(x: int): PNode {.exportc: "buildTree", dynlib.} = + result = newOp(nkMul, newOp(nkAdd, newLit(x), newLit(x)), newLit(x)) diff --git a/tests/dll/server.nim.cfg b/tests/dll/server.nim.cfg new file mode 100644 index 000000000..02393ba8b --- /dev/null +++ b/tests/dll/server.nim.cfg @@ -0,0 +1,2 @@ +--define:useNimRtl +--app:lib diff --git a/tests/dll/test_nimhcr_integration.bat b/tests/dll/test_nimhcr_integration.bat new file mode 100644 index 000000000..66e6beac4 --- /dev/null +++ b/tests/dll/test_nimhcr_integration.bat @@ -0,0 +1,10 @@ +set NIM=nim +set NIM_FLAGS=-d:debug + +%NIM% c --outdir:"." %NIM_FLAGS% ../../lib/nimrtl.nim +%NIM% c --outdir:"." %NIM_FLAGS% ../../lib/nimhcr.nim + +set HCR_FLAGS=--forceBuild --hotCodeReloading:on --nimcache:nimcache %NIM_FLAGS% + +%NIM% %HCR_FLAGS% c nimhcr_integration.nim +nimhcr_integration %NIM% %HCR_FLAGS% c nimhcr_integration.nim diff --git a/tests/dll/test_nimhcr_integration.sh b/tests/dll/test_nimhcr_integration.sh new file mode 100755 index 000000000..a2e2d0483 --- /dev/null +++ b/tests/dll/test_nimhcr_integration.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -e + +rm -rf nimcache + +NIM_FLAGS=${*:- -d:debug} +NIM=nim + +$NIM c --outdir:"." $NIM_FLAGS ../../lib/nimrtl.nim +$NIM c --outdir:"." $NIM_FLAGS ../../lib/nimhcr.nim + +echo ===== Compiling HCR Integration Test ===== +HCR_FLAGS="--forceBuild --hotCodeReloading:on --nimcache:nimcache $NIM_FLAGS" +$NIM $HCR_FLAGS c nimhcr_integration.nim +export LD_LIBRARY_PATH=$(pwd):$LD_LIBRARY_PATH +./nimhcr_integration $NIM $HCR_FLAGS c nimhcr_integration.nim diff --git a/tests/dll/visibility.nim b/tests/dll/visibility.nim new file mode 100644 index 000000000..ec15dad29 --- /dev/null +++ b/tests/dll/visibility.nim @@ -0,0 +1,43 @@ +discard """ + output: "" +""" + +const LibName {.used.} = + when defined(windows): + "visibility.dll" + elif defined(macosx): + "libvisibility.dylib" + else: + "libvisibility.so" + +when compileOption("app", "lib"): + var + bar {.exportc.}: int + thr {.exportc, threadvar.}: int + proc foo() {.exportc.} = discard + + var + exported {.exportc, dynlib.}: int + exported_thr {.exportc, threadvar, dynlib.}: int + proc exported_func() {.exportc, dynlib.} = discard +elif isMainModule: + import dynlib + + let handle = loadLib(LibName) + + template check(sym: untyped) = + const s = astToStr(sym) + if handle.symAddr(s) != nil: + echo s, " is exported" + template checkE(sym: untyped) = + const s = astToStr(sym) + if handle.symAddr(s) == nil: + echo s, " is not exported" + + check foo + check bar + check thr + + checkE exported + checkE exported_thr + checkE exported_func |