CM3 5.1 and Elego ComPact

Instead of using the shell scripts provided in the script directory of the source distribution, you can use the project manager of Elego ComPact to build, ship, clean, and generally maintain the CM3 5.1 packages. Elego ComPact offers also a component based view of version control (with components being packages, projects, and configurations) built on top of CVS. Elego ComPact Free (free non-commercial use) and Elego ComPact Demo (expiring free evaluation) can be downloaded from Elego's WWW site.

Currently Elego ComPact is not distributed as open source, but with the release of CM3 5.1 there may be a more tightly integrated version of the Elego ComPact project manager and the CM3 builder that we release under the DEC SRC copyright. If you're interested in this, please write us about it. Elego ComPact is written entirely in Modula-3.

How to compile CM3 5.1 with Elego ComPact

It's quite easy to use Elego ComPact together with the CM3 5.1 distribution. These steps are necessary:

  1. Install Elego ComPact
  2. Define an appropriate package kind
  3. Setup an Elego ComPact project

You may then

  1. Compile and ship CM3 packages with Elego ComPact
  2. Version control your CM3 packages
  3. Apply arbitrary commands to one, several, or all packages

Install Elego ComPact

Please refer to the installation instructions on Elego's Download pages. Basically you only need to get the executable programs for your platform, unpack them somewhere in your file system, and extend your PATH. It is probably a good idea to get the configuration and manual archives as well, though.

The program you're using for project management tasks is named prjm. You will get a short help notice with prjm -h and a more verbose description with prjm -man. You can also use Elego ComPact's graphical user interface ComPactHTTPd.

Try to run the programs and have a look at the in-line help. If you encounter any problems, feel free to contact compact{at}

Define an appropriate package kind

The Elego ComPact tools need to be able to locate and identify your CM3 packages. As Elego ComPact is language independent, it needs some information about the structure of packages and the actions that may be applied to them. Here at Elego we currently use the following definitions:

# ----------------------------------------------------------------------------
# CM3 5.1 System Packages on UNIX
# ----------------------------------------------------------------------------
  ostype "bsd|unix|linux|sunos5" has file "src/m3makefile" and dir "src"
  inherit actions BASIC_VC_UNIX_OVERRIDES
  inherit actions BASIC_VC
  inherit actions CRITICAL_MASS_M3_SYS

# ----------------------------------------------------------------------------
# CM3 5.1 System Packages on Win32
# ----------------------------------------------------------------------------
  ostype "winnt|windows|win32|nt|cygwin" has file "src/m3makefile" and dir "src"
  inherit actions CRITICAL_MASS_M3_SYS

# ----------------------------------------------------------------------------
# CM3 5.1 System Packages
# ----------------------------------------------------------------------------
  has file "src/m3makefile" and dir "src"
  inherit actions BASIC_VC
  action build 			"m3msh -- rm .bok && cm3 {?OPT} {?CM3OPT} -build 2> PkgErr && m3msh -- touch .bok"
  action buildlocal		"m3msh -- rm .bok && cm3 {?OPT} {?CM3OPT} -DROOT={!ROOT} -build -override && m3msh -- touch .bok"
  action builtok 		"test -f .bok"
  action shipglobal		"cm3 {?OPT} {?CM3OPT} -ship 2> PkgErr && m3err PkgErr"
  action shipproject		"cm3 {?OPT} {?CM3OPT} -ship 2> PkgErr && m3err PkgErr"
  action shiplocal		"echo no shipping needed"
  action clean			"cm3 {?OPT} {?CM3OPT} -clean 2> PkgErr && m3err PkgErr"
  action realclean		"m3msh rm {?OPT} {?RMOPT}  PkgDep PkgCDT PkgCRT PkgErr ; cm3 {?OPT} {?CM3OPT} -clean"
  action mkdep			"m3dep {?OPT} {?M3DEPOPT} > PkgDep && test -f src/m3overrides || m3ovr -v {!LOCATIONS} > src/m3overrides 2> PkgErr"


These definitions extend the standard definitions bundled with Elego ComPact's programs. We suggest you put them into the file ${HOME}/compact/PkgBase.DefaultData, which is one of the standard locations where ComPact will look for them.

You could as well use the bundled definitions only, but by default the project manager will overwrite your m3overrides files with generated ones containing absolute paths from your workspace. This will make it difficult to provide patches (context diffs). So we suggest you use the above definitions and ensure that all the m3override files are correct, i.e. defining all necessary overrides relative to the variable ROOT. As the first source distribution of CM3 did only contain some correct m3override files, you probably want to get the m3override-update.tgz update archive. You will notice that the buildlocal action uses the variable ROOT which must be passed to prjm on the command line, e.g. prjm -D ROOT=~/work/cm3 more-arguments.

Finally you need to make sure that Elego ComPact correctly identifies your packages. You can do this by setting the environment variable PKGKIND=CRITICAL_MASS_M3_SYS_UNIX and exporting its value, or by placing a PkgKind file containing that name in every package root. This can easily be accomplished with one of the scripts in cm3/scripts:

  ./ -c 'echo CRITICAL_MASS_M3_SYS_UNIX > PkgKind' `cat PKGS`

If the package database PKGS does not yet exist, you must create it with ./find-packages.

That's all that is needed for the general setup of Elego ComPact and CM3.

Setup an Elego ComPact project

To actually do something useful with the Elego ComPact tools, and CM3, you also need one or more project descriptions. These are packages that contain a project description file (PrjDesc). A project description file that contains some CM3 standard packages looks like this (~/work/prjm/cm3-std/PrjDesc):

  collectionroot ${PRJ_ROOT}
  collection m3-comm at cm3/m3-comm
  collection m3-db at cm3/m3-db
  collection m3-demo at cm3/m3-demo
  collection m3-games at cm3/m3-games
  collection m3-lectern at cm3/m3-lectern
  collection m3-libs at cm3/m3-libs
  collection m3-mail at cm3/m3-mail
  collection m3-obliq at cm3/m3-obliq
  collection m3-pkgtools at cm3/m3-pkgtools
  collection m3-sys at cm3/m3-sys
  collection m3-tools at cm3/m3-tools
  collection m3-ui at cm3/m3-ui
  collection m3-www at cm3/m3-www
  collection sharedboard at cm3/m3-demo/sharedboard

  package m3core in m3-libs
  package libm3 in m3-libs
  package X11R4 in m3-ui
  package bitvector in m3-libs
  package digraph in m3-libs
  package formsedit in m3-ui
  package formsvbt in m3-ui
  package formsvbtpixmaps in m3-ui
  package formsview in m3-ui
  package jvideo in m3-ui
  package m3back in m3-sys
  package m3bundle in m3-tools
  package m3scanner in m3-sys
  package m3tk in m3-tools
  package netobj in m3-comm
  package netobjd in m3-comm
  package parseparams in m3-libs
  package realgeometry in m3-libs
  package set in m3-libs
  package slisp in m3-libs
  package sortedtableextras in m3-libs
  package stubgen in m3-comm
  package table-list in m3-libs
  package tcp in m3-comm
  package tempfiles in m3-libs
  package ui in m3-ui
  package vbtkit in m3-ui
  package videovbt in m3-ui
  package web in m3-www

The PrjDesc file contains definitions of collections and packages and their location. In the file above, all package locations are relative to the environment variable PRJ_ROOT, which is convention at Elego. You could also directly insert the path to the root of your workspace there.

A PrjDesc file must reside in the directory where prjm is invoked, which is then considered to be a project package. A project package is also used by prjm to save and reconstruct project configurations and version control the needed meta data. For build management purposes you need not concern yourself with these uses.

It is probably easiest to get the cm3-elego-5.1.0.tgz archive which contains some example project files and the appropriate package kind definitions.

Compile and ship CM3 packages with Elego ComPact

Once you have setup everything as described, you can easily compile an arbitrary big set of packages. We'll use the cm3-std project again as an example, which we assume is installed in your home directory under ${HOME}/work/prjm/cm3-std:

  export ROOT PRJ_ROOT

  prjm -D ROOT=${ROOT} -buildlocal

The first three lines are just to remind you of the setup needed, while the last line will compile all packages in the PrjDesc file. The project manager will automatically determine the dependencies of the packages (as long as all the imports can be found in the top-level m3makefile) and issue all needed commands. It also uses a cache containing fingerprints of all the packages, so that only packages that have changed will be re-compiled. So the given command should usually find a quite minimal set of build commands.

If you want to compile all the packages and ship them to the CM3 package pool (usually in /usr/local/cm3/pkg), use the following command:

  prjm -D ROOT=${ROOT} -buildglobal

Version control your CM3 packages

If you have set up CVS and your packages are under version control, you can use the Elego ComPact package version manager pkgvm to checkout named versions of packages, commit changes, view diff listings, package logs, etc. And you can use the project manager prjm to apply version control on a project wide scale. Note: You must have checked out the packages from a CVS repository for this to work. Elego would like to provide public access to the CM3 CVS repository via CVS and CVSup, but this needs some time to organize and setup; anyway, it's not working yet.

Let's assume you have got a working CVS repository with all the versions of all the CM3 sources. You can then checkout an initial workspace populated with the latest versions with:

  prjm -get head

If you have made some modifications, you may want to see what packages are modified and produce a unified context diff of all the changes:

  prjm -mod
  prjm -m -q -qc -udiff

You could then commit all the changes and create a named change set at the same time:

  prjm -m -cs my-change-set -commit patch

To remember the current configuration of your workspace under a simple name, you would make use of a snapshot:

  prjm -snapshot my-snapshot-name

This configuration could then be restored using the -get command of the project manager at any time.

There are a lot of more version control functions you can use to control the history of your projects. We will not enumerate them here and be content with the given examples; please have a look at the complete Elego ComPact Manuals.

Apply arbitrary commands to one, several, or all packages

The Elego ComPact project manager is a tool which applies actions to a set of packages. Some actions are pre-defined, but you may as well apply any other command to one, some, or all packages of a project.

  prjm -apply 'wc src/*.i3 src/*.m3'

will give you the character, word, and line number of the m3 files in the src directory of your packages. You could as well search for something or replace certain expressions using some standard POSIX tools:

  prjm -k -apply 'test -f src/m3overrides && 
       mv src/m3overrides src/m3overrides.bak && 
       sed -e 's/ROOT/TOP/g' src/m3overrides.bak > src/m3overrides'

This would change all the ROOT variables in the override files to TOP. The Elego ComPact command line tools fit nicely in the old paradigm of small tools that can be combined in various ways.