UPS/UPD Doc Home page | Computing Division| Fermilab at Work | Fermilab Home
View/print PDF file
Fermilab CD logo Complete Guide and Reference Manual for UPS, UPD and UPP v4

Chapter Contents

Chapter 16: UPS Product Development: General Considerations
  16.1 Product Development Considerations and Recommendations
    16.1.1 All Products (Locally Developed and Third Party)
    16.1.2 Products that You Develop
    16.1.3 Third-Party Products Requiring a Hard-Coded Path
  16.2 Tools for Developing and/or Packaging Products
    16.2.1 Buildmanager
    16.2.2 CVS
    16.2.3 Template_product
  16.3 Directory Structure for a UPS Product Instance

Chapter 16: UPS Product Development: General Considerations

This chapter discusses the UPS product development methodology and tools that can be used in product development. It also provides recommendations for organizing your local product development area and the individual product root directories you will need to create.

16.1 Product Development Considerations and Recommendations

In this section we will provide some guidelines for product development as it affects the product's inclusion in the UPS framework.

Simple scripts which run on any architecture are naturally quite straightforward to implement under UPS. Products which are obtained from the outside world (third party) as executable images with no source code are also generally straightforward. The ones that get complicated are the products which must be compiled and/or otherwise built for each and every supported architecture.

16.1.1 All Products (Locally Developed and Third Party)

Shell Independence

The product should run the same way under both shell families, sh and csh. If the product requires any actions to take place before it will run (e.g., its bin directory added to your $PATH, some environment variables set), provide a table file containing these actions. The UPS environment is described in Chapter 2: Overview of UPS, UPD and UPP v4 and table files in Chapter 36: Table Files. The functions supported in table files are designed to work in a shell-independent manner, in general.

Flavor Declaration in UPS

On your development system, we recommend that you declare your products according to the fully specified flavor of the machine on which you build them (or on which they were built). We consider this to be very important, especially if your target systems contain or will ever contain mixed OS releases (e.g., IRIX+6.2 and IRIX+6.5). This will help to avoid problems when a new OS release doesn't run images built on an older one, or vice-versa. You don't want to have to go back and comb out which OS release a particular product instance was built for, you want to be able to tell immediately from looking at the database. Installers and users also need this information to facilitate their database maintenance.

Products which have no flavor-dependence at all (shell scripts, for instance), should be declared as NULL to the database (use the "zero" option, -0; see Chapter 25: Generic Command Option Descriptions). For other products, include the entire flavor string of the build platform in the declaration, or the major portion of that string. For example, if you build on an OSF1 machine running V3.2, declare your products with the flavor OSF1+V3.2 or OSF1+V3 rather than just OSF1 (e.g., use the flavor level corresponding to the options -3 or -2 rather than -1)

Policy Regarding Use of /usr/local/bin

Outside Fermilab, in the UNIX world at large, products typically get put in /usr/local/bin. With this in the user's $PATH, all the products are accessible. This practice is inconsistent with the goal of UPS to provide concurrent versions of products. Therefore only products specially approved by the FUE working group may write into /usr/local/bin. No other products should write to this area, or to any other area within /usr/local.

16.1.2 Products that You Develop

If you're writing your own product for implementation within UPS, you have the luxury (and, we might add, the responsibility) of creating it such that it exploits the important features of UPS, thus making it easy for the user to install and run, and easy for you or another developer to maintain in the future. We urge you to follow the guidelines we present here.

Self-Containment and Location Determination

First, design the product such that it is self-contained. It should identify its location and the location of any required files at run time (as opposed to compile time). You as the product developer have total control over the structure and contents of the product root directory, but no control at all over where the product root directory will reside on a target system.

If you write the product such that it calculates its location at compile time, you'll be putting the hard-coded path to your development environment into the image -- most likely not the correct path on the user machine.

You can choose to define the environment variable $<PRODUCT>_DIR, which points to the product root directory. In UPS v4, this variable is no longer always necessary since much of its usefulness is taken over by the local read-only variable ${UPS_PROD_DIR}, described in section 35.6 Local Read-Only Variables Available to Functions. However, users will still find $<PRODUCT>_DIR to be useful since they will have access to it as long as the product is setup.

As an example of the use of ${UPS_PROD_DIR}, take myproduct written in perl which requires the file lib/ You should refer to this file in the perl code as $ENV::{MYPROD_PERL_LIB}/ rather than by its full path, e.g., /path/to/lib/ In the table file, set MYPROD_PERL_LIB to ${UPS_PROD_DIR}/lib. You should make no assumptions about where users will put the file.

As stated above, products should not use or copy files into the areas under /usr/local.

Reproducible Build Procedure

All products should be built using a build script in order to ensure that the build procedure is reproducible. If your product is at all complex, we recommend that you use Makefiles for this purpose. We have created a template product for creating UPS products, described in Chapter 19: Using template_product to Build and Distribute UPS Products. It includes Fermi-standard Makefiles, and automates much of the process. The general UNIX make utility and the associated Makefiles are beyond the scope of this document, but the subject is introduced in UNIX at Fermilab, and treated in many standard UNIX texts.

System Independence

The various flavors of UNIX have many differences. You will generally have to release separate instances of your (compiled) products for the different flavors. However, the more you are able to insulate your product from flavor/release dependencies, the easier your product will be to maintain, and the less rigid it will appear to installers and users.

16.1.3 Third-Party Products Requiring a Hard-Coded Path

If you're installing a third-party product, downloaded from the Web or elsewhere, you may not have the opportunity to code it such that it identifies its location at run time based on ${UPS_PROD_DIR} or the $<PRODUCT>_DIR environment variable. Whereas many products never need to know their location (they only need to be in your $PATH, for example), many other products do need to know their location in order to locate auxiliary commands, libraries, utilities, and so on.

Techniques for Implementing these Products

For those that do, the technical note TN0086 Use of "/usr/local/products" now deprecated, on-line at, describes recommended techniques for implementing the products. Please refer to it for information. The three approaches it describes are, briefly:

In the past for UPS v3 we used the /usr/local/products convention. We include this information for reference purposes only. This convention had serious drawbacks. The old (now deprecated) procedure was standard only on fully FUE-compliant systems (defined in the on-line document DR0009), and required that you:

  • configure, build, and/or (re-)code the product so that the hard-coded path it uses is /usr/local/products/{product}/{version} (e.g., /usr/local/products/tk/v4_2a).
  • write a configure script which creates the directory /usr/local/products/{product}, and creates in it the symbolic link {version} back to the real product root directory (e.g., /usr/local/products/tk/v4_2a is a symbolic link to /path/to/products/OSF1+V3/tk/v4_2a).
  • write a current script that creates a symbolic link called current in the same directory, pointing to the link for the instance which is declared as current (e.g., /usr/local/products/tk/current is a symbolic link to /usr/local/products/tk/v4_2a).

Examples of Products Requiring Hard-coded Paths

Here are examples of situations in which hard-coded paths are unavoidable:

16.2 Tools for Developing and/or Packaging Products

The tools that we introduce in this section can be used separately or together. They are all available as UPS products in KITS. See the on-line documentation Integrating buildmanager, cvs, template_product,and upd at

16.2.1 Buildmanager

The buildmanager application is a configurable tool which lets you build software on multiple systems simultaneously, in an organized and consistent fashion. It allows you to set up standardized build sequences and define actions to be performed automatically. It can stop if things go wrong, and allows interaction with various build systems to correct problems. It is available as a UPS product in KITS. Any system to which you can telnet and run commands can be used as a build system with buildmanager. See the on-line documentation at

16.2.2 CVS

It is a common practice to maintain a product's source code as well as its Makefile and UPS management files in a CVS repository for development and maintenance. CVS allows each developer to check out files into a private working directory and to modify them as necessary. With CVS you can maintain all the different versions and flavors in a single work area, and you can pull them out to the separate nodes as needed. Developers working with prebuilt binaries (downloaded from the Web or purchased from a vendor) can use CVS for just the Makefile and UPS management files (e.g., the local README and INSTALL files, the table file, tests, documentation, and so on) so that they can be properly source-controlled. Documentation for CVS can be found on-line at

It is useful to be able to use UPS to setup these checked-out areas. One way that this can be accomplished is by declaring the checked-out area to either the main or a private UPS database, but this is often cumbersome, as these checked-out areas are by nature fairly transient.

A better solution is to exploit the UPS capability of setting up a product instance without having it actually declared to any database. To do this, you simply need to supply the setup command with all of the necessary information, shown here:

% setup <product> -r /your/checked/out/area -M <tableFileDir> \ 
 -m <tableFile> -q <qualifierList> -f <flavor> 

16.2.3 Template_product

To simplify and somewhat automate the process of building UPS products, we have designed the product template_product. Once this product is installed on your system, it can be cloned into a new product area and customized to the new product. template_product can be used to build products of all types (shell script, pre-built binary, source code). We discuss this product in detail in Chapter 19: Using template_product to Build and Distribute UPS Products.

16.3 Directory Structure for a UPS Product Instance

The top level directory of a UPS product instance is called the product root directory, and in general it should contain files and subdirectories in which almost everything related to the product instance resides: the executables, the library files, the documentation, and so on. The ups directory files (i.e., the UPS metadata) and the table file usually reside here, but are not required to do so.

UPS is very lenient in the directory structure it allows. Nothing is required in all situations beyond a product root directory. Normally product instances have a table file containing actions that are run during operations like product installation and setup.

We recommend that you follow a few directory structure guidelines simply to conform to a generally recognized format. This will make it easy for yourself and others to identify each file and directory later on. The following is a relatively complete sample directory structure underneath the product root directory. Most products won't require all of these elements. On the other hand, you may include other directories and/or files not listed here. Elements which we strongly recommend that you provide (in addition to the executables) for every product include a README file, man pages, a user guide, test scripts and example files.

text file containing information such as origin of the product (by whom, from where, etc.), support level, support group/person, caveats and known bugs (may be contained in the ups directory)
directory containing the executable(s)
directory containing metadata files and other executable and data files used during implementation and invocation; may also contain INSTALL_NOTE (described below) file and the directories toman, toInfo, tonews and tohtml. Often the table file resides here. (This directory is no longer a required element of a UPS product.)
Default location of the ups directory is directly underneath the product root (for compatibility with UPS v3), but it may reside anywhere.
text file containing a detailed description of any installation actions that are more easily performed directly by the installer rather than by a script (beyond or instead of running configure and/or tailor and/or current). This should not be a script. This file is not usually needed. If provided, mention it in the README file so that product installers know to run it.
directory containing libraries
directory containing source code
directory containing include files
directory containing a user guide and any other documentation as appropriate; should include the source files (e.g., LaTeX, Word) as well as the printable files (e.g., PostScript)
directory containing unformatted man pages. The files get copied into the location specified in $PRODUCTS/.upsfiles/dbconfig (keyword MAN_TARGET_DIR).
Default location (for compatibility with UPS v3): ups/toman/man
directory containing formatted man pages. The files get copied into the location specified in $PRODUCTS/.upsfiles/dbconfig (keyword CATMAN_TARGET_DIR).
Default location (for compatibility with UPS v3): ups/toman/catman
directory containing the html version of the user guide and any other documentation as appropriate (automatic copy of files to standard area defined by HTML_TARGET_DIR not implemented in UPS v4)
Default location (for compatibility with UPS v3): ups/tohtml
directory containing news files to be posted to a newsgroup (automatic copy of files to standard area defined by NEWS_TARGET_DIR not implemented in UPS v4)
Default location (for compatibility with UPS v3): ups/tonews
directory containing any text files that are to be displayed as a login announcement via the Info feature. The files get copied into the location specified in $PRODUCTS/.upsfiles/dbconfig (keyword INFO_TARGET_DIR). Info is generally used to communicate to users about the Fermilab computing systems events, (e.g., shutdowns), software upgrades and other systems-related information.
Default location (for compatibility with UPS v3): ups/toInfo
directory containing test scripts and any other test-related files
directory containing example files to help users learn how to use the product

Product Documentation Storage

Each different type of product documentation (e.g., man pages, html files, PostScript files, and so on) must reside in a separate subdirectory. The subdirectories usually reside under the product root directory, but do not have to. In the product's table file, you should use the keywords XXX_SOURCE_DIR as listed in section 28.4 List of Supported Keywords (e.g., MAN_SOURCE_DIR, INFO_SOURCE_DIR) to identify the directory in which each form of documentation is maintained. For example:


UPS currently requires that all files in a directory specified by XXX_SOURCE_DIR be of the corresponding file type; you cannot mix file types.

The ups/toman directory and its subdirectories man, catman and toInfo are used as defaults in UPS v4 for backwards compatibility. This structure is not necessarily our recommendation. If a product comes with man pages, Info files, html files and so on, we recommend that you leave them where they are, and simply specify their locations in the table file. If you are writing your own, you can put them in subdirectories directly under the product root directory, which is generally the most convenient place.

In UPS v4, NEWS_SOURCE_DIR and HTML_SOURCE_DIR are not implemented.

Most vendors (freeware, shareware, and the few paid packages where you get the source code and rebuild it) now make it possible to modify the Makefiles so that you can decide where you want the output files, images, and so on, to go. Unfortunately, these are still frequently hard-coded at compile time, not run time. Therefore, packages that you build in this manner on your development system will not be right when installed on a user system with a different product root directory path.

UPS/UPD Doc Home page | Computing Division| Fermilab at Work | Fermilab Home
View/print PDF file

This page generated on: 10/15/02 14:06:03