gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gm2] On the gm2 build process and dependencies


From: Martin Hofmann
Subject: Re: [Gm2] On the gm2 build process and dependencies
Date: Wed, 20 Jun 2012 23:11:05 +0200
User-agent: Mozilla/5.0 (X11; FreeBSD i386; rv:12.0) Gecko/20120506 Thunderbird/12.0.1

Hi Gaius,

thank you for your helpful comments.

a good description - would be great to place this into the gm2 internals
section of the documentation.

I'll clean the text up a bit and send it to you, you may incorporate it in the documentation as you see fit.


2  Assemble modules into object files
-------------------------------------

     as: hello.s -->  helloprog.o

Nothing special here, this is done by all GCC compilers.

But note that the object file for the main program module is named
`helloprog.o` instead of `hello.o`. (This is of course only relevant if
non-temporary files are created via the `-save-temps-option` to gm2.)

yes this is because hello.o is the C++ scaffold object (generated by
compiling hello.cpp) see below and helloprog.o is the main program
module.

Isn't the `hello.cpp` compiled into `hellostart.o` (see below)? Not that
it matters much, though.

3  Collect a list of all modules to be initialized
--------------------------------------------------

     gm2l: hello.mod -->  hello.l

gm2l will topologically order the module imports - but it cannot
solve cyclic imports obviously.

Okay, that's what I expected.

     gm2lorder: hello.l -->  hello.lst

it ensures that the core system modules are the initialised first.
See -fruntime-modules=

which specify, using a comma separated list, the runtime modules and
their order.  These modules will initialised first before any other
modules in the application dependency.  By default the runtime modules
list is set to Storage,SYSTEM,M2RTS,RTExceptions,IOLink.  Note that
these modules will only be linked into your executable if they are
required.  So adding a long list of dependant modules will not effect
the size of the executable it merely states the initialisation order
should they be required.

Good to know.

QUESTION: Where does `gm2cc` come from?

it is just a copy of 'gcc' from the 4.1.2 tree.  Called gm2cc to avoid
any name clash.

I see.

    Would'n it be nicer and easier to generate a Modula-2 scaffolding
    program containing a `main()` function?

ok yes - this could be done.  The main program module could contain the
main function.  It is not clear that there would be huge benefits
though.

Indeed. It just bothered me that a C++ compiler is needed to build a modest Modula-2 program, so it's probably good that this is technically not a requirement.

    Could this also avoid the need to link `libstd++` in?

ah well possibly this route could be taken - but I'd rather stay with
libstdc++ as it provides gm2 with mixed language support.  The ability
to link with C++ and Ada (probably Java) as well and throw and catch
other language exceptions.  Currently gm2 can work with swig and
languages such as Python can catch gm2 exceptions.  I raised (no pun
intended) this subject at a gcc conference in 2009 and the strong advice
was to use libstdc++.  I know it adds compiler build time, but the end
user should get many benefits.

Having mixed language support like this is certainly a bonus.

    Since this scaffoling program would only vary in the list of
    functions to be called (init, main, finish), we could even re-use a
    fixed object module which references just a list of function pointers
    outside in a build-time generated (assembly?) object ...?

an interesting approach I grant.  I'm keen to keep an eye on the
embedded system platform - where data size is sometimes needs to be kept
to a bare minimum.  For a native *nix machine your approach would work
well.

Maybe I'm going to experiment with that approach, looks nice to me.

    This way every module would itself arrange for the initialization of
    its imported modules. (A more elaborate variant would distingish
    between import of procedures and variables - which need initialized
    provider modules - and import of types and constands only - wich
    doesn't.)

ok, this could be added and implemented with a command line link option
if required?

Sure. Another route for experiment :-)

    I'd very much like to get rid of the dependency of both the C++
    compiler and the C++ library ...

I hear this - but the exception handling code is quite complex and has
been solved by the gcc developers.  Having to maintain a Modula-2
version seems to be creating unnecessary work.  It also occasionally
changes and I'd rather just use the default one provided by gcc.  The
Ada group had a setjmp/longjump mechanism - but seem to be deprecating
this in favour of libstdc++

Not quite. GNAT actually supports both models where appropriate - the `setjmp`/`longjmp` way where nothing else is available, and the "zero cost" C++ ABI (if this is the correct name ...) as a default where it is available. But GNAT uses only the "Base ABI" [ABI1]`_Unwind_RaiseException` and friends from "outside" (eg from `libgcc_s`).

For the C++ (g++) functions `__cxa_begin_catch` etc (these seem to be the "Level II: C++ ABI" [ABI2]), the compiled code references (more or less equivalent?) functions `__gnat_begin_handler` etc.

There is also a special `__gnat_eh_personality` function provided in `ada/raise-gcc.c`.

[ABI1]:http://sourcery.mentor.com/public/cxx-abi/abi-eh.html#base-abi
[ABI2]:http://sourcery.mentor.com/public/cxx-abi/abi-eh.html#cxx-abi

So GNAT doesn't use `libstdc++` at all, but I'm not sure what this means in terms of run time behaviour when it comes to mixed Ada and C++ exception handling ... (And looking into the GNAT exception handling sources sure doesn't invite to write your own!) A shared-linked executable links to

    libgnat.so
    libgcc_s.so
    libc.so
    libm.so
    libthr.so

Out of curiosity I peeked into an object file generated by Native XDS-x86 Modula-2 [XDS] from a small exception-handling module: `nm` shows a reference to `X2C_setjmp`, so this looks like the first exception handling model (there is no mention of C++ exceptions in the XDS documentation at all). The executable links to

    libc.so
    libm.so

(and needlessly to `libncurses.so). There seems to be no way to have the Modula-2 libraries dynamically linked.

[XDS]:http://www.excelsior-usa.com/xdsx86.html


All in all, I'd like to have a more GNAT-like compilation:

- No need for a C++ compiler at compile time (by using the precompiled
  start-up object or a generated Modula-2 start-up scaffolding module);

- No need for `libstdc++.a` at link time (rsp dependency on
  `libstdc++.so` at run time);

- An easy way to link to shared run time libraries (`libgm2.so`,
  `libgcc_s.so`, `libc.so`, `libm.so` (I thought that the `/SO`
  sub directories in `gm2/pim` etc would have a `libgm2.so` etc,
  but they don't ...).

Nice to have:

- An own implementation of complex elementary functions and others on
  top of a C90 `libm` (tedious, but can probably borrowed from GNU
  `libm`);

- The run-time import tree walking as sketched above - mostly to avoid
  the two-time parsing of all the sources.

That gives me a route for experiments:

- Replace the `gmcc` step with the use of a start-up object.

- Add exception support to the run-time library (ie personality routine
  and Level II functions, possibly renamed, as copies from `libc++`).

- Produce appropriate shared libraries for the `gm2` libs, and let them
  be found when linking - switched by an option.

Does that sound reasonably (or, well, feasible ...)?

I was considering whether to modify gm2 to compile whole project at
once.  Ie read in all source from all modules and compile producing
a single .o, this would allow for intermodule optimisations which could
hopefully reduce the overall footprint of an executable.

Hmm, isn't the problem that on the contrary the linker draws in a pretty big object for every _module_ (instead of procedure) of the standard libraries? So that it would reduce the executable size if the linker would eliminate unused _functions_ - from one or from many input object files. I would expect to gain executable speed from intermodule optimization, but not necessarily code size reduction (think of inline expansion).


Regards

Martin



reply via email to

[Prev in Thread] Current Thread [Next in Thread]