[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