A GENDIST-package is not another package-format (there are enough of these around). Consider a GENDIST-package as a unit of work to do during the creation of a filesystem. The package can do anything, but it usually just copies or unpacks some files into the filesystem.
Each package "lives" in it's own subdirectory underneath DIST_ROOT/src/packages/name-of-filesystem. The makefile is the only file necessary in the package directory. The name of the package is the directory-name relative to DIST_ROOT/src/packages/foo-fs, eg. shells/bash is a valid package-name (as long as src/packages/foo-fs/shells/bash exists). Therefore, you can group your packages in a directory-hierarchy.
Packages defined in the variable foo-fs_PACKAGES (usually in the toplevel file config.inc) correspond to directories below of the foo-fs subdirectory of DIST_ROOT/src/packages.
Packages are also used to create the build-environment. These packages differ from filesystem-packages in two ways: they are defined in subdirectories of DIST_ROOT/src/packages/env/ and they define different targets. See environment-packages below for a detailed discussion.
To interface cleanly with the rest of the build-system, the package-level makefile must follow a number of guidelines.
The rules are quite simple:
You will find a template makefile in DIST_ROOT/rules/Makefile.package.
The easiest way to learn how to create GENDIST-packages is to have a look at the examples provided by the GENDIST distribution.
The build-system sets a number of variables, which you can use for the commands of the install-target. Typically, you will use the variable TARGET_DIR, which points to the root of the filesystem currently created. Other useful variables include DIST_NAME or VERSION.
One of the design-goals of GENDIST is to prevent as much recompilation as possible. If a package is made (i.e. installed), a pseudo-target file with the name _packagename.install is created in the package-directory. As long as this file exists, the package is not remade. A 'make clean' will of course delete the pseudo-target. So if you want to be sure your package is remade, just remove the pseudo-target by hand, or call 'make clean' (the latter is the preferred method).
All this is handled by the rules in package.inc. This is also the reason why you should not define your own targets before including package.inc.
A number of pattern-rules are available to build (install) and clean individual packages of root-fs_PACKAGES and cd-fs_PACKAGES (packages of additional filesystems are not yet supported):
Environment packages are defined in subdirectories of DIST_ROOT/src/packages/env/ and should be listed in the variable env_PACKAGES.
Environment packages should define the following targets:
Environment-packages can share code with normal packages. E.g. the uClibc-package could install the uClibc-wrappers in the environment, and install the uClibc-libraries in the root-fs. To minimize code-duplication, just create a symbolic link from e.g. DIST_ROOT/src/packages/root-fs/foo to ../env/foo and define the normal targets and the environment-targets in the makefile. If you use symbolic links, make sure you use relative links, else you will run into trouble.
Note for CVS-users: CVS does not support symbolic links. In this case, you could add an additional package called symlinks which creates all necessary symbolic links.
You can also build your files from source, including automatic download of the source-archives. The include file $(DIST_ROOT)/rules/package.inc has a number of predefined rules for all that is necessary. A typical makefile then looks like this:
# ----------------------------------------------------------------------------- # Makefile for uClibcLinux: package busybox # # License: GPL2 # ----------------------------------------------------------------------------- # Define list of dependent packages (relative to this package) ---------------- DEP-PACKAGES := # package description --------------------------------------------------------- PACKAGE_NAME := busybox PACKAGE_VERSION := 0.60.3 PACKAGE_EXT := tar.bz2 PACKAGE_WEB_PREFIX := http://busybox.net/downloads # Include standard rules (don't define targets before this include!!) --------- include $(DIST_ROOT)/rules/package.inc # package configuration ------------------------------------------------------- ifeq (,$(DOSTATIC)) DOSTATIC := false endif ifeq (,$(DOLFS)) DOLFS := false endif # install files into root-fs -------------------------------------------------- install: source @echo "Installing Busybox to directory $(TARGET_DIR)" $(MAKE) -C $(PACKAGE_SRC_DIR) install-hardlinks \ PREFIX=$(TARGET_DIR) \ $(if $(DOSTATIC),DOSTATIC=$(DOSTATIC)) \ $(if $(DOLFS),DOLFS=$(DOLFS))
Necessary are the package-description-variables. The target "source", in the above example a prereq of "install", will download, unpack and patch the source-code. The target "source" is defined in DIST_ROOT/rules/package.inc.
The default download-location is DIST_ROOT/src/SOURCES, but you can override this with the configuration-variable SOURCE_CACHE_DIR. A "make distclean" will remove the downloaded archive, if the cache-dir is relative to DIST_ROOT. A "make mrproper" will remove it in any case.
The wget-utility is used for downloading from PACKAGE_WEB_PREFIX. For testing purposes, you can set the variable USE_LOCAL_WEB to true and define LOCAL_WEB_PREFIX. This will download the packages from the local site instead.
The downloaded archive will be unpacked to DIST_ROOT/src. A symbolic link DIST_ROOT/src/PACKAGE_NAME is created to the directory DIST_ROOT/src/PACKAGE_NAME-PACKAGE_VERSION. This assumes that the toplevel-directory in the archive follows this naming convention.
After download and unpacking, the source is patched. The makefile searches for an executable file patch.sh and executes it. Typically, patch.sh will copy some configuration files or invoke the patch(1)-command.
Building and installing are rather individual tasks, therefore there are no predefined rules. One could actually augment the above example with a target "build". In this case, "build" would be the prereq of "install", and "source" would be the prereq of "build".