MKMF — User Commands
NAME
mkmf − generate Makefiles automatically
SYNOPSIS
mkmf [−f makefile] [−x] [−m machineType] [-mmachineType]
OPTIONS
−f makefile
Generate a file named makefile instead of Makefile. Also use makefile.proto, makefile.ed, and makefile.ex instead of Makefile.proto etc.
−xTurns on echo-ing so that all the commands in the mkmf scripts are printed on the terminal. This is useful primarily for debugging mkmf scripts.
−m machineType or -mmachineType
Work only on subdirectory for machineType. Multiple −m flags can be used to run mkmf on multiple machine types.
INTRODUCTION
Mkmf generates a Makefile for the current working directory. It also creates additional make-related files in machine-dependent subdirectories of the current directory. Mkmf can generate Makefiles for a variety of directories, including those holding programs, libraries, header libraries, kernel sources, and other things. mkmf manages all of the directories holding Sprite system code. In normal use, all you should have to do is type "mkmf"; mkmf will generate a suitable Makefile based on the directory’s full path name and the files and subdirectories in it. After that you can invoke pmake to recompile in the directory, install, and so on. The files produced by mkmf will only work with pmake, not with the original UNIX version of make (but in Sprite make is a symbolic link to pmake). This man page assumes that you are familiar with pmake; if not, you should read the pmake tutorial.
Warning: there is also a UNIX program called mkmf; although its general goal is the same as this program’s, its mechanisms are very different.
Normally, you should re-run mkmf in a directory whenever you add or delete source files. When mkmf runs, it assumes that all of the source files (those with extensions .c, .h, .y, etc.) are to be used to create a single program or library, and it generates Makefile accordingly. If there are source files that don’t pertain to the thing being created (e.g. test programs), put them in a subdirectory where mkmf won’t see them.
MAKEFILE STRUCTURE
The makefile structure that mkmf generates is a bit complicated, but it’s also powerful and flexible. Among other things, it supports compilation for multiple target machines from a single set of source files, and it makes it easy to make a global change in the way all directories of a particular type are made (e.g. all command programs, or all libraries). For most directories there are five kinds of pmake-related files:
Makefile
This is the main file generated by mkmf, but it is short and does relatively little. It sets up several pmake variables that give the name of the program, a list of target machines for which the program can be compiled, default flags for C compilation, and so on. Then Makefile includes the other files described below, which contain most of the useful pmake-related information. Makefile contains information that may be different for this directory than for other directories of the same type (for example, each library has a different name), but it only contains information that is independent of the particular target machine being compiled for.
∗.md/md.mk
There is one subdirectory for each target machine that this program or library or module can be compiled to run on. These are called machine-dependent subdirectories and have names x.md where x is the type of the target machine, e.g., sun2.md or sun3.md. A machine-dependent subdirectory holds all information that is different for that particular machine than for other machines. This includes the object files compiled for that machine, plus any machine-dependent sources. Most user programs don’t have machine-dependent sources, but many of the kernel modules and libraries do. In each machine-dependent subdirectory there is a file md.mk, generated automatically by mkmf. Md.mk is included by Makefile and creates variables like SRCS, OBJS, and HDRS. These describe the files needed to recompile for that target machine, including both the machine-independent files in the parent directory (the one containing Makefile) and the machine-dependent files in the x.md subdirectory.
∗.md/dependencies.mk
There is one of these files in each machine-dependent subdirectory. Dependencies.mk lists the header files used directly or indirectly by each source file. It is included by Makefile so that pmake will do the appropriate recompilations when headers change. Dependencies.mk files are generated automatically by makedepend. The command “pmake depend” will run makedepend to regenerate dependencies.mk. Mkmf also issues a “pmake depend” command whenever it runs.
sysmakefile
There only a few different kinds of source directories in Sprite: commands, libraries, kernel modules, etc (see “HOW MKMF WORKS” below). For each of these types of directories, there is one file of pmake commands that contains all of the “real stuff” that controls recompilation, installing, etc. Makefile sets the variable SYSMAKEFILE to hold the name of this file, and under normal conditions Makefile will include the sysmakefile whenever pmake is invoked (see “PERSONALIZATION” below for exceptions to this rule). The sysmakefiles use the variables and dependencies set up by Makefile, md.mk, and dependencies.mk. The sysmakefiles are all stored in /sprite/lib/pmake.
utility makefiles
There is a collection of small makefiles in the directory /sprite/lib/pmake, which are include by sysmakefiles for operations that are shared by many sysmakefiles.
STANDARD TARGETS
Several standard pmake targets are available in any directory managed by mkmf:
default If you type pmake with no arguments, then the default target just recompiles the program or library in this directory. Compiled files are placed in the .md subdirectory for the current target machine (see below for more information on target machines).
clean Remove any files that can be regenerated automatically by pmake. This frees up space on disk and forces a complete recompilation the next time pmake is invoked.
tidy Remove any files that can be regenerated automatically by pmake, except the executable produced for a command. This frees up space on disk and forces a complete recompilation the next time pmake is invoked, but it leaves around the unstripped executable for debugging purposes.
debug Valid for libraries only. Generate a version of the library with debugging symbols. The default for libraries is to compile without debugging information
depend Regenerate the dependencies.mk file in the .md subdirectory for the current target machine. This target should be re-made when source files are created or deleted, or when header file usage has changed.
install Recompiles the information in this directory and installs it in its official system location, so that it can be used by other people. For commands, this means copying the binary of the command to the appropriate system command directory and saving the old installed version of the command in a backup directory. For libraries, it means copying the library’s .a file to the relevant library directory, and also installing the library’s header files and lint library.
installdebug Valid for libraries only. Install the version of the library with debugging symbols.
installhdrs This target is only available in library and header directories. It installs the public header files for the module in the appropriate system header directory. Mkmf decides which header files are public and which are private based on the files’ names. In order to be public, the first letters of a .h file must be the same as the name of the directory, and the string Int must not appear in the file’s name. Thus, in the library sx the file sx.h is public, whereas the files sxInt.h and foo.h are treated as private.
installlint This target is only available in library directories. It generates a lint library file for the contents of this module and installs it in the system lint library.
installprofile This target is only available in library directories. It installs the version of the library that has been compiled for profiling.
lint Run lint on this program/library and the other programs and libraries it uses. Output is placed in the file lint in the .md subdirectory for the current machine.
mkmf Run mkmf to regenerate the Makefile for this directory. This target is particularly useful in top-level directories with many children, since it will run mkmf recursively in each of the subdirectories.
newtm Set things up to compile for a new type of target machine (which must be specified explicitly using the TM variable). This includes creating a .TM subdirectory and re-running mkmf.
profile Compile a profiled version of the command or library.
tags Generate a tags file in this directory that describes all the information in all of the source files for this program or library, including both the machine-independent sources and the machine-dependent sources for all target machines.
TARGET MACHINES
The above targets all apply to the “current target machine”, which is the value of the TM variable in Makefile. If you wish to compile for a different target machine, you can specify an explicit value of the TM variable on the pmake command line, such as
pmake TM=sun2
or
pmake install TM=sun3
There are also four other ways you can specify target machines as part of pmake targets:
tm If you specify a target machine as a pmake target, such as pmake sun2, then the default target will be made for that particular machine
all The all target causes the default target to be made for all target machines currently known for this directory.
target tm If you add a machine name as a suffix to one of the standard targets, e.g., pmake installsun2 or pmake lintsun3, the result is equivalent to specifying the TM variable: the target is re-made for the given machine instead of the default machine.
targetall If you add the all suffix to a target, e.g. pmake installall, then target will be re-made for all known target machines.
The list of known target machines is given by the MACHINES variable specified in Makefile. This variable is set from the names of .md subdirectories at the time mkmf is run. To add a new target machine, foo for example, create a subdirectory foo.md and then re-run mkmf.
ADDITIONAL PMAKE VARIABLES
There are a few variable names that mkmf reserves exclusively for your use, as a way of controlling various things. The makefiles generated by mkmf will use these variables, if you set them on a pmake command line:
NOBACKUP
Normally, when a command is installed the previous version of the command is saved in a backup directory. If you set the NOBACKUP variable to any value, then no backup copy will be saved.
BACKUPAGE
If NOBACKUP is not defined, then normally, a backup overwrites a previous backup only if the file being backed up is sufficiently old to be deemed stable (run update -help for information about the default age). BACKUPAGE, if set, overrides the default age used for this purpose.
XAFLAGS Extra flags that will be used in all assembler invocations, in addition to the standard ones set up by the makefiles.
XCFLAGS Extra flags that will be used in all C compilations, in addition to the standard ones set up by the makefiles.
In addition to the variables above, you can also override other variables defined in the makefiles. See "LOCAL.MK VARIABLES" below.
PERSONALIZATION
The makefiles generated by mkmf won’t always do the right thing without additional program-specific information. For example, a particular program may need to use additional libraries besides the C library, or it may need particular compiler switches, or certain files may need special processing during compilation. There are six ways to personalize the information in a particular directory, each of which is invoked by creating a file with a particular name:
kernel.mk This file can be used to create personalized Sprite kernels. Makefiles in kernel module directories will check for the existence of a kernel.mk file in your home directory. If the file exists it will be included prior to including any other files. The kernel.mk is intended modify the behavior of a sysmakefile for a kernel module, not to replace it. In this respect a kernel.mk file is different from a local.mk file.
local.mk This is the simplest and most common form of personalization. Makefile checks for the existence of local.mk; if it exists, then Makefile includes it instead of the sysmakefile. Usually local.mk contains a few pmake commands, then it includes the sysmakefile (whose name is passed in the variable SYSMAKEFILE), then it issues a few more pmake commands. See "LOCAL.MK EXAMPLES" below.
Makefile.sed If Makefile.sed exists when mkmf runs, then mkmf uses it as a Sed script to modify Makefile. If the −f switch has been used to specify a different makefile, say foo, then mkmf looks for foo.sed. In particular, you can place a file md.mk.sed in a machine-dependent subdirectory in order to modify the md.mk file. Most things that you can do with a Makefile.sed script you can also do in a local.mk file; this feature is mostly a leftover from ancient times when the local.mk facility didn’t exist.
Makefile.ex Similar to Makefile.sed, except mkmf uses it as an Ex script to modify Makefile.
Makefile.proto
If this file exists when mkmf runs, then mkmf uses it as a prototype makefile instead of one from the mkmf library. See “HOW MKMF WORKS” below for what this means.
mkmf.local If this file exists, it must be a shell script. It will be executed by mkmf in place of the standard type-specific mkmf script that would normally be executed to generate Makefile. See “HOW MKMF WORKS” below for more information on this.
Finally, there is one other, even more radical, way for you to control what’s in your Makefile, and that is to create your own Makefile from scratch and make sure it contains a line “# No mkmf”. Mkmf will refuse to do anything if it finds a Makefile with such a comment in it; you can then put anything you like in the Makefile. It’s probably a bad idea (and unnecessary) for you ever to generate a Makefile by hand in any Sprite system directory, but if you do, be sure it has a “# No mkmf” line: it is common practice to run mkmf indiscriminately on system directories, and this will make sure your Makefile doesn’t accidentally get overwritten (actually, mkmf won’t overwrite a makefile unless it finds a line “# Allow mkmf” in it, but if it doesn’t find a “# No mkmf” line then it will ask for permission to overwrite it).
HOW MKMF WORKS
The mkmf program runs as a two-stage shell script. The top-level script is the mkmf program itself. It does things that are common to all uses of mkmf, such as checking for the “# Allow mkmf” line in your Makefile and running pmake dependall. There are several second-level shell scripts, called type-specific scripts. Each one of these scripts is set up to handle a particular kind of directory, such as those for libraries, programs, or directories containing only header files. The type-specific scripts correspond to the sysmakefiles: for each type, there is an mkmf script to generate its Makefile, a prototype makefile that the script fills in, and a sysmakefile in /sprite/lib/pmake that does most of the real work for making things of that type. The type-specific scripts and prototype makefiles are all stored in /sprite/lib/mkmf with names like mkmf.library and Makefile.library.
Mkmf uses the file /sprite/lib/mkmf/mkmf.map to select which type-specific script to use. Mkmf.map is an awk script that performs pattern matching on the current directory to select a type-specific script. This file has already been set up to handle most of the system areas, but if you add a major new area of programs or libraries you’ll probably have to add a new entry in mkmf.map. If mkmf finds a script mkmf.local in the current directory, then mkmf uses it instead of the one that would have been selected by mkmf.map. Similarly, if there is a file Makefile.proto in the current directory, it is used instead of the default prototype makefile.
You can reconfigure the way that mkmf works by placing a file .mkmf in your home directory. If this file exists, mkmf will source it as a shell script just after doing its initialization. You can use this feature to set up a private map for yourself and change other internal features of mkmf. For more details on how this works, read the top-level mkmf script.
CURRENT TYPES
Although the list of available type-dependent scripts will probably grow and change faster than this man page can be updated, here are the types that were available as of the last time the man page was updated. To force mkmf to use a particular type (e.g., “library” instead of “command”), use either a mkmf.local or a Makefile.proto, as described in “HOW MKMF WORKS,” above.
command This type is for command directories where all of the files related to the command are together in a single directory and its .md subdirectories. It is the default type used by mkmf for directories not explicitly listed in mkmf.map. Makefile will compile and link the command into tm.md/name, where tm is the name of a target machine and name is the name of the directory containing Makefile (the directory name and command name are assumed to be the same). Makefile will install the command into the appropriate system directory (see the mkmf scripts for details on where this is). During the conversion of Sprite to the new C library, this type of directory is actually command2, but it will revert to command when the conversion is finished.
bigcmd This type is for commands whose source files have been partitioned into multiple subdirectories, with one Makefile for each subdirectory. The Makefiles in the subdirectories are of type bigcmd, and the Makefile of the parent is of type bigcmdtop. Each bigcmd subdirectory contains tm.md subdirectories, which contain object files compiled from that subdirectory plus a file linked.o, which consists of all the object files from that subdirectory linked together.
bigcmdtop This type is used for a command source directory that contains one or more subdirectories of type bigcmd. The Makefile in this directory will cause all the children directories to be re-made, plus it will regenerate the file tm.md/name, where tm is the name of a target machine and name is the name of the bigcmdtop directory. A special target quick is also available in bigcmdtop directories: it will relink tm.md/name using the existing linked.o files from the children, without passing through all the subdirectories to remake there.
library This type is for directories containing all of the files related to a particular library. Makefile will compile all the files in the directory and assemble them into an archive file named tm.md/libname.a, where tm is the name of a target machine and name is the name of the directory containing Makefile (the directory name and library name are assumed to be the same). Makefile will install the library and its headers and lint library.
biglib This type is for libraries with many source files, such as the C library. The library’s sources are assumed to be split over many subdirectories, with one Makefile for each subdirectory. The Makefiles in the subdirectories are of type biglib, and the Makefile of the parent is of type biglibtop. Compiled files will be archived together into the file ../tm.md/libname.a (relative to the subdirectories containing the biglib Makefiles), where tm is the name of a target machine and name is the name of the top-level directory (the directory containing the biglib directories is assumed to have the same name as the overall library).
bigligtop This is the type of a directory that contains one or more biglib subdirectories. The Makefile in this directory will pass most of the standard targets along to its children directories. The installation targets (such as install and installlint) should be invoked in this directory. A special target installquick is also available in biglibtop directories: it will install the standard version of the library without cycling through all of the subdirectories to give each of them a chance to recompile.
kernel This type is used in the directories that hold the major modules of the Sprite kernel.
hdrs This type is used for directories that hold nothing but “.h” files for the standard library. The only thing you can do with pmake is to install the header files; the default target does this, as does pmake install. In addition, pmake recursive will install header files in this directory and all of its subdirectories (this is only useful for header directories that contain more header directories as subdirectories).
top This is a general-purpose type for directories that don’t have anything interesting in themselves, but have child directories that do contain interesting things. When pmake is run in such a directory, the Makefile will simply pass all the standard targets down to each of its child directories in turn. This type of Makefile is used, for example, in the top-level directory of a biglib tree, or in a top-level commands directory, each of whose children is of type command.
LOCAL.MK VARIABLES
The following list describes some of the variables that you may wish to use, augment (using “+=”), or override in local.mk files. This is just a list of the most commonly-used variables. For other possibilities, read the makefiles.
AFLAGS Flags passed to the assembler. You may wish to augment this in local.mk.
CFLAGS Flags passed to the C compiler. You may wish to augment this in local.mk, for example to define certain compiler switches. Or, you can override the value in Makefile with something completely different.
CLEANOBJS A list of object files and other things to delete as part of pmake clean or pmake tidy.
HDRS A list of all the locally-defined “.h” files (both machine-dependent and machine-independent) used to compile this module.
INSTALLDIR The base directory in which a program gets installed. Mkmf will add a machine-dependent suffix onto this, depending on the particular machine being compiled for (see the makefiles for more details on this).
INSTALLFLAGS
Flags passed to update when the module is installed. You may wish to add extra flags, like −m 4755 to make a program set-user-id.
OBJS A list of all the object files used to link together this module. These files should always be in a machine-dependent directory.
SRCS A list of all the source files (both machine-dependent and machine-independent) that comprise the module’s version for the current target machine.
SUBDIRS A list of all the subdirectories of this directory, except those of type tm.md). Is usually only available in top-level Makefiles, like those in directories of type top, bigcmdtop, or biglibtop. This variable determines where to invoke recursive sub-makes.
TM The name of the current target machine. Normally this is specified on the command line or defaulted in Makefile, so you shouldn’t modify it.
LOCAL.MK EXAMPLES
The normal structure for a local.mk file is for it to set up or modify a few variables, include the sysmakefile, and then add new targets or extend targets defined by the sysmakefile. For example, here is a simple local.mk that defines some additional compiler variables (by adding to CFLAGS) and uses an extra library: CFLAGS += -DNAME=testProg LIBS += -lm -X11 #include <$(SYSMAKEFILE)>
Or, below is a local.mk that generates an additional C file from a template. Since the file may not have existed when mkmf was run, it must be added to the SRCS and OBJS variables generated by mkmf. In addition, when this program is installed (using the update command), it is marked at set-user-id (mode 4755): SRCS += auto.c OBJS += $(TM).md/auto.o INSTALLFLAGS += -m 4755
#include<$(SYSMAKEFILE)>
auto.c: template prog prog template > auto.c
The reason for adding new targets after including the sysmakefile is to allow the sysmakefile to define the first target, which is the default that will be made if pmake is invoked with no arguments. If, on the other hand, you want to change the default target, then you can define the default target before including the sysmakefile.
As a third example, consider a program that uses non-standard header files. It would have a local.mk that looks something like #include <$(SYSMAKEFILE)>
.PATH.h :/sprite/lib/include.special
Notice that the .PATH.h line comes after the sysmakefile is included.
SEE ALSO
pmake, sed, ex
KEYWORDS
make, Makefile, prototype
Sprite version 1.0 — May 23, 1991