Skip to content
Snippets Groups Projects
module_setup.md 7.39 KiB
Newer Older
Martyn Welch's avatar
Martyn Welch committed
+++
date = "2019-10-28"
weight = 100
Martyn Welch's avatar
Martyn Welch committed

title = "Module Setup"

aliases = [
    "/old-wiki/Guidelines/Module_setup"
]
+++

The layout and basic structure of a project’s source directory needs to be done
when the project is created. If done well, with thought put into future
maintainability and scalability of the build system, little maintenance time
will be required on the build system in future.

# Summary

- Follow the standard root directory layout so users of the project can find
  information where they expect.
  ([Root directory layout](#root-directory-layout))
- Ensure the project and each source code file is clearly licenced.
  ([Licencing](#licencing))
- Do not commit generated files to `git`.
  ([Generated files](#generated-files))
- For libraries, separate public and private dependency lists using
  [`AX_PKG_CHECK_MODULES`](http://www.gnu.org/software/autoconf-archive/ax_pkg_check_modules.html#ax_pkg_check_modules).
  ([Dependency management](#dependency-management))
- For libraries, ensure they are completely parallel installable with other
  API-incompatible versions of the same library.
  ([Parallel installability](#parallel-installability))

# Root directory layout

In the root directory of a module’s repository, the following files should
exist:

- `AUTHORS`: Should contain a contact address which is unique to the module,
  but which doesn’t necessarily have to be a real person. It could be a catch
  address like `[module] maintainers <[module]@apertis.org>`.
- `NEWS`: Should have a section for each release, in a format similar to this:
  [1](https://git.gnome.org/browse/libgdata/tree/NEWS#n1)
  - All API changes and additions should be clearly listed so that developers
    using the library know how to update their code.
  - All major changes should be clearly listed so packagers know what to test.
  - Updates to translations should be listed, unless the module doesn’t have
    translations.
- `README`: Should give a description of the module, what it does, and
  potentially a list of its dependencies (if such a list could be kept up to
  date).
- `COPYING`: Should be a verbatim copy of the module’s licence, the
  [MPLv2](https://www.mozilla.org/MPL/2.0/).
- `[project-name]/` (libraries) or `src/` (programs): Location for all source
  code, including header files. Header files should *not* be put in a separate
  `include/` directory, as that separates them from their associated C files,
  making maintenance a little harder.  Libraries should have their source code
  in a directory named after the project so that headers can be universally
  included using `#include <[project-name]/header.h>` for
Martyn Welch's avatar
Martyn Welch committed
  [namespacing reasons]( {{< ref "coding_conventions.md#namespacing" >}} ).
Martyn Welch's avatar
Martyn Welch committed

# Licencing

As well as a [valid COPYING file](#root-directory-layout), in order for a
module to be correctly licenced, it should be clear which files the licence
applies to. Therefore it is necessary to put a brief copyright header at the
top of each source code and header file, and in `README`. This is in addition
to having a `COPYING` file.

    /* This Source Code Form is subject to the terms of the Mozilla Public
     * License, v. 2.0. If a copy of the MPL was not distributed with this
     * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

In source and header files, this should go immediately after the
Martyn Welch's avatar
Martyn Welch committed
[file’s vim modeline]( {{< ref "coding_conventions.md#code-formatting" >}} ).
Martyn Welch's avatar
Martyn Welch committed
In the `README` it should go in a ‘Licensing’ section.

For more information on licensing, see the
Martyn Welch's avatar
Martyn Welch committed
[licensing guide]( {{< ref "license-applying.md" >}} ).
Martyn Welch's avatar
Martyn Welch committed

# Generated files

Any file which is generated by the build system (that is, by `autogen.sh`,
`automake` or `make`) should *not* be committed to git.  Doing so makes the
repository larger unnecessarily, results in spurious changes in people’s
commits as the generated files change, can cause conflicts on checkout, and can
result in stale files if the build system always uses an out-of-date copy of
the generated file from `git`.

Generated files should be ignored by `git`; this can be automated by using
[`git.mk`](https://github.com/behdad/git.mk) in each module.  Ideally, the
output of `git status` should be empty for a module which has been checked out,
not modified, and then built. `git.mk` automatically ignores files listed in
`CLEANFILES` (and the other automake cleaning variables), so if generated files
are correctly cleaned, they should be correctly ignored by `git`.

Generated files include those generated manually by programmers, using
[`gdbus-codegen`](https://developer.gnome.org/gio/stable/gdbus-codegen.html)
for example. Instead of generating such files manually, rules should be added
to the `Makefile.am` to use `gdbus-codegen` at build time and automatically
generate the files.

Other typical files which are automatically generated and which should *not* be
in `git`:

- `ChangeLog`
- All files in `m4/` except in-tree macros from the
  [autoconf-archive](http://www.gnu.org/software/autoconf-archive/)
- All files in `config/`
- `po/ChangeLog`
- `po/Makefile.in.in`
- `po/POTFILES` (but leave `POTFILES.in` in git)
- `po/stamp-it`

# Dependency management

Libraries (but not applications) have to be careful which of their dependencies
are exposed publicly (referenced in the library’s public header files). Public
dependencies need to be kept separate from private dependencies, as they need
to be handled differently for shared and static linking. Private dependencies
are not needed for dynamic linking, but are needed for static linking. By
removing them from the dynamic link command, over-linking is prevented.

pkg-config has support for public and private dependencies in the form of its
[`Requires` and `Requires.private` keys](http://people.freedesktop.org/~dbn/pkg-config-guide.html).

Use the
[`AX_PKG_CHECK_MODULES` macro from autoconf-archive](http://www.gnu.org/software/autoconf-archive/ax_pkg_check_modules.html)
instead of the normal pkg-config `PKG_CHECK_MODULES` macro to automatically
support public and private dependencies, as explained in this article:
[A checklist for writing pkg-config files](https://tecnocode.co.uk/2014/12/09/a-checklist-for-writing-pkg-config-files/).

# Parallel installability

All public libraries should be designed to be installable in parallel with
other API-incompatible versions of the same library. This has little impact at
the start of a project, but is very important later in the project’s lifetime
if a large API break is made. It is hard to port every user of a library from
the old API to the new one, so it is necessary to support installation of the
two versions of the library in parallel, without them conflicting. Building in
support for this kind of parallel installation is much easier to do at the
start of a project than it is to do retroactively.

This is explained in detail in this
[article on parallel installability](http://ometer.com/parallel.html).
The key point is to include the project’s major package version number in its
library name everywhere the library is installed on the file system — in the
binaries, the header include paths, and the pkg-config name and filename.

# External links

- [Guide to pkg-config](http://people.freedesktop.org/~dbn/pkg-config-guide.html)
- [A checklist for writing pkg-config files](https://tecnocode.co.uk/2014/12/09/a-checklist-for-writing-pkg-config-files/)
- [`git.mk`](https://github.com/behdad/git.mk)
- [Guide to parallel installability](http://ometer.com/parallel.html)