Exporting Chapel as a LibraryΒΆ

Note

This page discusses the implementation of libraries, which are still under development. The idea is to allow components to be developed in Chapel and linked with other programs and languages. It is currently fragile and difficult to work with.

Normally, Chapel assumes that you are building a main program and produces a main routine whether one is explicitly coded or not. When the --library flag is provided on the command line, it tells the Chapel compiler to produce a library instead. The user can further specify (through the --static and --dynamic flags) which type of library to produce. If neither --static nor --dynamic is specified, a platform-dependent default library type is produced.

Some platforms support linking against both static and dynamic versions of the same library. On those platforms, the --static or --dynamic flag can be used to select which type of library (and thus which kind of linking) is performed by default. Library files which are named explicitly on the chpl command line take precedence over any found through object library paths (-L). Where there is a conflict, the last library specified takes precedence.

When creating a library file from Chapel code, only those symbols with export attached to them will be available from outside the library. For example, if one defines a Chapel file foo.chpl like this:

// This function will be available to the library user
export proc bar(): int {
  // Does something
  ...
}

// As will this one
export proc baz(int x) {
  // Does something different
  ...
}

// but this function will not be
proc gloop() {
  // Does something else
  ...
}

When using a Chapel library file in C code, a fairly exact incantation is required. First, a header file must be created for the library. This does not happen through use of the Chapel --library flag during compilation! If during compilation of the library the --savec <dir> flag is also used, the C definitions for the exported functions should be visible in a C file under dir of the same name as the library Chapel file. A declaration version of these definitions should go into a .h file. For instance, if one compiled foo.chpl like this:

chpl --library --savec cDir --static -o libfoo foo.chpl

then under cDir/foo.c one might see something resembling:

int64_t bar(void) {
  ...
}

void baz(int64_t x) {
  ...
}

from which one would create a .h file:

int64_t bar(void);
void baz(int64_t x);

It may be necessary to #include some Chapel headers, such as chpl-string.h, depending on the types used in your Chapel library.

Next, if compiling dynamically, update the $LD_LIBRARY_PATH environment variable to include the directory where the new library file lives and the directory where the Chapel build lives. The latter can be found by looking at the output of a $CHPL_HOME/util/printchplenv call and finding the appropriate directory under $CHPL_HOME/lib; the directory name can be found by running $CHPL_HOME/util/printchplenv --runtime --path.

# Replace $PWD with the appropriate path to your library file if it isn't
# in the current directory
# Replace libDir with the directory we just found.
export LD_LIBRARY_PATH=$PWD:$CHPL_HOME/lib/`$CHPL_HOME/util/printchplenv --runtime --path`:$LD_LIBRARY_PATH

When using a Chapel library from C, one must first initialize the Chapel runtime and standard modules. This is done by the addition of a couple of extern declarations, calling the function chpl_library_init() before the Chapel library function calls and by calling chpl_library_finalize() after all the Chapel library function calls are finished. For example:

#include "foo.h"

extern void chpl_library_init(int argc, char* argv[]);
extern void chpl_library_finalize(void);

int main(int argc, char* argv[]) {
    chpl_library_init(argc, argv);

    baz(7); // Call into a library function

    chpl_library_finalize();

    return 0;
}

Finally, compilation of the C program involves some additional command line includes and links. The easiest way to get the right combination is by using the compileline --compile and compileline --libraries tools we provide. The compilation command would then look like this (replacing myprog.c with the name of your C program):

`$CHPL_HOME/util/config/compileline --compile` myprog.c -L. -lfoo `$CHPL_HOME/util/config/compileline --libraries`

Note that compileline --compile-c++ is also available. It requests a compilation command able to compile a C++ program.

Chapel library files cannot be used from Chapel code. The library files must include the chapel runtime and standard modules for use in a non-Chapel program and when the library is linked to a Chapel program this leads to multiple definitions of these functions.

As mentioned above, this feature is not very sturdy. Please refer to Reporting Chapel Issues if any problems are encountered.