The current spec contains no examples of how you would specify a library archive. Which of the following are legal: foreign import ccall "[Storable_cbits.o]" readCharOffPtr :: ... foreign import ccall "[libc.so]" malloc :: ... foreign import ccall "[libc.a]" malloc :: ... foreign import ccall "[-lc]" malloc :: ... foreign import ccall "[-L/usr/lib -lc]" malloc :: ... I'm assuming that any relative filenames should be interpreted as being relative to the directory containing the .hs file. My current interpretation is that anything legal on a link line is ok (so all the above are kosher) but it may be sensible to limit it to just the first 3 forms. I'd like the spec to say what's legal and give at least one example. -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/
Alastair Reid <reid@cs.utah.edu> wrote,
The current spec contains no examples of how you would specify a library archive. Which of the following are legal:
foreign import ccall "[Storable_cbits.o]" readCharOffPtr :: ... foreign import ccall "[libc.so]" malloc :: ... foreign import ccall "[libc.a]" malloc :: ... foreign import ccall "[-lc]" malloc :: ... foreign import ccall "[-L/usr/lib -lc]" malloc :: ...
I'm assuming that any relative filenames should be interpreted as being relative to the directory containing the .hs file.
My current interpretation is that anything legal on a link line is ok (so all the above are kosher) but it may be sensible to limit it to just the first 3 forms.
I'd like the spec to say what's legal and give at least one example.
The actual motivation for inclusion of the library specification was that SPJ pointed out that it would otherwise be difficult to generate code for .NET (where apparently you need to give the name of the dll or so when calling a non-.NET function in the IL). In that case, it'll probably be something like foreign import ccall "[libc]" malloc :: ... Without this requirement for .NET, we would have omitted the library specification altogether as something which is much too system dependent. Hence, personally, I would tend to restrict the string in square brackets to the name of a library without a suffix. The suffix and other link options would, then, need to be supplied by the Haskell system or via command line options to the compiler and/or linker. I favour this, as it seems to be the most likely scenario that makes a single foreign import declaration work on more than one platform. (I would also give the Haskell system the option of ignoring the library spec altogether.) I am not sure what others think about this. Manuel
Hence, personally, I would tend to restrict the string in square brackets to the name of a library without a suffix.
So you're proposing that it be a single library and not a list of libraries and especially not a bunch of search directories and files? This works for .h files because is is easy to merge multiple .h files into one by creating a super-file which #includes the others. But this relies on having multi-include protection in the individual (leaf-node) include files. Can we do this for libraries too? I think it would need multi-include protections and at the moment I'm struggling to see how to do it. Hmmmm, what is the story if two files independently link against the same .o file or .so file? Do you get one copy of the file or two? I guess you have to get just one copy - which means that dynamic linking has to be in a single namespace which has some consequences for Hugs and GreenCard (which currently uses a separate namespace per module).
The suffix and other link options would, then, need to be supplied by the Haskell system or via command line options to the compiler and/or linker. I favour this, as it seems to be the most likely scenario that makes a single foreign import declaration work on more than one platform.
This makes sense.
(I would also give the Haskell system the option of ignoring the library spec altogether.)
Hmmm, Hugs is already ignoring the header file because it doesn't seem to provide anything except headaches[details at end]. If I can ignore the lib spec too then things get much simpler but not necessarily better. The package system provided by GHC and NHC provides an alternate place where libraries could be specified. Can someone familiar with packages and with Hugs comment on whether they'd be able to replace the ffi's library spec and would make sense for typical Hugs usage. And would that meet SimonPJ's need too? -- Alastair Reid reid@cs.utah.edu http://www.cs.utah.edu/~reid/ ps The reason I'm wary of using the user-supplied header file is not cpp/C-namespace cleanliness (see recent GHC bug report) but the way that adding or removing a function prototype changes the semantics. The new Hugs ffi implementation ignores the header file and generates its own prototypes. This makes the following forms equivalent (which I consider a good thing): foreign import ccall "static" foo :: <whatever> and foo :: <whatever> foo = foo_dyn foo_addr foreign import ccall "& foo" foo_addr :: FunPtr <whatever> foreign import ccall "dynamic" foo_dyn :: (FunPtr <whatever>) -> <whatever> I think the useful and important job of checking that the ffi specs match the header file or, better, the code as compiled is best done by a separate tool.
participants (2)
-
Alastair Reid -
Manuel M. T. Chakravarty