m3makefile(7)             MODULA-3 PROGRAMMERS MANUAL            m3makefile(7)

NAME
m3makefile- The Modula-3 build file written in the quake extension lan-
guage.
m3overrides-  Overrides  elements  of  the  m3makefile  when   building
"local".

SYNOPSIS
m3makefile

DESCRIPTION
When  building  moderately  or very complex software packages, the com-
piler needs help identifying all that needs to happen.  This  is  where
the m3makefile and m3overrides file come into play.

The  exporting  of  packages  into the modula-3 system wide (or global)
repository is managed from these files.

Both the m3makefile and m3override files are scripts used in the build-
ing  of  Modula-3,  programs and libraries, and identifying items to be
exported as global entities.

A package may be build as either a "local"  or  "global"  entity.   The
m3overrides  file  is only used when building a "local" or non-exported
entity rather than a "global" or exported package.  The compiler switch
-override  is  used  to inform the cm3 compiler to read the m3overrides
file before it reads the m3makefile.  Some  packages  may  indicate  in
their  m3makefiles  that  they are only local , and are not exported to
the global repository.  The main procedure called  by  the  m3overrides
file is override(), as described below.

Both  the  m3makefile and m3overrides files are written in the quake(7)
extension language and are interpreted by the  modula-3  compiler  (the
interpreter is built into the cm3(1) compiler).

For  both  these  files,  cm3  first defines an additional set of func-
tions/procedures beyond the built-in functions and  procedures  of  the
quake  language.  These are specific to the tasks of building software.
These tasks are not only building both programs and libraries, but also

Both  these files are located in the " src " directory of your project,
and any nested subdirectory that gets  included  via  include_dir  (see
include_dir() below).

PACKAGING
Modula-3 is distributed as a set of packages. Each package is contained
in a single directory which conforms to a standard structure.  The  top
level directory should contain a README file (or index.html), and a src
subdirectory containing Modula-3 source files, and a derived  directory
for each platform on which the package has been built.

The location of public packages, as well as any other variable is spec-
ified in the cm3.cfg configuration file which is located  in  the  same
directory  as  cm3 executable program. You can move the compiler or the
public packages around, as long as the configuration file stays at  the
same directory as the compiler.

The  m3makefile,  that describes the package, resides in the src subdi-
rectory of the package. Although it is  common  for  all  the  Modula-3
sources to also reside in the src directory, they may be distributed in
a more complex directory structure rooted at src.

There are  three  primary  types  of  packages:  source,  program,  and
library.   A source package contains a collection of sources, like html
files; it builds nothing. A program package constructs  a  single  exe-
cutable  program  by  compiling  and  linking  the contents of a set of
source packages.  Similarly, a  library  package  constructs  a  single
library from a set of source packages.

Source Packages
The  m3makefile  for a source package simply lists the pieces of
source that are to be included in  programs  or  libraries  that
include the source package.

Program Packages
The m3makefile for a program package names the sources needed to
build the program, and the packages that it uses to satisfy  its
imports. It ends with a single program() or Program()
invocation. See the example.

Library Packages
The  m3makefile  for  a  library package names the sources to be
included in the library, and the packages that it uses  to  sat-
isfy  its  imports. It ends with a single library() or Library()
invocation.

Note that as in a program, all the imports of a package must  be
satisfied.  If  a  package  A  builds  a  library and any of the
objects in that library import interfaces from  another  library
package B, then import(B) must be specified in A's m3makefile.

Use cm3 -ship command to install a private package in the public
repository. Note that on some systems,  you  must  have  special
privileges to install public packages.

PROCEDURES
SOURCES
The  most  primitive declarations in an m3makefile are those that iden-
tify source files. They can be Modula-3, C or assembler files. A source
file has three attributes: a package, the subdirectory within the pack-
age where the declaration occurs, and a visibility. The visibility  has
two  values,  visible and hidden. When a package A imports a package B,
only the visible sources in B are available to compilations that  occur
in  A.  By  default all sources are visible. However, it is possible to
explicitly control the visibility of Modula-3 interfaces.

Source files are named relative to the m3makefile that mentions them.

interface(X)
declares that the file X.i3 contains an interface.

implementation(X)
declares that the file X.m3 contains a module.

module(X)
declares both the interface X.i3 and the module X.m3.

generic_interface(X)
declares that the file X.ig contains a generic interface.

generic_implementation(X)
declares that the file X.mg contains a generic module.

generic_module(X)
declares both a generic interface and module.

h_source(X)
declares that the file X.h contains a C include file.

c_source(X)
declares that the file X.c contains a C module.

s_source(X)
declares that the file X.s contains an assembly module.

pgm_source(X)
declares that the file X contains compilable source  (e.g.  .ic,
.mc, .is or .ms files).

With  the  exception  of  h_source, each of the procedures above
defines a hidden source file.  There  are  capitalized  variants
Interface,  Module,  Generic_interface,  Generic_implementation,
and Generic_module  that  identify  their  sources  as  visible.
Remember,  only those interfaces that are marked as visible will
be available to importers of your library or package.

template(X)
declares that the file X.tmpl contains quake code that is to  be
included in this build, and in all builds that import this pack-
age.

The template call is used to extend the set of available  proce-
dures.   For example, the table package includes a template that
defines the table procedure which instantiates the generic table
module.

IMPORT
Import  reflects  the fact that programs are built from separately com-
piled pieces, rather than being compiled as a whole. If we always  com-
piled from source, include would suffice.

import(P)
The  library  and  visible sources of package P are available to
satisfy  IMPORT  requests  in  the  current  compilation.    The
imported sources are not recompiled.

import_version(P,BuildDir)
Like import(P), but the library and visible sources of package P
are selected from building directory BuildDir  rather  than  the
default building directory for the current platform.

include_dir(D)
Recursively  include the sources named in the m3makefile in sub-
directory D of the current directory.

include_pkg(P)
Include the sources named in  package  P's  src/m3makefile.  The
location of P may be overridden.

BUILDING
library(X)
compile  the  sources accumulated so far and build a library, X,
from the resulting compiled object files.  The visibility of the
library is hidden.  Library(X) The same as library.

program(X)
constructs an executable program named X from the given sources.

Program(X)
like program, but X is exported to /bin.

build_standalone()
ensures that the program being built does not depend on  dynamic
linking and shared libraries.  To have an effect, this procedure
must be called before program or Program is called.

COMPILER OPTIONS
m3_option(x)
adds option x to the set of arguments passed to the compiler.

Specifically, m3_option adds x to the M3OPTIONS variable.  x should  be
a single string preceded with a hyphen, e.g.  m3_option(-O).

Some of the more useful compiler options include:

-why        Explain why each compilation is needed (default).
-commands   Print the compilation commands as they are started.
-verbose    Print what happens to each file.
-times      Print a breakdown of elapsed time.
-g          Generate debugging symbols (default).
-O          Optimize code.
-keep       Preserve intermediate files.
-once       Don't recompile modules with new opaque info.

Any compiler option may be specified here.  See cm3(1).

OVERRIDE
override(P,D)
Use the version of package P in directory D/P
instead of the one in /pkg/ P.

override  alters the behaviour of the include_pkg and import_pkg
procedures, and must be executed prior to any such calls to have
an effect.

To help ensure that the public repositories are consistent, "cm3
-ship", and the older "m3ship" will refuse to install any  pack-
age built using overrides.

When  the  -override  option  is specified, cm3 looks for a file
named m3overrides in the src directory and, if one exists,  exe-
cutes  it  immediately prior to executing m3makefile. By keeping
all override calls in an m3overrides file and not in an  m3make-
file, you can build both private and public versions of packages
without editting any files.

The overrides in effect when a package was built  are  automati-
cally carried forward into importers of the package, so there is
no need to restate the complete set of overrides at every level,
only  of  those packages that are directly imported into a given
package.

There is a pre-declared variable, WDROOT, that defines the  con-
ventional  location of a user's private package repository. (see
\ref{VAR-sec}).

FOREIGN OBJECTS AND LIBRARIES
These procedures allow foreign objects and/or libraries to be  included
in a Modula-3 program.  Here foreign means not written in Modula-3.

import_lib(X,P)
If  P/libX.a  is  a  library, includes -LP -lX in the final link
command.  Otherwise, includes -lX in the final link command.

import_obj(X)
Include X in the final link command.

EXPORTING FILES
These functions should be used to export files to the  public  directo-
ries.   These  public directories are bound to actual directories via a
set of logical assignments specific to your installation.

BinExport(X)
exports source file X to /bin.

BindExport(X)
exports derived file X to /bin.

DocExport(X)
exports source file X
to /doc.

DocdExport(X)
exports derived file X to /doc.

EmacsExport(X)
exports  source  file  X  to  /emacs.   EmacsdExport(X)  exports
derived  file  X to /emacs.  HtmlExport(X) exports source file X
to /html.

LibExport(X)
exports source file X to /lib.

LibdExport(X)
exports derived file X to /lib.

ManExport(X,sec)
exports source file X.sec to section sec of /man.

MandExport(X,sec)
exports derived file X.sec to section sec of /man.

HIDING AND EXPORTING
The following procedures can be used in two ways.  First to  provide  a
clearer  indication  of  visibility than is given by the capitalization
convention (which exists partly  to  support  old  style  m3makefiles).
Second,  to  change  the visibility of imported components.  Generally,
it's much better to convince the owners of  the  exporting  package  to
give  their sources the correct visibility rather than overriding their
initial decision.

Hidden programs are not copied to the  /bin  directory,  exported  ones
are.

hide_interface(X)
sets the visibility of interface X.i3 to hidden.

export_interface(X)
sets the visibility of interface X.i3 to visible.

There  are  also  variants  that  hide or export programs and generics,
hide_program,   hide_generic_interface,    hide_generic_implementation,
export_program,  export_generic_interface, and export_generic_implemen-
tation.

INSTALLATION DEPENDENCIES
The builder contains some built-in support for  machine  and  operating
system dependencies. The package structure makes provision for separate
build directories for different machine and operating  system  combina-
tions.  The default behaviour of cm3 is to generate the compiled object
files, libraries and programs in the build directory  corresponding  to
the machine and operating system on which cm3 is executing.

The following set of variables exist to allow m3makefiles to be parame-
terised by machine and operating system.

INSTALLATION DEPENDENCIES
The builder contains some built-in support for  machine  and  operating
system dependencies. The package structure makes provision for separate
build directories for different machine and operating  system  combina-
tions.  The default behaviour of cm3 is to generate the compiled object
files, libraries and programs in the build directory  corresponding  to
the machine and operating system on which cm3 is executing.

The following set of variables exist to allow m3makefiles to be parame-
terised by machine and operating system.

TARGET This variable defines the machine type on which the  library  or
program being built will execute. It is chosen from the standard
set of machine types on which Modula-3 runs. Check  the  runtime
or cm3 packages for the complete set.

OS_TYPE
This  variable  defines  the  operating  system  under which the
library or program being built will execute. Currently, Modula-3
supports  two  operating  system  variants, POSIX and WIN32. The
former breaks down further  into  specific  variants,  but  this
variation  is  not made available to clients. [There is a way if
you absolutely need it, see the unix package.]

BUILD_DIR
This names the package  sub-directory  in  which  object  files,
libraries  and  programs  will  be built. It is usually, but not
always, the same as TARGET.

The net effect of the above allows a single package to  build  a
family  of architectural variants, in different build sub-direc-
tories, where each variant uses the  same  set  of  m3makefiles,
parameterized  by  the above variables. If this degree of flexi-
bility is insufficient, then the extra variation must be  speci-
fied  in a separate package, which can use include_pkg to access
the shared sources.

PKG_USE
This defines the location of the public package repository, e.g.
/proj/m3/pkg or /usr/local/lib/m3/pkg.

WDROOT This  defines the standard location for a user's private package
repository, typically $HOME/m3/pkg. This is typically used in override calls. TARGET This variable defines the machine type on which the library or program being built will execute. It is chosen from the standard set of machine types on which Modula-3 runs. Check the runtime or cm3 packages for the complete set. OS_TYPE This variable defines the operating system under which the library or program being built will execute. Currently, Modula-3 supports two operating system variants, POSIX and WIN32. The former breaks down further into specific variants, but this variation is not made available to clients. [There is a way if you absolutely need it, see the unix package.] BUILD_DIR This names the package sub-directory in which object files, libraries and programs will be built. It is usually, but not always, the same as TARGET. The net effect of the above allows a single package to build a family of architectural variants, in different build sub-direc- tories, where each variant uses the same set of m3makefiles, parameterized by the above variables. If this degree of flexi- bility is insufficient, then the extra variation must be speci- fied in a separate package, which can use include_pkg to access the shared sources. PKG_USE This defines the location of the public package repository, e.g. /proj/m3/pkg or /usr/local/lib/m3/pkg. WDROOT This defines the standard location for a user's private package repository, typically$HOME/m3/pkg.  This is typically used in
override calls.

MISCELLANEOUS
The declarations in this section are  typically  only  needed  by  spe-
cialised applications, for example the Modula-3 compiler or other quake
templates.

source(X)
declares that X contains non-compilable source.

derived_interface(X,V)
adds the derived interface X.i3 to the list of files to be  com-
piled.  V
must be either VISIBLE or HIDDEN to indicate whether the inter-
face should be available to importers outside this package.

derived_implementation(X)
adds the derived module X.m3 to the list of  files  to  be  com-
piled.

derived_c(X)
adds the derived C code X.c to the list of files to be compiled.

derived_h(X)
adds the derived include file X.h to the list of  include  files
available to the compiler.

EMACS SUPPORT
The  following functions support building and installing GNU emacs lisp
code.

Gnuemacs(X)
exports source file X.el to /emacs.

CompiledGnuemacs(X)
exports the source  file  X.el  and  compiles  and  exports  the
derived file X.elc to /emacs.

GENERICS SUPPORT
Many  of  the  packages that export generic interfaces and modules also
define m3makefile procedures that will instantiate the  generic  source
and add it to the list of Modula-3 sources to be compiled.  The instan-
tiated interfaces and modules are created in the derived directory,  so
they won't clutter up your source directory.

array_sort(nm,elt)
instantiates  the  ArraySort  generics to produce nmArraySort.i3
and nmArraySort.m3 which implement a sort for  arrays  of  elt.T
values.

Array_sort(nm,elt)
like  array_sort,  but  also  makes  the  interface available to
importers outside the current package.

list(nm,elt)
instantiates  the  List  generics  to  produce   nmList.i3   and
nmList.m3 which implement linked lists of elt.T values.

List(nm,elt)
like  list,  but also makes the interface available to importers
outside the current package.

list_sort(nm,elt)
instantiates the ListSort generics to produce nmListSort.i3  and
nmListSort.m3  which  implement a sorting procedure for lists of
elt.T
values. This  procedure  assumes  that  list(nm,elt)  has  been
called.

List_sort(nm,elt)
like  list_sort,  but  also  makes  the  interface  available to
importers outside the current package.

pqueue(nm,elt)
instantiates the PQueue generics to produce nmPQ.i3 and  nmPQ.m3
which implement a priority queue of elt.T values.

Pqueue(nm,elt)
like pqueue, but also makes the interface available to importers
outside the current package.

sequence(nm,elt)
instantiates the Sequence generics to  produce  nmSeq.i3,  nmSe-
qRep.i3 and nmSeq.m3 which implement a sequence of elt.T values.

Sequence(nm,elt)
like sequence,  but  also  makes  the  interfaces  available  to
importers outside the current package.

sorted_table(nm,key,value)
instantiates  the SortedTable generics to produce nmSortedTbl.i3
and nmSortedTbl.m3
which implement a sorted  table  mapping  from  type  key.T  to
value.T.

Sorted_table(nm,key,value)
like  sorted_table,  but  also  makes the interface available to
importers outside the current package.

table(nm,key,value)
instantiates the Table generics to produce nmTbl.i3 and nmTbl.m3
which implement a table mapping from type key.T to value.T.

Table(nm,key,value)
like  table, but also makes the interface available to importers
outside the current package.

MANUAL PAGES SUPPORT
The following calls format and install man pages.

manPage(name,sec)
formats man page name.sec.

ManPage(name,sec)
is like manPage, but also exports the man page to section sec of
/man.

ManExport(X,s)
exports source file X.s to section s
of /man without further formatting.

MandExport(X,s)
export  derived  file  X.s  to section s of /man without further
formatting.

NETWORK OBJECTS SUPPORT
The following procedures are  used  to  build  programs  using  network
objects.

netobj(X,T)
runs the network objects stub generator on the interface X.i3 to
produce the network object glue needed to manipulate objects  of
type  X.T.   The resulting source files are included in the cur-
rent build.

Netobj(X,T)
Like netobj, but also exports the resulting interface.

RESOURCES
The following procedures support the inclusion of arbitrary data, known
as a resource, in a program.  For example an image as a PNG file.

resource(file)
is shorthand for resource_named(file,file).

resource_named(rd,file)
declares that file is a resource file. It will be accessible via
the reader rd if a bundle is built.

bundle(m)
declares that the module m is to be built as  a  bundle  of  the
files   specified   by   the   prior   calls   to  resource  and
resource_named.

EXAMPLE
For example, here's a simple program composed  of  a  main  module,  an
imported interface and its implementation.

To  begin,  create  a  fresh  directory for the package and within that
directory, a directory for the source files:

> mkdir hello
> cd hello
> mkdir src

Create the following source files in the src directory:

In the file src/Main.m3:

MODULE Main;
IMPORT A;
BEGIN
A.DoIt ();
END Main.

In the file src/A.i3:

INTERFACE A;
PROCEDURE DoIt ();
END A.

In the file src/A.m3:

MODULE A;
IMPORT Wr, Stdio;

PROCEDURE DoIt () =
<*FATAL ANY*>
BEGIN
Wr.PutText (Stdio.stdout, "Hello world.0);
Wr.Close (Stdio.stdout);
END DoIt;

BEGIN
END A.

In the file src/m3makefile:

import ("libm3")
implementation ("Main")
module ("A")
program ("foo")

Finally, from the package directory, hello, run cm3.  This  should/will
compile  the  three  source  files  and  link  them  with  the standard
libraries. The derived files will be placed in a directory  that  names
the architecture. On an Alpha/AXP machine running OSF, the directory is
called ALPHA_OSF. The executable program  will  be  named  foo  in  the
derived directory.

NOTES
The  older  style of m3makefiles using the capitalization convention is
depreciated, and its use is highly discouraged.

The quake interpreter is built into the CM3 Modula-3 compiler,  whereas
it was a separate executable for earlier ones, such as PM3.
The  Critical  Mass  Modula-3  compiler  cm3(1),  and the man pages for
quake(7).

For a full list of compiler options, please see cm3(1).

For creating network objects see the manpage for stubgen(1).

For a description of how to access resources from your running program,
see  the  Bundle  and  Rsrc  interfaces,  along with the developer tool
program m3bundle(1).

AUTHOR
(man page) Peter Eiserloh (eiserlohpp -at- yahoo.com)