Quick Navigator

 Search Site Miscellaneous Server Agreement Year 2038 Credits

# Manual Reference Pages  -  M3MAKEFILE (7)

### NAME

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

### CONTENTS

Synopsis
Description
Packaging
Procedures
Sources
Import
Building
Compiler Options
Override
Foreign Objects And Libraries
Exporting Files
Hiding And Exporting
Installation Dependencies
Installation Dependencies
Miscellaneous
Emacs Support
Generics Support
Manual Pages Support
Network Objects Support
Resources
Example
Notes
Author

m3makefile

### DESCRIPTION

When building moderately or very complex software packages, the compiler 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 building 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 functions/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 documentation and other miscellaneous tasks.

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 specified 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 subdirectory 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 executable 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 satisfy 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 identify source files. They can be Modula-3, C or assembler files. A source file has three attributes: a package, the subdirectory within the package 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 package. The template call is used to extend the set of available procedures. 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 compiled pieces, rather than being compiled as a whole. If we always compiled 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 subdirectory 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 package built using overrides. When the -override option is specified, cm3 looks for a file named m3overrides in the src directory and, if one exists, executes it immediately prior to executing m3makefile. By keeping all override calls in an m3overrides file and not in an m3makefile, you can build both private and public versions of packages without editting any files. The overrides in effect when a package was built are automatically 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 conventional 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 directories. 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_implementation.

#### 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 combinations. 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 parameterised 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 combinations. 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 parameterised 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-directories, where each variant uses the same set of m3makefiles, parameterized by the above variables. If this degree of flexibility is insufficient, then the extra variation must be specified 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-directories, where each variant uses the same set of m3makefiles, parameterized by the above variables. If this degree of flexibility is insufficient, then the extra variation must be specified 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 specialised 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 compiled. V
must be either VISIBLE or HIDDEN to indicate whether the interface should be available to importers outside this package.
derived_implementation(X)
adds the derived module X.m3 to the list of files to be compiled.

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 instantiated 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, nmSeqRep.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 current 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)
Search for    or go to Top of page |  Section 7 |  Main Index

 CRITICAL MASS M3MAKEFILE (7) 28-Jun-2009

Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.