pure-c / purec

C backend for PureScript
234 stars 8 forks source link

ffi and link problems #57

Closed LATBauerdick closed 5 years ago

LATBauerdick commented 5 years ago

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_putStrLn1_ in: .purec-work/main/Data.Puts.o .purec-work/main/Example1.o duplicate symbol _Data_Puts_putStrLn2 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_PutsputStrLn$ 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

felixSchl commented 5 years ago

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:

LATBauerdick commented 5 years ago

of course, thanks, I could/should have known that...