Next: How to produce swig interface files, Previous: Unbounded by reference, Up: Using GNU Modula-2 [Contents][Index]
This section describes building a tiny shared library implemented in Modula-2 and built with libtool. Consider a project consisting of three definition modules and three implementation modules a.def, a.mod, b.def, b.mod, c.def and c.mod.
DEFINITION MODULE a ; END a.
IMPLEMENTATION MODULE a ;
FROM libc IMPORT printf ;
BEGIN
printf ("init: module a\n")
FINALLY
printf ("finish: module a\n")
END a.
Module b is almost identical, but it imports module a.
DEFINITION MODULE b ; END b.
IMPLEMENTATION MODULE b ;
IMPORT a ;
FROM libc IMPORT printf ;
BEGIN
printf ("init: module b\n")
FINALLY
printf ("finish: module b\n")
END b.
Likewise Module c is almost identical, but it imports from
module b.
DEFINITION MODULE c ; END c.
IMPLEMENTATION MODULE c ;
IMPORT b ;
FROM libc IMPORT printf ;
BEGIN
printf ("init: module c\n")
FINALLY
printf ("finish: module c\n")
END c.
The first step is to compile the modules using position independent code. This can be achieved by the following three commands:
libtool --tag=CC --mode=compile gm2 -g -c a.mod -o a.lo libtool --tag=CC --mode=compile gm2 -g -c b.mod -o b.lo libtool --tag=CC --mode=compile gm2 -g -c c.mod -o c.lo
The second step is to link these objects into a shared library.
export LIBDIR=$(gm2 -print-file-name=)../../../../lib64
libtool --tag=CC --mode=link gcc -g a.lo b.lo c.lo \
-L${LIBDIR} -rpath `pwd` -lm2pim -lm2iso -lstdc++ \
-lm -o libabc.la
At this point the shared library libabc.so will have been created inside the directory .libs.
This library can be called from C++ using the following technique.
The define USER_LIB is the name of the library dialect and
maybe changed if required.
The DEFAULT_RUNTIME_MODULE_OVERRIDE is a predefined string
containing the default base core module initialization order.
#include <stdio.h>
#include <m2rts.h>
#define USER_LIB NULL
/* Add the runtime dependency for this file on modules a, b and c. */
void
dep (void)
{
m2iso_M2RTS_RequestDependant (__FILE__, USER_LIB, "c", USER_LIB);
m2iso_M2RTS_RequestDependant (__FILE__, USER_LIB, "b", USER_LIB);
m2iso_M2RTS_RequestDependant (__FILE__, USER_LIB, "a", USER_LIB);
}
void
init (int, char *[], char *[])
{
printf ("test.c:init\n");
}
void
fini (int, char *[], char *[])
{
printf ("test.c:fini\n");
}
void
construct_scaffold (int argc, char *argv[], char *envp[])
{
m2iso_M2RTS_RegisterModule (__FILE__, USER_LIB,
init, fini, dep);
m2iso_M2RTS_ConstructModules (__FILE__, USER_LIB,
DEFAULT_RUNTIME_MODULE_OVERRIDE,
argc, argv, envp);
}
void
deconstruct_scaffold (int argc, char *argv[], char *envp[])
{
m2iso_M2RTS_DeconstructModules (__FILE__, USER_LIB,
argc, argv, envp);
}
int
main (int argc, char *argv[], char *envp[])
{
printf ("main starts\n");
construct_scaffold (argc, argv, envp);
printf ("main application goes here\n");
deconstruct_scaffold (argc, argv, envp);
printf ("main tidying up\n");
return 0;
}
This source file can be compiled and linked using the following command:
export INCLUDE=$(gm2 -print-file-name=)/m2/m2iso
g++ -I${INCLUDE} -g test.c -L. -l:.libs/libabc.so -L${LIBDIR} -lm2iso
and finally run using:
LD_LIBRARY_PATH=.libs:${LIBDIR} ./a.out
main starts
init: module a
init: module b
init: module c
test.c:init
main application goes here
test.c:fini
finish: module c
finish: module b
finish: module a
main tidying up
Next: How to produce swig interface files, Previous: Unbounded by reference, Up: Using GNU Modula-2 [Contents][Index]