Creating mmpack packages

package specfile structure

name and location

The mmpack specfile should be called specs and be placed within a folder named mmpack at the root of the repository being packaged. Following this naming convention will allow mmpack to automatically find and work with the package specfile.

Format

The specfile follow the yaml format. It is split into two parts: the general part, and a custom part for package specifics.

The general part is named general and contain data concerning all the the project itself, all the packages that can be build from it, and the necessary information to build them.

The custom part is optional, and made of any number of entries, one for each package it wants to customize.

The general section

Mandatory fields
name:

The source package name. This name is also used as root to generate the binary package names (unless they all are customized). For ghost packages, this field will also be used to search for binary package in the system package repository. All binary system package whose source is this name will be fetched to create ghost packages. This source name to search in the repo can be changed with syspkg-srcnames option.

version:

The version of the packages to be generated. It also is used in the name generation. e.g. package name “XXX” version “1.0.0” will generate by default: (on arch amd64-debian)

  • source package: XXX_1.0.0_src.tar.gz
  • binary package: XXX_1.0.0_amd64-debian.mpk
  • devel package: XXX-devel_1.0.0_amd64-debian.mpk
  • doc package: XXX-doc_1.0.0_amd64-debian.mpk
maintainer:

The email address of the maintainer (the person a user should contact if something goes wrong)

url:

The url used to recover the upstream sources of the project. On git, this url is the same as the argument for git clone

description:

Any text describing the project.

Optional fields
build-options:

Any custom compilation flags that will be added to the build when creating the package. e.g. -D_WITH_CUSTOM_DEFINE=1

build-system:

Which build plugin to use. e.g. “cmake” to use the cmake build plugin (build-cmake file). Or the custom wildcard to tell mmpack to build using a provided build plugin mmpack/build See build-plugin-specs.md on how to write such a thing.

build-depends:

A list of packages required to build the project. This is a key split into several sub-keys. Used alone, it can only contain mmpack packages. It can then be customized by platform

  • build-depends-debian-mmpack
    list of mmpack packages that are needed only when building on debian
  • build-depends-debian-system
    list of debian packages that are needed to build
ghost:

True if the packaging specs refers to a ghost of system packages. If not present, False is assumed.

syspkg-srcnames:
 

Meaningful only if ghost is True. Optional key-value mapping allowing to determine to which source name the system binary packages must be associated when searched in the repository of system package. If the key matches the target distribution, the corresponding value will be used as source project name instead of name field in the mmpack spec. However name field will still be used to generate the name of the mmpack ghost package. The key is a PCRE regular expression used to match targetted host distribution of the generated package.

ignore:

list of files to be ignored by any packages. Any entry follows the PCRE format.

licenses:

List of licences for the project. Each entry can be either a path to the project’s license file, or a license name as present in mmpack’s common-licenses folder. If left unset, will fallback to either LICENSE, or COPYING file from the source tree (case insensitive). Note: the “licenses” field is optional, but its value is mandatory for mmpack-build to work. If no license could be found, mmpack-build will abort.

copyright:

Can be either a string, or a path to a copyright file. The copyright file has a free format without any special specifications. The copyright field and value is entirely optional (unlike the “licenses” field).

The custom sections

The custom sections are used to change the default values of created packages, or to create a custom specific package. If a custom entry does not match a default mmpack target, then it will be considered a custom packages.

List of fields to specify a package:

depends:A package runtime mmpack dependency
sysdepends-platform:
 Where platform is to be replace by the platform name (e.g. sysdepends-debian) is a platform runtime dependency
description:Any text describing the package
files:List of built files to include into the package. Follows the PCRE format. e.g. .*\.so to include all the files with so extension

Note on the default packages

For project XXX, the default packages usually are as follows:

  • A XXX binary package with the binaries themselves, the (1) section of the man pages, the locale files …
  • A XXX-devel package containing the development files (this is mostly true for projects that are libraries)
  • A XXX-doc package that will contain any generated documentation.
  • If the package contains a library libyyy.so, then a package will be created for it.

Minimal specfile example

general:
    name: mmpack-hello-world
    version: 1.0.0
    maintainer: Gandalf <[email protected]>
    url: ssh://intranet.mindmaze.ch:29418/mmlabs/mmpack-hello-world
    description: |
      mmpack hello world

Ghost package specfile example

general:
    name: mmpack-hello-world
    version: 1.0.0
    maintainer: Gandalf <[email protected]>
    url: ssh://intranet.mindmaze.ch:29418/mmlabs/mmpack-hello-world
    description: |
      mmpack hello world
    ghost: true
    syspkg-srcnames:
        debian: mmpack-h-w # project source is known as mmpack-h-w in Debian
        fedora: mmpack-helloworld # project source is known as mmpack-helloworld in fedora

package sources_strap structure

It is possible to separate the mmpack packaging from the actual source of the project it package. In such a case, when generating the source tarball, the upstream sources will be fetched and merged with mpack packaging.

name and location

It should be called sources-strap and be placed within a folder named mmpack at the root of the repository being packaged. Following this naming convention will allow mmpack to automatically find and fetch upstream source automatically.

Format

The format follows the yaml format.

Mandatory fields

method:The method how to fetch the sources. It should be currently ‘tar’ or ‘git’.
url:The url used to recover the upstream sources of the project. With ‘git’ method, this url is the same as the argument for git clone.

Optional fields

branch:(for git only) The commit hash, tag or branch that must be extracted by git clone
sha256:(for tar only) The SHA256 hash of the tarball that must be downloaded

Examples

method: git
url: https://github.com/libusb/libusb.git
branch: v1.0.23
method: tar
url: https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.24.0.tar.xz
sha256: 9f71d61973626d8b28c4cdf8e2484b4bf13870ed643fed982d68b2cfd754371b

Generating binary packages

When building packages from a project, mmpack will create one or several packages from the files staged for installation. The packages declared in the mmpack specfile will receive the files according to files fields specified there. The remaining files are assigned to either:

  • a main binary package
  • one package for each dynamic library
  • a devel package
  • a debug package
  • a documentation package

This process can be detailed as follows (for package “XXX”):

  1. Gather all the staged files
  2. Give the custom packages their requested files
  3. Give files to their corresponding package based on their type. Create the packages as needed.
    • documentation files (man pages, sphinx outputs …) go to XXX-doc
    • debug symbols go to XXX-debug
    • development files (headers, static libraries …) go to XXX-devel
    • dynamic libraries create their own packages
    • binaries, and .1 man pages go to the main binary package XXX
  4. All the remaining files (if any) will go to a default package. The default package is the main binary package if there is one. If there is no binary package and only one library package, the default library is the library package. Finally, if there is no binary package, and there are multiple library packages, create a main binary package as host for those files.

Some filters are not explicit here because they should be intuitive to understand. If you have an issue with they way this works, most of them are implemented in src/mmpack-build/file_utils.py should you feel up to it, otherwise contact us and we’ll try to help.

Minimal mmpack packaging example

A minimal mmpack packaging example is available here [1]. It is an autotools-based hello-world project with simple commands. It also is used as part of the mmpack continuous testing. Feel free to fork it, and play around with it.

[1] https://intranet.mindmaze.ch/mmlabs/gerrit/admin/repos/mmlabs/mmpack-hello-world

You can test is as follows:

# prepare to work on a tmp prefix
MMPACK_REPOSITORY=http://mm-v008/mmpack/stable/debian/
export MMPACK_PREFIX=/tmp/mmpack-hello-world-prefix

# create a mmpack prefix
mmpack mkprefix --url=$MMPACK_REPOSITORY $MMPACK_PREFIX

# clean the mmpack-build workspace, temporary files, and previously
# generated packages
mmpack-build clean --wipe

# build mmpack-hello-world directly from git, using the top of the master
# branch.
mmpack-build pkg-create --git-url ssh://intranet.mindmaze.ch:29418/mmlabs/mmpack-hello-world --tag master

# You can also clone and do the same from the project's folder:
git clone "ssh://intranet.mindmaze.ch:29418/mmlabs/mmpack-hello-world"
cd mmpack-hello-world
mmpack-build pkg-create
# This should end with telling you: "generated package: mmpack-hello-world"
# the full name of your package should be in the line just before.

# assuming you did not change your config, install from the created package
# file within your home folder.
# (on debian/x86, the * wildcard would expand into amd64-debian)
mmpack install ~/.local/share/mmpack-packages/mmpack-hello-world_1.0.0_*.mpk

# you can test the package by running
hello-world
mmpack run hello-world

head-libexec-world  # should fail
mmpack run head-libexec-world  # this one should work

How to create a local repository using the package I created ?

# assuming you did not change your config, the mmpack packages are created
# in the following folder
REPO="$HOME/.local/share/mmpack-packages/"

mmpack-createrepo $REPO $REPO

# add the repository to your list of repositories by adding file://$REPO
# to your mmpack config "repositories" list
# It could look like this
cat ~/.config/mmpack-config.yaml
repositories:
  - file:///home/gandalf/.local/share/mmpack-packages