Text Document Icon mports's Fake System

Introduction

The fake system is a large change for the mports system, which has caused many ports to destabilize. This document is intended to give developers an understanding of the issues that cause fake errors, and the knowledge to fix those errors.

The fake system goes through the following steps to install a port:

  1. The port is fetched, extracted, patched, configured, and built as normal. There are no changes to these parts of the system.
  2. The port is installed into a temporary directory called FAKE_DESTDIR. This is usually ${WRKDIR}/fake-inst-${ARCH}.
    The actual installs is done as follows:
    1. ${FAKE_DESTDIR}/${PREFIX} is created, and populated with the directory layout with mtree.
    2. The pre-fake target is called. This target runs in the normal environment.
    3. The pre-install target (if it exists) is called. This target does not run in a normal environment. Instead, several variables are prepended with the FAKE_DESTDIR. These variables are PREFIX, LINUXBASE, and KMODDIR. Note that PREFIX is used to define many other variables, so much so that almost all the variables used in an install target are faked. This means that a pre-install target can do something like:
      ${CP} myconfig ${PREFIX}/etc
      and it just works. If you need the real prefix it is available as TRUE_PREFIX.
    4. The pre-su-install target (if it exists) is called in the fake environment.
    5. By default the dist's makefile (the makefile down in WRKSRC) is called like this (simplified for clarity):
      make DESTDIR=${FAKE_DESTDIR} install
      However, if your port has a do-install target, this will be called instead in the fake environment.
    6. The post-install target (if it exists) is called in the fake environment.
    7. The post-fake target is called in the normal environment.
  3. A package is created from the files installed in FAKE_DESTDIR.
  4. This package is installed

When Things Go Wrong

Often when fake fails, the first sign will be an error when the man pages are compressed. This is because compressing man pages is the first step that assumes files to be correctly installed in FAKE_DESTDIR. Several things can cause a fake install to fail, this document will attempt to cover the common cases.

No DESTDIR Support

DESTDIR is a variable used by many projects for staged installs, which is exactly what we are doing. DESTDIR is prepended onto every install path. The GNU Coding Standards page on DESTDIR is an excellent reference.

Most recent projects using the GNU build tools (especially if automake is used) support DESTDIR, as do perl modules, ruby modules, GNUStep modules, and many other projects. Our experience has shown that approximately 75% of ports try to support DESTDIR.

Sometimes there is no DESTDIR support, which will require one of two fixes. If the project is small, you many be able to simply patch the project's makefile. For example, this is a patch, ironically, to GNU patch:

 install:: all installdirs
-       $(INSTALL_PROGRAM) patch$(EXEEXT) $(bindir)/$(patch_name)$(EXEEXT)
-       -$(INSTALL_DATA) $(srcdir)/patch.man $(man1dir)/$(patch_name)$(man1ext)
+       $(INSTALL_PROGRAM) patch$(EXEEXT) ${DESTDIR}$(bindir)/$(patch_name)$(EXEEXT)
+       -$(INSTALL_DATA) $(srcdir)/patch.man ${DESTDIR}$(man1dir)/$(patch_name)$(man1ext)

 installdirs::
-       $(SHELL) $(srcdir)/mkinstalldirs $(bindir) $(man1dir)
+       $(SHELL) $(srcdir)/mkinstalldirs ${DESTDIR}$(bindir) ${DESTDIR}$(man1dir)

A quick and dirty hack is to override prefix in the port makefile:

FAKE_OPTS=	prefixhack

DESTDIR is occasionally called something different, the most common case being INSTALL_ROOT. Simply set the DESTDIRNAME variable in the port's makefile.

Broken DESTDIR Support

DESTDIR support can be tricky for authors to correctly implement. Subtle flaws can lead to broken ports. These are often difficult to track down and fix, as it requires to the port maintainer to learn the software package's installation scheme.

Packages that use automake normally "just work". However, authors often forget about DESTDIR in hand made targets. Any such target will have to be patched.

If your package wants to run a binary to generate files during an install, this may need to be moved to a pkg-install script. This depends on if the binary in question is expecting to run after the final installation. There are no hard and fast rules here, as the port's maintainer you'll have to use your judgement. If you need your path to include fake installed binaries, set the bin option: FAKE_OPTS= bin

Sometimes a package will expect to be able to link to its shared libraries at some point in the install. This will fail as the linker has no knowledge of the FAKE_DESTDIR, nor should it. Set the libs option to add the right information to the fake environment: FAKE_OPTS= libs

Most packages will not let you override both DESTDIR and PREFIX (note uppercase). However, if your package does, you will need to set the trueprefix option, as PREFIX is normally faked to ${FAKE_DESTDIR}${PREFIX}.

Binary Ports

Binary ports are often a problem because they use non-standard installation schemes. They are often a bit too cute; a bit too hacky. It may it end up being easier to make a do-install target than to dive in and modify an installation script.

GNUstep Ports

We have upgraded to gnustep-make 2.0, which has excellent DESTDIR support. However gnustep-make 2 does not create a library_paths.openapp file. This file has not be used in years and its removal is a good idea; just be sure to remove it from the plist as well.

Minor Notes

Never run a configure script with the fake destdir. The software package may include that path somewhere, and once it is installed in the final destination things will break.

Port makefiles used to have to reproduce the steps of pkg_add, for example run pkg-install scripts or display a pkg-message. Makefiles should no longer do this.

Most of the sub-systems (for example the linux-rpm or python sub-systems) have been updated to work properly with fake. Some are not yet moved over however. If you encounter such a sub-system consult with the ctriv@ before committing any fix.

If your linux port is installing with the wrong permissions, make sure you have the most recent version of cpio.