Let’s write a minimal module with one exported function in Oberon:
MODULE m;
PROCEDURE add*(a, b : INTEGER): INTEGER;
BEGIN
RETURN a + b;
END add;
END m.
We even can compile it now with oo2c
$ oo2c m.Mod
and get directories obj and sym.
We may now compile obj/m.c
and get an object m.o
gcc -Iobj -I/local/oo2c/lib/oo2c/src -I/local/oo2c/lib/oo2c/obj -c obj/m.c
Now we need a pascal wrapper to bind it.
Let’s call it mbind.pas
unit mbind;
{$link m.o}
(*oo2c objs to link*)
{$link RT0.o}
{$link Object.o}
{$link Exception.o}
{$link HashCode.o}
{$linklib c}
interface
uses CTypes;
function m__add(a, b : ctypes.cint16) : ctypes.cint16; cdecl; external;
(*
/local/oo2c/lib/oo2c/obj/C.oh
typedef OOC_INT16 C__shortint;
*)
implementation
end.
We need to tell compiler explicitly which object files to link.
m.o is the object file we get by compiling obj/m.c
Other files are the minimal oo2c rtl which needs to be linked.
We also need to link to libc, because oo2c works by compiling via C.
Function name is m__add because oo2c translates m.add to C as m__add
Note, that implementation section is empty, and fpc does not issue an error because the function marked as external.
Eventually, let’s write a main module to call the Oberon function.
program m0;
uses mbind;
var i : integer;
begin
i := m__add(20, 3);
writeln (i);
end.
Neither fpc nor oo2c do not need a make file.
FreePascal compiler, as well as Oberon can itself resolve module dependencies.
For example, I do not need to write a makefile where I compile first mbind.pas and get mbind.o and link it during the next step.
However, in this case I’d like to write a make file.
IPATH = -Iobj -I/local/oo2c/lib/oo2c/src -I/local/oo2c/lib/oo2c/obj
LPATH = /local/oo2c/lib/oo2c/obj
GCC = /usr/bin/gcc
OO2C = /local/oo2c/bin/oo2c
FPC = /local/fpc/bin/fpc
all:
$(OO2C) m.Mod
$(GCC) $(IPATH) -c obj/m.c
$(FPC) -Fo$(LPATH) -Fo. m0.pas
clean:
rm *.o
rm *.ppu
I usually use custom fpc I compiled from subversion, and I prefer to keep my software in /local
LPATH is the path where oo2c main rtl objects are located, so fpc can find and link RT0.o, Exceptions.o, Object.o and HashCode.o.
So, first oo2c compiles the m module to c.
Then gcc compiles it to object file.
Then fpc compiles the main module.
And now enjoy:
$ ./m0
23
und so weiter