
#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