A GENDIST-package is not yet 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 distribution, especially during the generation 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 include-file $(DIST_ROOT)/rules/package.inc contains a number of targets typically needed during the lifecycle of distribution-development (e.g. targets "clean" or "distclean"). These targets (and other behaviour) are controlled by makefile-variables. Most variables have sensible defaults, but for special situations, you need to override them. The following table is the reference (and I hope it's in sync with package.inc ;-). Typically, only variables in bold are defined/overridden. You should check the Makefile in GENDIST_ROOT/examples/packages/kernel for a real-life example of using overrides.
Name | Description |
---|---|
DEP-PACKAGES | Blanck separated names of the prereq-packages relative to the current packages. Typical use: DEP-PACKAGES := ../prereq1 ../prereq2. |
DEP-PACKAGES-ENV | Blanck separated names of the prereq-packages for the environment, again relative to the current packages. Typical use: DEP-PACKAGES-ENV := ../prereq1 ../prereq2. |
CLEAN_TARGETS | Targets to process during "make clean". The default is "clean-default", which will also clean any automatically downloaded, unpacked and patched source-code. |
DISTCLEAN_TARGETS | Targets to process during "make distclean". The default is "distclean-default", which will also distclean any automatically downloaded, unpacked and patched source-code. Note that not every source-package will define this target. |
MRPROPER_TARGETS | Targets to process during "make mrproper". The default is "mrproper-default", which will also mrproper any automatically downloaded, unpacked and patched source-code. Note that not every source-package will define this target. |
ENV_CLEAN_TARGETS | Targets to process during "make env-clean". The default is "env-clean-default", which will also clean any automatically downloaded, unpacked and patched source-code. |
ENV_DISTCLEAN_TARGETS | Targets to process during "make env-distclean". The default is "env-distclean-default", which will also distclean any automatically downloaded, unpacked and patched source-code. Note that not every source-package will define the target "distclean". |
ENV_MRPROPER_TARGETS | Targets to process during "make env-mrproper". The default is "envmrproper-default", which will also mrproper any automatically downloaded, unpacked and patched source-code. Note that not every source-package will define the target "mrproper". |
PACKAGE_NAME | When this variable is defined, the package will automatically be downloaded, unpacked and patched. See Building from Source below. |
PACKAGE_VERSION | Version of the package, e.g. "0.60.3". |
PACKAGE_EXT | Extension of the package, e.g. "tar.bz2". |
PACKAGE_FILE | Complete name of the package. Defaults to $(PACKAGE_NAME)-$(PACKAGE_VERSION).$(PACKAGE_EXT). |
PACKAGE_WEB_PREFIX | Leading part of URI of package. The package will be downloaded from $(PACKAGE_WEB_PREFIX)/$(PACKAGE_NAME)-$(PACKAGE_VERSION).$(PACKAGE_EXT). |
DOWNLOAD_TARGETS | Targets to process during downloading. Default is
"download-package-default", which will use wget to
download the source-archive to
$(SOURCE_CACHE_DIR).
A typical use of overriding this target would be:
DOWNLOAD_TARGETS := download-package-default local-download-package local-download-package: cd $(SOURCE_CACHE_DIR) && wget -nd $(my-special-files)This will download the package-source using the default download target and then it will download addtional files (e.g. patches). |
UNPACK_TARGETS | Targets to process during unpacking. Default is "unpack-package-default". This target currently supports the following formats: bzip2-compressed tar-archives (extensions: tar.bz2, tbz2, tbz), gzip-compressed tar-archives (extensions: tar.gz, tgz) and zip-archives (extensions: zip). |
PATCH_TARGETS | Targets to process during patching. Default is "patch-package-default", which will execute a script called "patch.sh" (if existent in the current directory and executable). The patch.sh-script can do anything, but a typical use would be to use the patch(1)-utility. |
CLEAN_SOURCE_TARGETS | Targets to process during "make clean-source". The default is "clean-source-default", which will clean the automatically downloaded, unpacked and patched source-code. |
DISTCLEAN_SOURCE_TARGETS | Targets to process during "make distclean-source". The default is "distclean-source-default", which will distclean the automatically downloaded, unpacked and patched source-code. Note that not every source-package will define the target "distclean". |
MRPROPER_SOURCE_TARGETS | Targets to process during "make mrproper-source". The default is "mrproper-source-default", which will mrproper the automatically downloaded, unpacked and patched source-code. Note that not every source-package will define the target "mrproper". |
DONT_USE_ENV_PATH | If this variable equals true, $(ENV_DIR)/bin is removed from PATH. Useful for compiling/linking packages for the environment itself (e.g. uClibc). |
The build-system also 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.
There are four types of targets in a package-level makefile: predefined targets, automatic (pseudo) targets, user-defined but mandatory targets, and user-defined but optional targets. For a seamless integration of user-defined targets into normal makefile integration, they also have to be configured using configuration variables, as described in the section above.
Name | Type | Description |
---|---|---|
install | mandatory (filesystem-packages) optional (environment-packages) |
This user-defined target does "the real work", e.g. it installs some files in the target filesystems or creates directories and so on. For many packages it will suffice to define this single target. |
env-install | optional (filesystem-packages) mandatory (environment-packages) |
This user-defined target does "the real work", e.g. it installs some files in the environment or creates directories and so on. |
clean | predefined | Proces prereqs in $(CLEAN_TARGETS) and remove dummy targets. |
clean-default | predefined | If PACKAGE_NAME is defined, process clean-source. |
distclean | predefined | Proces prereqs in $(DISTCLEAN_TARGETS). |
distclean-default | predefined | Process clean. If PACKAGE_NAME is defined, also process distclean-source. |
mrproper | predefined | Proces prereqs in $(MRPROPER_TARGETS). |
mrproper-default | predefined | Process distclean. If PACKAGE_NAME is defined, also process mrproper-source. |
env-clean | predefined | Proces prereqs in $(ENV_CLEAN_TARGETS) and remove dummy targets. |
env-clean-default | predefined | If PACKAGE_NAME is defined, process clean-source. |
env-distclean | predefined | Proces prereqs in $(ENV_DISTCLEAN_TARGETS). |
env-distclean-default | predefined | Process env-clean. If PACKAGE_NAME is defined, also process distclean-source. |
env-mrproper | predefined | Proces prereqs in $(ENV_MRPROPER_TARGETS). |
env-mrproper-default | predefined | Process env-distclean. If PACKAGE_NAME is defined, also process mrproper-source. |
download | predefined | Process prereqs in $(DOWNLOAD_TARGETS). |
download-package-default | predefined | Fetch package using wget. |
unpack-package | predefined | Process prereqs in $(UNPACK_TARGETS). |
unpack-package-default | predefined | Unpack package. This target currently supports the following formats: bzip2-compressed tar-archives (extensions: tar.bz2, tbz2, tbz), gzip-compressed tar-archives (extensions: tar.gz, tgz) and zip-archives (extensions: zip). |
patch-package | predefined | Process prereqs in $(PATCH_TARGETS). |
patch-package-default | predefined | This target will execute a script called "patch.sh" (if existent in the current directory and executable). The patch.sh-script can do anything, but a typical use would be to use the patch(1)-utility. |
source | predefined | Download, unpack and patch source-code. After processing this target the source-code is ready to configure/compile in $(PACKAGE_SRC_DIR). This target is typically a prereq of target "install" or "env-install". |
clean-source | predefined | Proces prereqs in $(CLEAN_SOURCE_TARGETS) and remove dummy targets. |
clean-source-default | predefined | If $(PACKAGE_SRC_DIR) exists, process "make -C (PACKAGE_SRC_DIR) clean". |
distclean-source | predefined | Proces prereqs in $(DISTCLEAN_SOURCE_TARGETS) and remove dummy targets. |
distclean-source-default | predefined | Remove $(PACKAGE_SRC_DIR). If downloaded source-archive is relative to DIST_ROOT, also remove downloaded source-archive. |
mrproper-source | predefined | Proces prereqs in $(MRPROPER_SOURCE_TARGETS) and remove dummy targets. |
mrproper-source-default | predefined | Remove $(PACKAGE_SRC_DIR) and downloaded source-archive (regardless of location). |
_packagename.install | automatic | Dummy target created after successful install. |
_packagename.env-install | automatic | Dummy target created after successful env-install. |
_packagename.unpack | automatic | Dummy target created after successful unpack. |
_packagename.patch | automatic | Dummy target created after successful patch. |
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 must define the target env-install: this target should install all necessary files in the build-environment. The target-directory is passed as the variable TARGET_DIR (which in fact is DIST_ROOT/build/env).
Cleanup is controlled by the targets env-clean and env-distclean. To override normal behaviour, change the variables ENV_CLEAN_TARGETS and/or ENV_DISTCLEAN_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 could create a symbolic link from e.g. DIST_ROOT/src/packages/root-fs/uclibc to ../env/uclibc and define both the normal target "install" and the environment-target "env-install" in the makefile. If you use symbolic links, make sure you use relative links, else you will run into trouble. Also note that a "make clean" would in this case also clean the source-package of your environment, unless you change the default behaviour (see the makefile in the examples/packages/uclibc-subdirectory of the GENDIST-distribution).
Note for CVS-users: CVS does not support symbolic links. In this case, you could add an additional package called symlinks to the environment 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 (true,$(GLOBAL_LFS)) # this won't override BB_DOLFS if set BB_DOLFS := true else BB_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 $(BB_DOLFS),DOLFS=$(BB_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".