[Hackage] #757: Building shared libraries to simplify C++ wrappers
Hackage
cvs-ghc at haskell.org
Thu Nov 4 08:12:07 EDT 2010
#757: Building shared libraries to simplify C++ wrappers
------------------------------+---------------------------------------------
Reporter: jodonoghue | Owner:
Type: enhancement | Status: new
Priority: normal | Milestone:
Component: Cabal library | Version: 1.8.0.6
Severity: minor | Keywords: C++, library
Difficulty: project(> week) | Ghcversion:
Platform: |
------------------------------+---------------------------------------------
While Haskell cannot directly link with C++ code via the FFI, it is
straightforward and pretty common practice to write wrapper functions
which are callable using C conventions. These can be used from the FFI.
As an example, consider the method functions setFoo and getFoo in the
class Bar. Ignoring const correctness and general good design, this might
look something like:
{{{
class Bar {
private:
String& val;
public:
Bar() { val = ""; }
String& getFoo() { return val; }
void setFoo(const String& v) { val = v; }
}
}}}
C language wrappers would be something like:
{{{
void* "C" Bar_constructor() { return (void*) new Bar; }
char* "C" Bar_getFoo(void* ths) {
return (char *) ((Bar*) ths)->getFoo();
}
void "C" Bar_setFoo(void* ths, char* val) {
((Bar*) ths)->setFoo(String(val));
}
}}}
Cabal is quite capable of compiling this today, but a problem can arise
when the code is linked.
The issue is that most C++ code needs to be linked with the C++ standard
library, libstdc++ (in the example above, it is needed for the String
type). On Windows, the MinGW compiler provided in Haskell Platform
provides only a static version of libstdc++.
When compiling with GHC, this is not an issue, since static linking to
libstdc++ works just fine. However, when loading the library into GHCi,
loading fails because no shared version of libstdc++ exists, and fix-up
fails when attempting to load libstdc++.
The proposed solution is to extend Cabal so that C or C++ code listed in
the c-sources stanza can (optionally) be built as a shared library. The
shared library can safely be linked with a static libstdc++, which removes
the need to export this dependency to Haskell (GHC/GHCi need only link to
the shared lib).
Concretely, this could be implemented as follows:
Add a new section {{{ForeignLibrary}}}
This would need to contain the following stanzas:
'''foreign-lib-name: <name>''' This is the basename of the library (i.e.
without the 'lib' prefix on Unix, and without any extension (.a, .so,
.dll) - as this basename is cross-platform compatible.
'''foreign-lib-type: shared | static''' Indicate whether the library
should be compiled as a shared library (.dll, .so, .dylib etc) or as a
static library (.a, .lib).
'''foreign-lib-extralibs: <list of libs>''' A list of libraries with
which the foreign library must be linked. In the case where the library is
being built as '''shared''', these will not be added to the list of
libraries in the module '''extra-libraries''' stanza. Where the foreign
library is built as '''static''' these libraries need to be added to
'''extra-libraries'''
'''foreign-lib-libdirs: <list of directory paths>''' Each path gets
added to a -L<path> when compiling C/C++ code.
'''foreign-lib-includes: <list of directory paths>''' Each path gets
added to a -I<path> when compiling C/C++ code.
'''foreign-lib-generate-def: True | False''' For Windows only, if the
library is being built as a '''shared''' library, generate the
corresponding .def file detailing the exported functions.
'''cc-options''', '''ld-options''' and '''frameworks''' should function
in the same way as they do in Cabal today.
I believe that this set of changes would be sufficient to allow wrapping
of many C++ libraries without the need for significant customization of
the Cabal Simple profile.
I believe that it might also simplify porting of foreign libraries which
were originally designed for Unix systems to run on Windows, since there
would be a standard way to build C/C++ code for inclusion with Haskell
modules.
--
Ticket URL: <http://hackage.haskell.org/trac/hackage/ticket/757>
Hackage <http://haskell.org/cabal/>
Hackage: Cabal and related projects
More information about the cabal-devel
mailing list