erzahlung uber: interfacing freepascal code with Oberon (oo2c)

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

պիտակներ՝ ջիսիսի  տեքնոլոգիաներ  տեղեկատուական տեքնոլոգիաներ  օբերոն  ֆրիպասկալ