Chapter 10. Tips and Traps

Table of Contents

1. Renaming Include Files
2. Symbolic Links
3. User Setup
3.1. The .cshrc or .profile files
3.2. The AEGIS_PATH environment variable
3.3. The .aegisrc file
3.4. The defaulting mechanism
4. The Project Owner
5. USENET Publication Standards
5.1. CHANGES
5.2. MANIFEST
5.3. Makefile
5.4. patchlevel.h
5.5. Building Patch Files
6. Heterogeneous Development
6.1. Project Configuration File
6.2. Change Attribute
6.3. Network Files
6.4. DMT Implications
6.5. Test Implications
6.6. Cross Compiling
6.7. File Version by Architecture
7. Reminders
7.1. Awaiting Development
7.2. Being Developed
7.3. Being Reviewed
7.4. Awaiting Integration

This chapter contains hints for how to use the aegis program more efficiently and documents a number of pitfalls you may encounter.

This chapter is at present very "ad hoc" with no particular ordering. Fortunately, it is, as yet, rather small. The final size of this chapter is expected to be quite large.

1. Renaming Include Files

Renaming include files can be a disaster, either finding all of the clients, or making sure the new copy is used rather than the old copy still in the baseline.

Aegis provides some assistance. When the aemv command is used, a file in the development directory is created in the old location, filled with garbage. Compiles will fail very diagnostically, and you can change the reference in the source file, probably after aecp(1)ing it first.

If you are moving an include file from one directory to another, but leaving the basename unchanged, create a link[21] between the new and old names, but only in the development directory (i.e. replacing the "garbage" file aegis created for you). Create the link after aemv(1) has succeeded. This insulates you from a number of nasty Catch-22 situations in writing the dependency maintenance tool's rules file.

2. Symbolic Links

If you are on a flavor of Unix™ which has symbolic links, it is often useful to create a symbolic link from the development directory to the baseline. This can make browsing the baseline very simple.

Assuming that the project and change defaults are appropriate, the following command

ln -s `aegis -cd -bl` bl

is all that is required to create a symbolic link called bl pointing to the baseline. Note that the aecd alias is inappropriate in this case.

This can be done automatically for every change, by placing the line

develop_begin_command =
	"ln -s $baseline bl";

into the project configuration file.

3. User Setup

There are a number of things which users of aegis can do to make it more useful, or more user friendly. This section describes just a few of them.

3.1. The .cshrc or .profile files

The aliases for the various user commands used throughout this manual are obtained by appending a line of the form

. /opt/aegis/share/profile

to the .profile file in the user's home directory, if they use the sh(1) shell or the bash(1) shell.

If the user uses the csh(1) shell, append a line of the form

source /opt/aegis/share/cshrc

to the .cshrc file in the user's home directory.

These days, many systems also provide an /etc/profile.d directory, which has symbolic links to the start-up scripts for various packages. These are run automatically for all users. If your system has such a thing, arrange for symbolic links

ln -s /opt/aegis/share/profile \
	/etc/profile.d/aegis.sh
ln -s /opt/aegis/share/cshrc \
	/etc/profile.d/aegis.csh

and you will not need to edit every user's .cshrc or .profile file.

3.2. The AEGIS_PATH environment variable

If users wish to use aegis for their own projects, in addition to the "system" projects, the AEGIS_PATH environment variable forms a colon separated search path of aegis "library" directories. The /opt/aegis/lib directory is always implicitly added to this list.

The user should not create this library directory, but let aegis do this for itself (otherwise you will get an error message).

The AEGIS_PATH environment variable should be set in the .cshrc or .profile files in the user's home directory. Typical setting is

setenv AEGIS_PATH ~/lib/aegis

and this is the default used in the /opt/aegis/share/cshrc file.

3.3. The .aegisrc file

The .aegisrc file in the user's home directory contains a number of useful fields. See aeuconf for more information.

3.4. The defaulting mechanism

In order for you to specify the minimum possible information on the command line, aegis has been designed to work most of it out itself.

The default project is the project which you are working on changes for, if there is only one, otherwise it is gleaned from the .aegisrc file. The command line overrides any default.

The default change is the one you are working on within the (default or specified) project, if there is only one. The command line overrides any default.

4. The Project Owner

For the greatest protection from accidental change, it is best if the project is owned by a Unix™ account which is none of the staff. This account is often named the same as the project, or sometimes there is a single umbrella account for all projects.

When an aegis project is created, the owner is the user creating the project, and the group is the user's default group. The creating user is installed as the project's first administrator.

A new project administrator should be created - an actual user account. The Unix™ password should then be disabled on the project account - it will never be necessary to use it again.[22]

The user nominated as project administrator many then assign all of the other staff roles. Aegis takes care of ensuring that the baseline is owned by the project account, not any of the other staff, while development directories always belong to the developer (but the group will always be the project group, irrespective of the developer's default group).

All of the staff working on a project should be members of the project's group, to be able to browse the baseline, for reviewers to be able to review changes. This use of Unix™ groups means that projects may be as secure or open as desired.

5. USENET Publication Standards

If you are writing software to publish on USENET, a number of the source newsgroups have publication standards. This section describes ways of generating the following files, required by many of the newsgroups' moderators:

MANIFESTList of files in the distribution.
MakefileHow to build the distribution.
CHANGESWhat happened for this distribution.
patchlevel.hAn identification of this distribution.

Each of these files may be generated from information known to aegis, with the aid of some fairly simple shell scripts.

5.1. CHANGES

Write this section.

Look in the aux/CHANGES.sh file included in the aegis distribution for an example of one way to do this.

5.2. MANIFEST

Write this section.

Look in the aux/MANIFEST.sh and aux/MANIFEST.awk files included in the aegis distribution for an example of one way to do this.

5.3. Makefile

Write this section.

Look in the aux/Makefile.sh and aux/Makefile.awk files included in the aegis distribution for an example of one way to do this.

5.4. patchlevel.h

Write this section.

Look in the aux/Howto.cook file included in the aegis distribution for an example of one way to do this.

5.5. Building Patch Files

The patch program by Larry Wall is one of the enduring marvels of USENET. This section describes how to build input files for this miracle program.

Write this section.

Look in the aux/patches.sh file included in the aegis distribution for an example of one way to do this.

6. Heterogeneous Development

The aegis program has support for heterogeneous development. It will enforce that each change be built and tested on each of a list of architectures. It determines which architecture it is currently executing on by using the uname(2) system call.

The uname(2) system call can yield uneven results, depending on the operating systems vendor's interpretation of what it should return.[23] To cope with this, each required architecture for a project is specified as a name and a pattern.

The name is used by aegis internally, and is also available in the ${ARCHitecture} substitution (see aesub(5) for more information).

The patterns are simple shell file name patterns (see sh(1) for more information) matched against the output of the uname(2) system call.

The result of uname(2) has four fields of interest: sysname, release, version and machine. These are stitched together with hyphens to form an architecture variant to be matched by the pattern.

For example, a system the author commonly uses is "SunOS-4.1.3-8-sun4m" which matches the "SunOS-4.1*-*-sun4*" pattern. A solaris system, a very different beast, matches the "SunOS-5.*-*-sun4*" pattern. Sun's 386 version of Solaris matches the "SunOS-5.*-*-i86pc" pattern. A convex system matches the "ConvexOS-*-10.*-convex" pattern.

6.1. Project Configuration File

To require a project to build and test on each of these architectures, the architecture field of the project aegis.conf file is set. See aepconf(5) for more details on this file. The above examples of architectures could be represented as

architecture =
[
  {
    name = "sun4";
    pattern = "SunOS-4.1*-*-sun4*";
  },
  {
    name = "sun5";
    pattern = "SunOS-5.*-*-sun4*";
  },

  {
    name = "sun5pc";
    pattern = "SunOS-5.*-*-i86pc";
  },
  {
    name = "convex";
    pattern = "ConvexOS-*-10.*-*";
  }
];

This would require that all changes build and test on each of the "sun4", "sun5", "sun5pc" and "convex" architectures.

It is also possible to have optional architectures. This may be used to recognise an environment, but not mandate that it be built every time.

  {
    name = "solaris-8-sparc";
    pattern = "SunOS-5.8*-*-sun4*";
    mode = optional;
  },

However, once an architecture name appears in a change's architecture list, it is mandatory for that change.

If the architecture field does not appear in the project aegis.conf file, it defaults to

architecture =
[
  {
    name = "unspecified";
    pattern = "*";
  }
];

Setting the architectures is usually done as part of the first change of a project, but it also may be done to existing projects. This information is kept in the project aegis.conf file, rather than as a project attribute, because it requires that the DMT configuration file and the tests have corresponding details (see below).

The lib/config.example/architecture file in the Aegis distribution contains many architecture variations, so that you may readily insert them into your project configuration file.

6.2. Change Attribute

The architecture attribute is inherited by each new change. A project administrator may subsequently edit the change attributes to grant exemptions for specific architectures. See aeca(1) for how to do this.

A build must be successfully performed on each of the target architectures. Similarly, the tests must be performed successfully on each. These requirements are because there is often conditional code present to cope with the vagaries of each architecture, and this needs to be compiled and tested in each case.

This multiple build and test requirement includes both development and integration states of each change.

6.3. Network Files

This method of heterogeneous development assumes that the baseline and development directories are available as the same pathname in all target architectures. With software such as NFS, this does not present a great problem, however NFS locking must also work.

There is also an assumption that all the hosts remotely mounting NFS file systems will agree on the time, because aegis uses time stamps to record that various tasks have been performed. Software such as timed(8) is required.[24]

6.4. DMT Implications

This method of heterogeneous development assumes that the baseline will have a copy of all object files for all target architectures simultaneously.

This means that the configuration file for the DMT will need to distinguish all the variations of the object files in some way. The easiest method is to have a separate object tree for each architecture.[25] To facilitate this, there is an ${ARCHitecture} substitution available, which may then be passed to the DMT using the build_command field of the project aegis.conf file.

The architecture name used by aegis needs to be used by the DMT, so that both aegis and the DMT can agree on which architecture is currently targeted.

6.4.1. Cook Example

As and example of how to do this, the cook recipes from the DMT chapter are modified as appropriate. First, the build_command field of the project aegis.conf file is changed to include the ${ARCHitecture} substitution:

build_command =
  "cook -b ${s Howto.cook} \
  project=$p change=$c \
  version=$v arch='$arch' -nl";

Second, the C recipe must be changed to include the architecture in the path of the result:

[arch]/%.o: %.c: [collect c_incl
  -eia [prepost "-I" ""
  [search_list]] [resolve %.c]]
{
  if [not [exists [arch]]] then
    mkdir [arch]
      set clearstat;
  if [exists [target]] then
    rm [target]
      set clearstat;
  [cc] [cc_flags] [prepost "-I"
    "" [search_list]] -c
    [resolve %.c];
  mv %.o [target];
}

Third, the link recipe must be changed to include the architecture in the name of the result:

[arch]/example: [object_files]
{
  if [not [exists [arch]]] then
    mkdir [arch]
      set clearstat;
  if [exists [target]] then
    rm [target]
      set clearstat;
  [cc] -o [target] [resolve
    [object_files]] -ly -ll;
}

The method used to determine the object_files variable is the same as before, but the object file names now include the architecture:

object_files =
  [fromto %.y [arch]/%.o
    [match_mask %.y [source_files]]]
  [fromto %.l [arch]/%.o
    [match_mask %.l [source_files]]]
  [fromto %.c [arch]/%.o
    [match_mask %.c [source_files]]]
  ;

Note that the form of these recipes precludes performing a build in each target architecture simultaneously, because intermediate files in the recipes may clash. However, aegis prevents simultaneous build, for this and other reasons.

6.5. Test Implications

Tests will need to know in which directory the relevant binary files reside. The test_command field of the project aegis.conf file may be changed from the default

test_command =
  "$shell $file_name";

to pass the architecture name to the test

test_command =
  "$shell $file_name $arch";

This will make the architecture name available as $1 within the shell script. Tests should fail elegantly when the architecture name is not given, or should assume a sensible default.

6.6. Cross Compiling

If you are cross compiling to a number of different target architectures, you would not use aegis' heterogeneous development support, since it depends on the uname(2) system call, which would tell it nothing useful when cross compiling. In this case, simply write the DMT configuration file to cross compile to all architectures in every build.

6.7. File Version by Architecture

There is no intention of ever providing the facility where a project source file may have different versions depending on the architecture, but all of these versions overload the same file name.[26]

The same effect may be achieved by naming files by architecture, and using the DMT to compile and link those files in the appropriate architecture.

This has the advantage of making it clear that several variations of a file exist, one for each architecture, rather than hiding several related but independent source files behind the one file name.

7. Reminders

This section documents some scripts available for reminding users of changes which require their attention. These scripts are installed into the /opt/aegis/share/remind directory, and may be run by cron(8) at appropriate intervals. You will almost certainly want to customize them for your site.

7.1. Awaiting Development

The /opt/aegis/share/remind/awt_dvlp.sh script takes a project name as argument. It is placed in the project leader's per-user crontab. It is suggested that this script be run weekly, at 8AM on Monday. This script will send all developers of the named project email if there are any changes in the awaiting development state in the named project. No mail is sent if there are no changes outstanding.

7.2. Being Developed

The /opt/aegis/share/remind/bng_dvlpd.sh script takes no arguments. It is placed in each user's per-user crontab. It is suggested that this script be run weekly, at 8AM on Monday. This script takes no arguments, and sends email to the user if they have any changes in the being developed or being integrated states. No mail is sent if there are no changes outstanding.

7.3. Being Reviewed

The /opt/aegis/share/remind/bng_rvwd.sh script takes a project name as argument. It is placed in the project leader's per-user crontab. It is suggested that this script be run daily at 8AM. This script will send all reviewers of the named project email if there are any changes in the being reviewed state in the named project. No mail is sent if there are no changes outstanding.

7.4. Awaiting Integration

The /opt/aegis/share/remind/awt_intgrtn.sh script takes a project name as argument. It is placed in the project leader's per-user crontab. It is suggested that this script be run daily at 8AM. This script will send all integrators of the named project email if there are any changes in the awaiting integration state in the named project. No mail is sent if there are no changes outstanding.



[21] A hard link uses fewer disk blocks. Symbolic links survive the subject file being deleted and recreated.

[22] Unless bugs in aegis corrupt the database, in which case repairs can be accomplished as the project account using a text editor.

[23] For example, SCO 3.2 returns the nodename in the sysname field, when it should place "SCO" there; Convex and Pyramid scramble it even worse.

[24] Some sites manage by running rdate(8) from cron(8) every 15 minutes.

[25] A tree the same shape as the source tree makes navigation easier, and users need not think of file names unique across all directories.

[26] Some other SCM tools provide a repository with this facility.