AdaMakeGen generates a Makefile based on the dependencies of a set of Ada source files.

To use the adamakegen

To create a Makefile that will compile all of the source code in directory1, directory2 and directory3, type:
     adamakegen directory1 directory2 directory3 
The given directories are the "active" directories. Any directories other than an active directory that an active directory depends on is a "passive" directory. AdaMakeGen will scan all of the Ada source code in both the active and passive directories and generate a Makefile that compiles the files in the active directories when they are out of date. During execution, Adamakegen will print the active and passive directories. The passive directories may have some informational letters before them:

A few varieties of parameters are recognized:

    -nNICK=/stuff/blah
    -NNICK=/other/stuff
    -e/junk1
    -i/junk2
    -ljunk3
    -r
    -fMakefile.sparc
-n creates a nickname in the Makefile so that the Makefiles can be moved more easily. In the example above, any dependence starting /stuff/blah/other would be replaced by $(NICK)/other.

-N creates a nickname that is used in the Makefile, but is never defined. This is useful if the user wants to define the value of the nickname in the user section or an included configuration file.

-e excludes the given directory (and everything below it) from being the target of dependencies in the Makefile, but the directory is still scanned for compilation units (and will warn about missing units).

-i ignores the given directory (and everything below it) so it won't be included in the list of passive directories. The user will be warned that any units from this directory are missing.

-l removes the given name (if present) from any directory name when adamakegen is looking for source code. If the ada libraries are placed in whatever/SUN4, executing "adamakegen dir1/SUN4 dir2/SUN4 -lSUN4" will use the ada libraries in dir1/SUN4 and dir2/SUN4, but the source code in dir1 and dir2. This also applies to all passive directories.

-r creates a Makefile that is relative to the current working directory. The default is to use complete path names for all files, but this option tells Adamakegen to use relative names for files below the current directory.

-f tells adamakegen to name the makefile the given name instead of Makefile. This allows users to choose the name of the Makefile. One potential use is to generate Imakefiles instead of Makefiles.

All of the options can be passed either on the command line or placed in an .adamakegenrc file. Options placed in the control file, should be given one per a line with no embedded spaces. Comments in the control file should be on their own line and proceeded with "--". The search path for the control file is (Only the first control file found is used.):

  1. Current directory
  2. User's home directory
If there is a control file in the standard library, it is also read in addition to any others.

This will generate 2 files (even if they already exist):

Once you have the Makefile, you use make to compile your system. For example:
     make                     -- compiles everything
     make depend              -- re-runs adamakegen with the same parameters
     make createlib           -- builds the libraries with a.path information
     make cleanlib            -- removes all of the .obj's and a.cleanlib
     make veryclean           -- removes all of the library directories
     make /path/.obj/test.obj -- compiles test.a and everything it depends on.

Adding Commands to the Makefiles

AdaMakeGen modifies the Makefile between two marker lines. Users should place any commands for make above or below these lines. The marker lines are:
# DO NOT DELETE THIS LINE -- Ada Make Gen commands are below this line.
# DO NOT DELETE THIS LINE -- Place user commands below this line.

Adding Link Commands

One typical command for the user section is to link the system into an executable with a command such as:
all: $(AMGROOT)/bin/prodag

$(AMGROOT)/bin/prodag: $(ROOTS) $(EXTLIBS)
        cd $(AMGROOT)/bin ; \
        a.ld prodag -o prodag

Adding C commands

AdaMakeGen is also compatible with makedepend for C programs. Makedepend will place its own marker in the makefile and modify below that point. So the Makefile will look like: The *'ed sections are optional. The user should not modify the Adamakegen section because the changes will not be maintained when Adamakegen is re-executed.

Portability of Makefiles

Adamakegen defines several Makefile variables to allow them to be modified easily for different systems. For example, directory nicknames are user-defined Makefile variables that allow the generated Makefiles to be used on different systems. Variables are placed in the User Header Section and thus may be modified and preserved between adamakegen invocations. The currently defined variables are:
ADAMAKEGEN      The command to execute adamakegen
DEPENDCMDS      A hook to perform additional commands after adamakegen

ADA             The command for the Ada compiler
AFLAGS          Flags to pass to the Ada compiler

ERRORTEST1,     The two halves of the command to determine whether a
ERRORTEST2              compilation was successful.

MAKELIB         The command to make an Ada library
ADDLIB          The command to add a directory to an Ada library
CLEANLIB        The command to empty out an Ada library
RMLIB           The command to remove an Ada library
FIXLIB          The command to "normalize" an Ada directory
Additional portability is gained if the user defines nicknames (-n and -N) for the libraries that are used by the project. This allows installers to change the definition of the nickname at the top of the Makefile and not through out the Makefile.

Current Limitations

  1. AdaMakeGen assumes that each file in the list of directories ending in ".a" is a valid Ada compilation unit. In particular, C libraries of the form libStuff.a are prohibited.
  2. AdaMakeGen assumes that there is only one instance of each compilation unit name in each directory. If there is more than one, then it picks one arbitrarily (for units depending on it) and warns the user.
  3. AdaMakeGen is dependent on the Verdix/SunAda compiler's format for ada.lib to find the path to search for other Ada directories.
  4. Although AdaMakeGen support loops in the Ada paths, the Verdix/SunAda compiler is iffy on them. I would avoid them if at all possible.
  5. Strings surrounded by %'s are not supported (Ada's alternative string format.)

Hints and Troubleshooting

  1. AdaMakeGen will use the adamakegen.log files for the passive directories if they are available. Since this is much faster than rescanning the source code, it is best to run adamakegen on the libraries first and then the directories that depend on them.
  2. Place new rules or dependencies below the Adamakegen section instead of above it so that the symbols for the nicknames and ROOTS are defined.
  3. For compiling under Verdix/SunAda it is often convenient for the Makefile to ignore warnings, but stop on an error. There are two approaches that may be used:
    1. Add -w to the AFLAGS variable to suppress all warnings
    2. Change the ERRORTEST variables to:
                
      ERRORTEST1 = test `grep error
      ERRORTEST2 = 2 > /dev/null | wc -l` -eq 0
      
    The first is easier, but the user is not given any warnings. The second option prints the warnings to the screen and saves them in the file file.err, but they do not interrupt the progress of the Makefile.
  4. Make every link target depend on $(EXTLIBS), which is a symbol for all of the passive directories' ada.lib files. This will ensure that if package bodies in a library are recompiled, your system will also be relinked, even if nothing is recompiled.
  5. The current verson of Icon (8.7) occasionally puts corrupted strings (notably \0) in to large Makefiles. To work around the problem, "setenv STRSIZE 5000000"
  6. It is not necessary to run adamakegen on one of the machines with an Ada compiler.
  7. If you are installing adamakegen on a different system, run adamakegen over the system directory and put the log somewhere world readable. Then change the part of the code that looks in my directory.

Top: Owen O'Malley