| Index | SD-UX | Mkpkg | Mkbdl | Glossary |
| SD-UX elements: | bundle | product | subproduct | fileset | vendor |
Mkpkg is meant to be used after the software is debugged and can install itself on the packager's machine. Given software that is ready for distribution, mkpkg helps the publisher develop a description of the software package, including manifests, dependencies, and control scripts. Using mkpkg a publisher can create software packages with three minutes effort, even for large and complex software packages such as TeX.
Publishers use mkpkg actions to accomplish the various tasks associated with creating an installation package. In addition, publishers can specify or modify various bits of package configuration information through the various views of the package. Many actions will automatically fill in various bits of the package configuration, such as the manifest, but other configuration must be done by the publisher.
In order to assemble a binary installation package, the installation tool needs to know a great deal about the software it is installing. The basic elements of an installation package are:
The first step is to prepare the software for packaging. Our software must be able to compile and install correctly on our machine. We should be able to automatically compile and install the software without human intervention. Of course, if we are building a package for pre-compiled software, we can skip compilation. In our case, we have a Makefile with three targets: all, install, and clean.
Our software sources are in less-1.0, and our package contains the following files:
| /usr/local/bin/less |
| /usr/local/bin/X11/xless |
| /usr/local/lib/X11/app-defaults/Xless |
| /usr/local/man/man1/less.1 |
| /usr/local/man/man1/xless.1 |
We need to decide if we will distribute code that has been statically linked or dynamically linked. In general, software that is released as part of HP-UX will be dynamically linked, while software that is shipped by third parties or is shipped independently of HP-UX may be statically linked. The advantage of static linking is that the executables do not depend on specific shared libraries and are more likely to work correctly on a wider range of platforms, but at the cost of additional disk space consumption. Our package will be shipped with dynamically linked executables. We are now ready to begin building our Software Distributor (SD-UX) product.
We first start mkpkg within our project directory less-1.0. The mkpkg interface has a menu bar across the top. Under the View menu, we can see all of the pages that contain information that we may need to provide, verify, or modify. Under the Action menu there are all the actions that we need to produce an installation package.
First, we must provide mkpkg with enough information to be able to build, install, and locate the software in our product. We are currently viewing the configuration page for the product. You should notice that mkpkg has already provided default values for many of the attributes. Some of the defaults come from the default values on the system pages, but others have been computed. For example, the product name (less) and version (1.0) have been computed from the current directory name.
On the configuration page, we need to fill in the directory attribute with /usr/local. This attribute is used in the PSF file, but it is also used by mkpkg during manifest generation to locate the files installed as part of the package. In some cases, we may not know where every file will be installed. Mkpkg has a (long) list of directories to check for new software, in order to catch these wayward files.
We have told mkpkg where to look for installed files, now we need to tell it how to build and install our software. Go to the build page under the View menu. Here, we need to check the attributes build, install, and clean. In this case, the defaults make, make install, and make clean are correct because those are the targets used by our Makefile.
We need to create the manifest, so try the menu option Create file list on the Action menu. This action may take a long time, since it will compile and, install the software, and then it will search your system for newly installed files. For large packages, just compiling the software may take hours, while for large systems it may take hours to search the file system for installed files. Once this action is complete, you should see a fileset less-RUN and a subproduct Runtime under the View menu. You should now check every attribute on each page, correcting or providing information as necessary. You should also check that the fileset less-RUN contains all the files from our package (and no more!), and that the subproduct Runtime contains just one fileset. Also, less-RUN should have dependencies on various filesets from OS-CORE and X11 .
We are now ready to create the installation package with the Create dynamic package action. This action compiles and installs the software. It then copies the software to a "safe" place (check the parent directory of less-1.0, there should be a directory something like less-1.0__10.20__dynamic). It then generates a PSF file (in the "safe" place), and uses that PSF to create an installation package. The installation package is left in the parent directory.
Mkpkg can automatically determine which files were installed by the package on the publisher's machine. Since the technique is based on timestamps, it can reliably detect all files installed by the package. Independent system activity can update files and these files will incorrectly appear in the manifest. Most such files are modified by standard system daemons. Since mkpkg has a list of such files, it can automatically remove most of those spurious files from the manifest.
Mkpkg automatically discovers all shared library dependencies by searching every executable in the package to create a list of all shared libraries used by the package. Mkpkg has a list of all the shared libraries installed on the publisher's machine and the package to which it belongs. It uses this list to identify all shared library dependencies.
When I first developed mkpkg, the vast majority of bugs were caused by shared library dependencies that I had overlooked. Once I added this module to mkpkg the number of bug reports diminished dramatically.
Writing these install/de-install scripts is very difficult, and many of the actions can be specified in a general fashion. In order to simplify the development of correct scripts the publisher simply specifies the desired result of executing the script, and mkpkg will generate all the scripts needed for the package.
If the user does not add more files to the package manifest, then the user may modify the package configuration after the components have been gathered.
Mkpkg has automated or partially automated the following tasks:
Mkpkg can automatically generate a package manifest which includes all files installed as part of the software, and which may include some files not belonging to the package. The manifest generation scheme relies on file timestamps to detect files that were installed by the package. Mkpkg creates a new file that it will use as a timestamp, then it builds and installs the software. It then searches (part of) the file system for files with modification or creation times that are newer than the saved timestamp. Since running systems often have deamons which update log files independent of the software installation process, mkpkg has a list of "spurious files" which are removed from the raw list.
Mkpkg has two ordered sets of rules for determining when to create filesets and subproducts. Each rule contains a regular expression, a threshold value, and a pattern. During fileset creation, the system iterates through the rules. It first creates a list of all files in the product that match the regular expression. If the number of files is greater than the threshold value, then a fileset is created using the pattern (if necessary), and all the matching files are assigned to the fileset.
Control scripts may be used at both the product and fileset levels. Mkpkg allows the user to specify customization actions at either level. The user specifies high-level actions, which mkpkg knows how to map into low-level script fragments for each of the ten possible control scripts. Mkpkg only generates control scripts when necessary, so it won't generate empty control files.
Each attribute of a product, subproduct, or fileset can be marked as "required". Before assembling the package, mkpkg can check that every required attribute has a value.
Mkpkg can also check to ensure that hard links do not cross fileset boundaries. In other words, if two files are joined by a hard link, then they must be in the same fileset.
Fileset names should conform to the conventions described in the Fileset help. Mkpkg uses a number of rules to automatically generate filesets based on the files contained in the product. However, it is impossible to automatically follow all the guidelines (e.g. for -MIN or -AUX filesets), so the publishers must be aware of the guidelines and must use their best judgement in creating the filesets.
.o
and executable files).
default is make clean
default is make
default is make install
default is CCOPTS
default is -Wl,-a,archive
default is ""
/etc/PATH.
The publisher can also specify control scripts. If mkpkg generates a control script for the same attribute, then the mkpkg script will execute the publisher's script which will be included in the fileset as an additional control file.
The configuration/customization actions which mkpkg can automatically generate are:
Mkpkg has a very modular design that provides a framework for adding new modules and functionality. The basic unit of functionality is the operation. Actions are composed of sequences of operations. The user requests that mkpkg execute actions, such as "create the product manifest".
Operations have a uniform function interface, and mkpkg will execute each operation within an action in sequence. The operations may return an error code (in which case mkpkg may ask the packager if they would like to abort) and it can add text to the operation log. Operations are intended to function without user interaction, since mkpkg can be used by either a command-line interface or the GUI.
New functionality is added to the system by developing new operations, and then adding them to the appropriate action list or creating a new action.
Its greatest weakness its data structures for storing package configuration information.
The array index is a comma-separated list of defining attributes of the data value. All of the context for a given piece of information is encoded in the index. For example, the list of prerequisites for mkpkg's fileset mkpkg-BIN is in product(mkpkg,fileset,mkpkg-BIN,prerequisite).
This system is cumbersome but effective for most of mkpkg's needs. As I have been developing the control script generation, its weaknesses for general hierarchical data have become more pronounced. Operations
Operations are the basic building block of mkpkg. Each operation is atomic, and may be used in many actions. Operations often modify the package or mkpkg state, but not always. For example, one action creates the timestamp file used during manifest generation while another action builds the application. Not all actions modify state, some are used to provide error checking.
The backends provide two functions: dumpPSF, and package. DumpPSF creates the PSF file for the package using all the state and information available. Package merely executes the backend-specific packaging program to create an installation package.