RCS Makefiles and Directory Structure

Using generic.def and Other Programmer's Tools


Introduction

Makefiles are files that provide rules for compiling a particular application, which are applied by programs such as GNU Make. Usually these rules are written for a specific application and for a particular platform. generic.def (formerly called Makefile.generic) is a make definitions file that provides additional rules that are not application specific that are then included in application makefiles to provide these features:
  1. Allow the application to be easily compiled for multiple platforms.
  2. Provide each programmer with ability to develop and test modifications to the application without affecting other programmers working on the application or users.
  3. Allow information about the compilers and libraries available at a given site for each platform to be centralized.
  4. Allow programmer's to more easily generate and use automatically generated dependency rules for header files.
  5. Add's the directory for the RCS Library header files to the compiler's include path.
In order for generic.def to work applications need to follow a particular directory structure, set certain Makefile variables, and follow some conventions for filenames. It is compatible with GNU Make but is not compatible with some other make utilities like Microsoft's NMAKE.

Directory Structure

Each application is expected to select one main application directory and to mirror the directory tree under this directory for each programmer working on the application. This allows each programmer to change the source code, re-compile and test those changes in a private workspace before releasing the changes to be used by the rest of the organization. The main application release directory should contain the directory tree shown in the Directory Tree Table. Each programmer's copy follows the same structure except that the SCCS directories are replaced with symbolic links to the corresponding SCCS directory under the main application directory.

The Application Include Makefile

It is recommended that each application create a short makefile to include some definitions to be used by makefiles throughout the application. This file should be a very convenient place to include generic.def and to define the APPDIR variable which generic.def will use. APPDIR should be set to the full path to the main application directory. This may also be a good place to set LOCAL_CFLAGS or other variables used by generic.def. The following is an example file that will be called "Makefile.app" in later examples:

#  Application Include Makefile for the application called `app'.

# Add some C and C++ compilation flags for our application. ]
#  (-g -- include debugging info, -pg -- include profiling support for gprof)
LOCAL_CFLAGS = -g -pg

# Define APPDIR
APPDIR = /home/manta/app

# Include the generic Makefile definitions
include /home/manta/rcslib/etc/generic.def

(To follow the Enhanced Machine Controller(EMC) convention, Makefile.app should be placed in the top-level directory.)

The Top-Level Makefile

The primary purpose of the top-level makefile is to provide a convenient way to call for a make of the appropriate target(s) in each subdirectory. There are several targets of importance in generic.def that can easily be passed to the subdirectories as the following example shows:

# Top-Level Makefile for the application called `app'.

# Include the Application Include Makefile
include Makefile.app

# To build any of these phony targets go to each subdirectory and run make.
clean depend install all headers sources:
	(cd src/sub_directory1; $(MAKE) -k $@)
	(cd src/sub_directory2; $(MAKE) -k $@)
	(cd src/sub_directory3; $(MAKE) -k $@)

Subdirectory Makefiles

Each source subdirectory should have its own Makefile. Within this makefile programmers will need to define several variables, include the application include makefile, and provide rules for linking any binaries or libraries together. The following example can be used as a template:
# Makefile for sub_directory1 of the application called `app'.

# Set the variables required by generic.def
SOURCES = example1.cc example2.cc example3.cc
OBJS = example1.o example2.o example3.o
LIBS = 

ifeq (vxworks,$(findstring vxworks,$(PLAT)))
BINS = 
else
BINS = example_bin
endif

# Include the Application Include Makefile
include ../../Makefile.app

# Create rules to link together specific binaries.
$(DEVP_PLAT_BIN)/example_bin: \	
	$(DEVP_PLAT_LIB)/example1.o \
	$(DEVP_PLAT_LIB)/example2.o \
	$(DEVP_PLAT_LIB)/example1.o
	($(COMPILER_SETUP); \
	$(CPLUSPLUS) $(CFLAGS) $(CPLUSPLUSFLAGS) $(CLINK) $(CPLUSPLUSLINK) $^ -o $@;)

Variables used in generic.def

Several variables are used within generic.def to control how your application is built. Other variables are set by generic.def or within one of the platform specific makefiles (of the form $(PLAT).def such as Makefile.vxworksCC or Makefile.sunos4) to aid in the development of rules for specific binaries and libraries. In the table below the "Where Set?" column provides recommended locations for setting each variable, unless the location is $(PLAT).def or generic.def in which case the variable must be set there and should not be set anywhere else. The platform specific makefiles are automatically included by generic.def so there is no need to include them directly from application makefiles.

VARIABLE Where Set? Meaning
APPDIR Application Include Makefile Specifies the main application directory, which is used in the INCLUDE path and for performing an install when the application is ready to be released.
AR $(PLAT).def Provides the name and path of the library archiver for the given platform. (See the ar manpage.)
BINS Subdirectory Makefile Lists the executable binary files that should be created by running make in this subdirectory. Binaries will need to have a separate rule at the end of the makefile.
CC $(PLAT).def Provides the name and path of the C compiler for the given platform.
CPLUSPLUS $(PLAT).def Provides the name and path of the C++ compiler for the given platform.
COMPILER_SETUP $(PLAT).def Provides the command(s) required to setup the environment so the compiler and related tools can be used. It should be used at the beginning of commands in rules for specific binaries and libraries.
DEVP_PLAT_BIN generic.def Provides the name of the directory where executable binary files should land within the programmer's workspace. It should be used to provide rules for specific binaries.
DEVP_PLAT_LIB generic.def Provides the name of the directory where object files and libraries should land within the programmer's workspace. It should be used to provide rules for specific binaries and libraries.
HEADERS Subdirectory Makefile Lists the header files found in this directory that should be copied to the platform include directory so that they may be used from other directories or by other programmers.
LIBS Subdirectory Makefile Lists the library files that should be created by running make in this subdirectory. Libraries will need to have a separate rule at the end of the makefile.
LOCAL_CFLAGS Application Include Makefile Lists options that will be passed to the C or C++ compiler.
LOCAL_CPLUSPLUSFLAGS Application Include Makefile Lists options that will be passed to the C++ compiler. (not to a C compiler)
OBJS Subdirectory Makefile Lists the object files that should be compiled by running make in this subdirectory.
PLAT Command Line Specifies which platform to compile for. It is normally set on the command line so that programmers can easily switch between multiple compilers and cross-compilers. It defaults to the value of the osrev environment variable.
RANLIB $(PLAT).def Provides the name and path of the ranlib utility for the given platform if one exists and is required, otherwise the variable contains some command that should have no effect. The ranlib utility converts archives to random libraries. (See the ranlib manpage.)
RCS_INCLUDE generic.def Provides the directory where header files for the RCS library are placed.
RCS_LIBRARY generic.def Provides the name and path of the RCS Library for the platform set with PLAT.
RCS_PLATLIB generic.def Provides the path to the RCS Library for the platform set with PLAT. This is also the location of the pmac and pcio libraries if they exist for the platform.
SOURCES Subdirectory Makefile Lists the C and C++ files used from that subdirectory. C files should have the .c extension and C++ files should have the .cc extension. Thie list is used for creating automatic dependency lists and for storing archives of the source code during an install. Do not list header files here.
USER_DIR Programmer's Environment, Application Include Makefile, or command line Specifies the top-level directory in the programmer's workspace. It defaults to the name of the application under the programmer's home directory. It is recommended that the applications be set up so that the default can be used and USER_DIR need not be set.
For example: If APPDIR=/home/manta/emc and the programmer's login name was "shackle" then the workspace should be placed in ~shackle/emc to match the default.

Special Targets

generic.def provides rules for creating several PHONY targets. By specifying one of these targets on the command line, the programmer can have several useful tasks performed.
Target Name Purpose
all Update everything within the programmer's workspace, including copying header files to the include directory, compiling, linking and archiving as necessary.
clean Deletes object files and programs from the programmer's workspace. This is useful for example when a change in compiler options would not take effect unless the entire application is rebuilt.
depend Generate lists of dependencies so that files will be recompiled whenever a header file they include directly or indirectly has changed (uses the makedepend utility).
headers Copies the header files to the src and include subdirectory of the current platform directory. For Windows and DOS platforms the files are also converted with unix2dos.
install Copy all the source, header, object files, libraries and programs from the programmer's workspace to the main application release the main application directory.
sources Copies the source and header files to the src and include subdirectories of the current platform directory. For Windows and DOS platforms the files are also converted with unix2dos and the .cc extension is replaced with .cpp.

Terminology

Platform
Each platform specifies a particular compiler, CPU type, operating system and sometimes certain compiler options, such as whether to compile a Windows program as a 16 or 32 bit application. For each platform there will be a subdirectory in both the programmer's workspace directory and in the application release directory. The PLAT variable should be set the name of this subdirectory. The Platforms Tested Table for the RCS Library also lists the names of the platforms as used by generic.def.
WorkSpace
Each programmer will have a separate workspace directory which mirrors the main application directory except that the SCCS directories are replaced with symbolic links to their counterparts in the main application directory.

Last Modified: 04/02/98

If you have questions or comments regarding this page or you would like to be notified of changes to the RCS library via email, please contact Will Shackleford at shackle@cme.nist.gov