This document is arranged as follows:
% gzcat babel-0.8.2.tar.gz | tar -xf -The configure script will probe your system for compilers and other required tools. Make sure your PATH environment variable includes Java, the C compiler, and the C++ compiler. We currently recommend using the GNU compilers gcc and g++. Although we are developing support for other compilers, the generation of C++ shared libraries is still somewhat platform-dependent. Future releases will more fully support other platforms and compilers. Currently, you must use GNU make to compile the Babel distribution, although we are modifying the build system to support non-GNU make programs.
% cd babel-0.8.2
% ./configure --prefix=$HOME/babel
% gmake install
If you have configuration troubles, please contact us at components@llnl.gov with a detailed description of the platform, environment, and the log file config.log from the configuration utility.
Assuming the "make install" completes successfully, the babel/ subdirectory of your home directory will contain the following:
We will write the "Hello World!" program in a directory called hello/ and place the client library in a subdirectory hello/lib/:
% mkdir helloThe first step is to write a SIDL file. Recall that SIDL is an interface definition language (IDL) that describes the calling interface for a scientific library. It is used by the Babel tools to generate glue code that hooks together different programming languages. A complete description of SIDL is beyond the scope of this introductory tutorial. Other documentation covers the SIDL grammar, Fortran 77, and C++ bindings. In addition, a sample SIDL file for the hypre library has been provided.
% cd hello
% mkdir lib
For this particular application, we will write a SIDL file that contains a class World in a package Hello. Method getMsg in class World returns a string containing the traditional computer greeting. Using your favorite editor, create a file called hello.sidl in the hello/ directory:
package Hello version 1.0 {The package statement provides a namespace for class World, which contains only one method, getMsg. The version clause identifies this as version 1.0 of the Hello package.
class World {
string getMsg();
}
}
% cd libIn this babel command, the "-sC++" flag indicates that we wish to generate server side C++ bindings. The "-R" flag indicates that the repository for other symbols (such as the base SIDL symbols) is in the directory $MYREP. The "--help" flag lists other babel command-line options. You may also refer to the command line documentation.
% $HOME/babel/bin/babel -R$MYREP -sC++ ../hello.sidl
This command will generate a large number of C and C++ header and source files. The files that begin with "Hello" correspond to our sample program. The files that begin with "SIDL" are part of the C++ interface to the SIDL run-time library. The file names that contain "IOR" or "Skel" are part of the Babel glue code. The file babel.make is a Makefile fragment that will simplify writing the Makefile necessary to compile the library. You may ignore the babel.make file if you wish. The only files that should be modified are those headers and sources that end with "Impl." Babel generates these implementation files as a starting point for developers. These files will contain the implementation of the Hello library.
Every implementation file contains many pairs of comment "splicer" lines such as the following:
stringAny modifications between these splicer lines will be saved between invocations of the babel tool. Any changes outside the splicer lines will be lost. Thus, it is easy to add new methods to the hello.sidl file without the loss of your modifications when babel regenerates its code.
Hello::World_impl::getMsg()
throw ()
{
// DO-NOT-DELETE splicer.begin(Hello.World.getMsg)
// insert implementation here
// DO-NOT-DELETE splicer.end(Hello.World.getMsg)
}
For our hello application, the implementation is trivial. Add the following return statement between the splicer lines in the Hello_World_Impl.cc file:
stringTo keep the Makefile simple, we will use the GNU gcc and g++ compilers. The following Makefile will compile the library files and create a shared library named libhello.so:
Hello::World_impl::getMsg()
throw ()
{
// DO-NOT-DELETE splicer.begin(Hello.World.getMsg)
return string("Hello World!");
// DO-NOT-DELETE splicer.end(Hello.World.getMsg)
}
.cc.o:You do not necessarily need to create a shared library for this example; you may generate a standard static library (e.g., libhello.a). However, in general, you must generate a shared library if you will be calling your library from Python or Java. To create the shared library archive libhello.so, simply execute make:
g++ -fPIC -I$(HOME)/babel/include -c $<
.c.o:
gcc -fPIC -I$(HOME)/babel/include -c $<include babel.make
OBJS = ${IMPLSRCS:.cc=.o} ${IORSRCS:.c=.o} \
${SKELSRCS:.cc=.o} ${STUBSRCS:.cc=.o}libhello.so: ${OBJS}
g++ -shared -o $@ ${OBJS}clean:
${RM} *.o libhello.so
% gmake libhello.so
#include <stdio.h>This code creates the Hello_World object, calls the getMsg method, prints the ubiquitous saying, decrements the reference count for the object, and frees the message string. To generate the C glue code necessary to call the library, we run the babel tool again, this time specifying C as the target language:
#include "Hello_World.h"int main(int argc, char** argv)
{
Hello_World h = Hello_World__create();
char* msg = Hello_World_getMsg(h);
printf("%s\n", msg);
Hello_World_deleteRef(h);
free(msg);
}
% $HOME/babel/bin/babel -cC -R$MYREPO hello.sidlThe "-cC" flag tells the babel code generator to create only the C client code, not the entire library implementation. The library libhello.so already contains the necessary IOR, skeleton, and implementation object files. We compile the hello program using the following Makefile:
.c.o:Note that the "-R" flags in the above Makefile snippet tell the dynamic library loader where to find the hello and sidl shared libraries. You could achieve the same behavior through environment variables such as LD_LIBRARY_PATH. Finally, we make the executable and run it:
gcc -I$(HOME)/babel/include -Ilib -c $<include babel.make
OBJS = hello.o ${STUBSRCS:.c=.o}hello: ${OBJS}
gcc ${OBJS} -o $@ \
-Rlib -Llib -lhello \
-R$(HOME)/babel/lib -L$(HOME)/babel/lib -lsidlclean:
${RM} *.o hello
% make helloCongratulations! You are now ready to develop a parallel scalable linear solver package.
% ./hello
Hello World!