ffi and link problems
LATBauerdick opened this issue · 2 comments
defining ffi in the sub tree leads to link error in example code:
This came up when I tried to port existing purescript code to pure-c and I got link errors that I don't know how to deal with. I reduced the issue to something easily reproduceable by slightly modifying the example1 (I may be missing something trivial here, in which case I apologize):
I move the definition of foreign import putStrLn :: String -> Effect Unit
to a separate module, say, src/Data/Puts.purs
:
module Data.Puts (putStrLn) where
import Prelude (Unit)
import Effect (Effect)
foreign import putStrLn :: String -> Effect Unit
which I define as expected in src/Data/Puts.h
#ifndef Data_Puts_H
#define Data_Puts_H
#include <purescript.h>
PURS_FFI_FUNC_2(Data_Puts_putStrLn, s, _, {
printf("%s\n", purs_any_get_string(s));
return NULL;
});
#endif // Data_Puts_H
and call from src/Main
:
...
import Data.Puts (putStrLn) as DP
...
DP.putStrLn "Please enter your details:"
... etc
The result are duplicate symbol errors in the link step, as if the C code of the foreign function was pulled into Example1.o
, in addition of being defined in Data.Puts.o
. I'm sorry that I don't know how to debug the link step or the makefile, but maybe someone can look at this?
...
duplicate symbol Data_Puts_putStrLn__1 in:
.purec-work/main/Data.Puts.o
.purec-work/main/Example1.o
duplicate symbol _Data_Puts_putStrLn__2 in:
.purec-work/main/Data.Puts.o
.purec-work/main/Example1.o
duplicate symbol _Data_Puts_putStrLn__1 in:
.purec-work/main/Data.Puts.o
.purec-work/main/Example1.o
duplicate symbol Data_Puts_putStrLn$ in:
.purec-work/main/Data.Puts.o
.purec-work/main/Example1.o
ld: 5 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [.purec-work/main/.build] Error 1
make[1]: *** [_main] Error 2
make: *** [main] Error 2
The current examples lead by poor example of putting the definition into the headers. You'd usually have a header file exporting the functions using PURS_FFI_EXPORT
, and implement them in a corresponding .c file.
See here for example:
of course, thanks, I could/should have known that...