Hello,
I wanted to try to create static lib in Nim and interface with C. However I cannot get it to work even when I tried to follow https://nim-lang.github.io/Nim/backends.html#interfacing-backend-code-calling-nim .
OS: Linux, Arch: amd64, Nim 1.6.0 and 1.4.8
Nim code in libnim.nim file:
proc add_int_in_nim*(a, b: cint): cint {.exportc.} =
result = a+b
echo "Echo in Nim: ", a, " + " , b, " = ", result
proc add_float_in_nim*(a, b: cfloat): cfloat {.exportc.} =
result = a+b
echo "Echo in Nim: ", a, " + " , b, " = ", result
proc add_double_in_nim*(a, b: cdouble): cdouble {.exportc.} =
result = a+b
echo "Echo in Nim: ", a, " + " , b, " = ", result
C code in main.c:
#include "libnim.h"
#include <stdio.h>
int main()
{
NimMain();
int a = 2;
int b = 3;
printf("Int: %d + %d\n", a, b);
int sum = add_int_in_nim(a, b);
printf("C printf - Nim calculated %d + %d = %d\n\n", a, b, sum);
float c = 2.0;
float d = 3.0;
printf("Float: %f + %f\n", c, d);
float sum2 = add_float_in_nim(c, d);
printf("C printf - Nim calculated %f + %f = %f\n\n", c, d, sum2);
double e = 2.0;
double f = 3.0;
printf("Double: %lf + %lf\n", e, f);
int sum3 = add_double_in_nim(e, f);
printf("C printf - Nim calculated %lf + %lf = %lf\n\n", e, f, sum3);
return 0;
}
Commands:
GCC output:
/usr/bin/ld: /tmp/cckiRwXc.o: in function `main':
main.c:(.text+0x9): undefined reference to `NimMain'
/usr/bin/ld: main.c:(.text+0x42): undefined reference to `add_int_in_nim'
/usr/bin/ld: main.c:(.text+0xc6): undefined reference to `add_float_in_nim'
/usr/bin/ld: main.c:(.text+0x165): undefined reference to `add_double_in_nim'
/usr/bin/ld: m: hidden symbol `add_float_in_nim' isn't defined
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
Do you have any idea what's wrong please?
GNU linkers (both default ld and gold) requires specific order of its inputs:
gcc -o m -Inimcache main.c libnim.a
main.c has a dependency on symbols from libnim.a thus it needs to come before libnim.a in a linking invocation. In your case the linker sees only unused symbols from libnim.a and tosses it out. Only then it reads contents from main.c, sees symbols it can't resolve (libnim.a is now out of the picture) and gives you linker errors.