This is Common IPS Build System (CIBS). It intend to replace all userland-hell known from OpenSolaris and OpenIndiana.
CIBS is inspired by Common Debian Build System
Major features are:
- Makefile-based (need GNU
- Modular design (include
autotools.mkfor GNU configure, or
cmake.mkfor CMake-based packages)
- Tracking build dependencies
- Building packages independently (no more terrible "consolidations" or "incorporations")
To create and publish an IPS package you need:
- CIBS package installed (
Makefiledescribing what and how you are building
- At least one canonical IPS manifest.
Look into directory
examples for examples.
Split development file and runtime
In contrast to some crazy distributions (like Solaris or Arch Linux) we do split runtime and development files (as Debian does).
Any shared library should be packaged into separate package reflecting
library's soname, e. g.
library/gmp10 includes libgmp.so.10. Nothing else.
library/gmp includes headers, man pages, maybe static libraries etc. -
anything that required to build applications using GMP. Both packages -
library/FOOxxx are built from the same source, and
library/FOO must depend on
library/FOOxxx in such a way:
depend fmri=pkg:/library/FOOxxx@$(ips-version) type=require depend fmri=pkg:/library/FOOxxx@$(ips-version) type=incorporate
The trick is that IPS will use
library/FOOxxx to fulfil runtime
dependencies, and we will be allowed to perform smooth migration
on newer library (e. g.
library/FOOyyy) without breaking existing
packages. Of course, newer
library/FOO will depend on
library/FOOyyy can be installed along with
library/FOOxxx must be installable together
so none of them can ship docs, man pages or images or anything,
but a shared library itself.
Another example is Node.js or Python. Use
runtime/nodejs package for development files and runtime.
runtime/nodejs includes only the binary -
and maybe other runtime files, man pages etc.
This module defines common variables and targets. All other modules include this module, and it should not be included directly, unless you are doing something really special.
Targets provided by common.mk
All targets (but
clean) provided by this module are abstract and
do nothing. Other modules extend these targets. Each target has
target-stamp which does the real job. Each
a file created with
touch command. All internal dependencies are
implemented through these "stamps", but developer can use basename
for target, e. g.
make unpack instead of
Meaning of these targets depends on other included modules:
unpack- put sources into the source directory (
patch- modify sources,
configure- configure sources, e. g. execute GNU configure or CMake,
build- build sources, e. g. compile with C compiler,
install- install files into proto directory.
Each target in the list above depends on previous target. Yes, except
clean has a double-colon rule
and by default it is:
clean:: rm -f *-stamp rm -rf $(workdir)
Building many variants
common.mk defines a macro
add-variant to extend above targets and to define
related variables such as
$(eval $(call add-variant,FOO))
will add dependencies to configure-stamp, build-stamp,install-stamp and define
variants += FOO protodir.FOO = $(workdir)/proto/FOO builddir.FOO = $(workdir)/build/FOO configure-stamp : configure-FOO-stamp build-stamp : build-FOO-stamp install-stamp : install-FOO-stamp %-FOO-stamp: variant = FOO
add-variant macro is used by
64.mk modules for
building 32-bit or 64-bit packages. You may want to use it for any
other purpose, e. g. to compile Curl with OpenSSL or with GNU TLS.
Standard modules, such as
autotools.mk, take care of every variant defined.
You can tune building by defining variables like
configure-options.FOO, e. g.:
$(eval $(call add-variant,ssl)) $(eval $(call add-variant,gnu)) configure-options.gnu = --without-ssl --with-gnutls configure-options.ssl = --with-ssl --without-gnutls
This module defines configure, build and install targets by GNU autotools.
These targets are implicit (e. g.
configure-%-stamp), and you can completely
override any of them by explicit target (e. g.
configure-foo-stamp) in the top Makefile.
configure holds the name of the configure script ("$(sourcedir)/configure" by default).
You can redefine it if the configure script is not in the top source directory or has a different name.
configure-options variable to append or replace options passed to the configure script.
configure-options.<variant> to define variant specific options (see above).
configure-env holds environment variables for the configure script,
such as CC, CFLAGS, LDFLAGS etc. As usual, you can append or completely replace them.
configure-env.<variant> to define variant specific environment variant.
Build and install targets use target-specific variable
target for invoking
This variable is empty for
build-%-stamp and is set to "install" for
You can redefine it in the top Makefile to build/install only a subset of a package. E. g.
for NCurses with wide character support this will build and install only libraries (without
programs and terminal database):
$(eval $(call add-variant,wide)) build-wide-stamp: target = libs install-wide-stamp: target = install.libs
Another target-specific variable is "make-vars". The value of this variable
is appended to make command. By default it is set to
build-%-stamp (disable silent rules) and to
install-%-stamp. You can append or completely replace "make-vars" to
make hacks or when you are using autotools.mk for packages which are not
actually use autotools, but some hand-made configure scripts.
This module provides functions to work with IPS manifests and publish packages.
Targets provided by ips.mk
publish- publish IPS package into IPS repository
pre-publish- make everything required to publish (including downloading archive, patching, compiling, mogrifying manifests etc), but do not publish. Usefull for final verifications what is going into IPS repository. All intermediate and final manifests are in "work/manifests" directory.
build-dep- install build dependencies
Variables used by ips.mk
ips-repo- IPS repository to publish, e. g.
make publish ips-repo=http://example.com:1234
Any variable defined in Makefile will be passed to
can be used in IPS manifests (*.p5m). This is especially useful
when with variable
ips-version, which is by default
Example is OpenSSL, where
version = 0.9.8x, but
(because letters are not allowed by IPS).
These variables passed additionally:
# or empty, and
# or empty. These variables can
be used to cut off some line in package manifest (by commenting out).
By default these vars are
32.mk is included,
build32 becomes '' (empty), so lines like:
$(build32) file path=usr/lib/libfoo.so.1
become uncommented. Same for modules
Other automatic variables are
These variables hold paths to corresponding directories used to
install or build package.
<variant> can be, for example, 32 or 64.
This allow exact specifying which file is requested, e. g.:
file $(builddir.32)/libfoo.so.1 path=usr/lib/libfoo.so.1
Use this modules to get sources from Git repositories. With this module included
unpack mean the same thing - clone git reporitory into
source directory ("work/source"), then checkout given tag, commit or branch.
Makefile should define two variables:
git-url- URL of Git repository, used as
git clone $(git-url) $(sourcedir)
git-checkout- Git tag, branch or commit; used as
git checkout $(git-checkout)
For example see "examples/symlinks".
git.mk, but for Mercurial
Makefile should define two variables:
hg-url- URL of mercurial repository, used as
hg clone $(hg-url) $(sourcedir)
hg-update- Mercurial tag, branch or commit; used as
hg update $(hg-update)
If this module is included, entire source tree will be copied into all requested building directories. This is useful for packages that do not support building out of source tree, such as zlib or openssl.