How to add extra pramgas to procedures ?
dinau opened this issue · 1 comments
I've tried these simplified steps,
-
Make hello.c
#include <stdio.h> void sayHello(void){ printf("Hello World"); }
Make
hello.dll
gcc -shared -o hello.dll hello.c
-
hello.h
void sayHello(void);
-
test.nim
import futhark when defined(useFuthark): importc: path "." "hello.h" outputPath "helloDef.nim" else: include "helloDef.nim" sayHello()
Generate
helloDef.nim
nim c -f -c -d:useFuthark -d:futharkRebuild test.nim
-
I'd like to run only using
helloDef.nim
and hello.dll as follows;nim c -r test.nim ... ... undefined reference to `sayHello' ...
but the error occured.
-
Generated
helloDef.nim
from macros import hint when not declared(sayhello): proc sayhello*(): void {.cdecl, importc: "sayHello".} else: static : hint("Declaration of " & "sayhello" & " already exists, not redeclaring")
I'd like to add
dynlib:"hello.dll"
pargma orpragma pragma
(for flexibility)
tosayhello*
proc.
How to add extrapragmas
using Futhark directives in this case ?
There are really a couple of questions here. To start lets address the error you get. That "undefined reference to sayHello
is from the C compiler because it doesn't know that it should link against hello.dll
. This can be fixed by passing in the correct linker flags with passL
, either as a switch or as a pragma. For example on Linux (where I named the library libhello.so
) I added {.passL: "-L. -lhello".}
and the compilation went well. On Linux you also need to call it as LD_LIBRARY_PATH=. ./test
because it doesn't load dynamic libraries from the current path by default, but I believe this isn't an issue with Windows. You can also throw this switch on the compilation nim c --passL:"-L. -lhello" test
.
The only thing the dynlib
pragma does is to automatically pass these flags during compilation when the procedures are used. The way you can add these built-in pragmas to everything in the Futhark generated output is to use the {.push.}
and {.pop.}
pragmas like this:
{.push dynlib: "hello.dll".}
when defined(useFuthark):
import futhark
importc:
path "."
"hello.h"
outputPath "helloDef.nim"
else:
include "helloDef.nim"
{.pop.}
sayHello()
This essentially applies the pragma to everything between the push and the pop, and they apply to the output of the importc and the include. Unfortunately this doesn't apply to custom pragmas from macros, but you can apply those with a macro that takes a typed
input.