According to Nim Backend Integration, I have the following code
type Vec3t {.exportc.} = object
x, y, z: float32
proc test_add(x, y, z: float32): Vec3t {.exportc.} =
Vec3t(x: x, y: y, z: z)
proc print_point_nim(p: Vec3t) {.exportc.} =
echo "[Nim] p.x: ", p.x
compiled with
nim c -d:release -d:danger --gc:refc --noMain --noLinking --nimcache:ncache --header:TEST.H TEST.NIM
However, when called in C there are linker errors like
/usr/bin/ld: /tmp/ccXiaS2r.o: in function `main':
LIGHT.C:(.text+0x148): undefined reference to `NimMain()'
LIGHT.C:(.text.startup+0x52): undefined reference to `test_add(float, float, float)'
/usr/bin/ld: light: hidden symbol `_Z8test_addfff' isn't defined
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
Tried with nim cpp instead with nim c and it compiles, but whenever the function is called it drops segfault.
It works on test project, but if I can't integrate it into existing C application.
Are there any specific compiler switches to overcome this?
Also, why even with the --header flag Nim still produces object files?
Shouldn't it compile only the .c sources, and then compile them in the next stage with gcc?
tried with nim cpp instead with nim c and it compiles,
I don't understand, nim c and then calling from C works for me (as it should).
but whenever the function is called it drops segfault.
You need to initialize Nim's GC by calling NimMain() in C beforehand. Unless you use a dynamic lib with --app:lib.
Also, why even with the --header flag Nim still produces object files?
It is supposed to only generate a header to include in your C file, use --compileOnly to skip object file generation. Alternatively you can generate a static lib with --app:staticlib.
+1 --compileOnly :)
@enthus1ast, you mean like
proc test_add(x, y, z: float32): Vec3t {.exportc cdecl.} =
Vec3t(x: x, y: y, z: z)
Didn't work ):
what confuses me is hidden symbol `_Z8test_addfff' isn't defined this is not some missing include library...
A bit perplexing…
My C file:
#include "ncache/test.h"
int main() {
Vec3t v;
NimMain();
v = test_add(1.0f,1.0f,1.0f);
print_point_nim(v);
return 0;
}
Build commands:
nim c --compileOnly --noMain --header:test.h --nimcache:ncache test.nim
gcc -o main -I /path/to/nim/lib main.c ncache/*.c
Tested on W10, nim 1.4.8
Doh! Found it.
It's gcc that causes the bug, not Nim, it was the filename case.
Nim generates lower case .c files, but in the project has files with upper case eg. 'TEST.C'.
So I reanamed all .c files generated from Nim to uppercase (with .C extension) and it works!