Gentoo Logo

Gentoo/Alt Contributor's Guide

Content:

A. Gentoo/Alt Contributor's Guide

1. Gentoo/Alt Policy

1.a. Intra-policy

Patches

Warning: This text is still a draft, with probably big grammar problems. The policies here stated needs to be completed and decided upon. While this warning is in place, don't take anything here as an official policy!

Patches added to the overlay (and to portage) should follow some basic policies, thought to simplify the process of merging them upstream, without breaking stuff. This allows to drop the patches when new versions are released.

The first important step is to make sure that the patch applies unconditionally, this means that after applying the patch, the sources works fine on every system, and not just the one you're patching for, and also that when adding code to workaround system problems, it should be protected with the right checks (preprocessor or autoconf) so that they don't get in the way when they are not needed.

Patches that changes entirely the building system of a package are usually discouraged, try to find a compromise with upstream developers, also if that would mean having an unusable package in the time being.

Behavior changes

All the behavior changes that might affect Gentoo Linux users must always be announced on gentoo-alt at least, and on gentoo-dev if they might affect development practices.

The behavior changes should also be tested on the gentoo-alt overlay so that it doesn't hit the normal users before testing.

2. Gentoo/Alt Overlay

2.a. The Overlay

Reasoning behind

Important: This guide is still a draft. It does not contain true policies about the use of the overlay as they are not being delineated yet,

Gentoo/Alt projects often need to change current ebuilds to let them know about their userland, libc or what else. These changes can be non-trivial, and should usually be hold until the maintainer of the ebuild can take a look to the patches and make sure that they works as intended.

The drawback is that then Gentoo/Alt users can't make use of the ebuilds on the fly, and developers might try to do the same thing more than one time as they might not know what the other developers worked on.

The overlay idea is took from Gentoo/FreeBSD, that used the overlay to apply patches that involved, for example, malloc patches, userland checks and other things that should have been reviewed before going into main tree.

In and Out

The overlay is intended to work as a cache of ebuilds while they are being tested (for totally new packages) or while the patches are being reviewed by ebuild maintainers.

In the case of packags that goes on the overlay just to wait for review by ebuilds maintainers, their addition should be direct, with obviously the same name of the original package. It's usually better, if the patch is trivial, to open a bug and note that in the ChangeLog for the overlaid package just before adding the package to the overlay itself, unless the patches needs to be tested for a while before submitting them to the ebuild maintainer.

As soon as a patch is merged in main tree, the ebuilds in the overlay needs to go, to avoid having unneeded ebuilds there. It's also important to have the ebuilds be in sync with the main tree in case of revision bumps.

Where

For developers, the overlay is available on Gentoo's Subversion repositories in svn+ssh://username@svn.gentoo.org/var/svnroot/gentoo-alt/trunk/overlay. It's not restricted, so please don't go over other's changes without notifying before, unless they causes problem on all the systems. Always try to get a solution that does work for every project while changes the minimum quantity of code.

As the overlay is intended to be used by users, too, daily snapshots can be found on mirrors as /experimental/snapshots/portage-alt-overlay-latest.tar.bz2. The daily snapshot can be fetched and used as portage overlay, and should be safe to be used in both Gentoo/Alt and Gentoo/Linux systems, also if might happen that the overlay interfere with Gentoo/Linux. In case that happens, remember to contact Gentoo/Alt developers so that the issues can be checked and resolved.

2.b. Development

Committing

One of the reasons why Subversion was chosen instead of CVS is that it supports atomic commits, does not expand keywords (like $Header: $) and so we can use it without using a two-step commit for manifests.

For this reason, the third line of ebuilds is safe to remain $Header: $ so that it will be safe when it's being moved to main portage.

When committing, it's important to use echangelog, also if it's an overlay to state the reasons why the ebuild is being changed. It's simple to write a bash function to get the commit done at one time:

Code Listing 2.1: Bash function to commit to Subversion

svncommit() {
  [[ -n $(echo *.ebuild) ]] && { echangelog "$@" }
  ebuild $(ls *.ebuild | head -n 1) manifest || return 1
  svn ci -m "$@" || return 1
}

Repoman still has a couple of issues when used in overlays, especially with Subversion, and with extra categories, as it's being done on Gentoo/Alt, but these things can be easily fixed in the future, and are just side problems.

echangelog still does not support Subversion-reposited ebuilds, so until it supports them fully, its output will be a bit limited, not telling when files are added and when are removed. It also returns a failure error to the caller, so it can't be checked against for failures.

Distfiles

Because ebuilds in the overlay are public to the users, their distfiles should be present in the mirrors. As the overlay ebuilds are not parsed by mirroring scripts, the distfiles loaded directly into the local dev.gentoo.org distfiles directory will be removed when "dead" distfiles are removed.

To avoid having the distfiles removed, especially for tarballs that was created ad-hoc, it's important to whitelist the extra files. To do so, log into dev.gentoo.org and open the /space/distfiles-whitelist/current file. There, place one by line all the files you put or are going to put in the mirrors that should not be removed. The whitelist lasts for six months.

3. Gentoo/Alt Technotes Guide

3.a. General Structure

Handling Users

There are differences between users in a Gentoo/Linux system and the ones in other Gentoo/Alt systems. These differences are usually a side problem that does not invalidate most of the work. Still, it's better to pay attention.

The first thing to check is to never use the root group. The group with id 0, called root on Linux is instead wheel on BSD and Darwin, (and probably other classical unices); while wheel group on Linux has GID 10. When you need to set the default permissions on a file (or a series of files), you should then use the command chown root:0 file instead, so that it takes the right permissions.

Important: This is the only one case where you should refer to a group or an user with its numeric ID instead of the name.

For every other case you should always use the name of groups and users, avoiding specifying them by ID as they can have different IDs on different systems.

Also, it's important to note that every ebuild that makes references to specific users and groups, should add them with enewgroup and enewuser, if it does not depend on the ebuild that adds them. So for example, cronbase adds cron user and group, as they can not be present on the users' systems.

It's not rare to create users that cannot login on a system. To do so, on Linux, the shell of those users is set to /bin/false. Unfortunately, this does not work on BSD-derived systems like Gentoo/*BSD and Gentoo/Darwin, as they use a more sofisticated approach, and /bin/false does not exists. enewuser function provide a simple way to create a disabled user: just use -1 as the shell for the newly created user, this way the function will take care of selecting the right shell for the disabled user, making use of /sbin/nologin where that is present (*BSD, Darwin and Linux using app-admin/nologin) or falling back to /bin/false when nothing else can be used.

Note: As of now eneweruser function fails when using /bin/false or any other direct "disabled" shell as shell for the user, forcing the ebuild developers to use -1 as it should be.

If you need to find out the home directory for a given user, you can't rely on the format of /etc/passwd or on the output of egetent, as they are different on FreeBSD and OSX. To avoid this, the egethome function (provided by portability eclass, but available inheriting eutils), returns the right field making sure that is the home directory for the user:

Code Listing 1.1: egethome usage

inherit eutils
...
homedir=$(egethome charlie)

3.b. Applications

Bash and shells

Bash is the default shell of Gentoo Linux, and it's on top of this that ebuilds are written. Because of this, Gentoo/Alt projects provides bash in their base system, as /bin/bash.

Ebuilds and scripts can use bashisms without problems as bash is provided, but in case of scripts, it's important that the first line reads as #!/bin/bash instead of just #!/bin/sh, to make sure that they are being executed with bash. The same goes for calling scripts from inside ebuilds, sh somescript is deprecated in favor of bash somescript so that bash is called for sure.

While bash should take care of managing [ .. ] tests, it's anyway suggested to use [[ .. ]] to run tests also when quoting the arguments correctly. This way, the tests are guarranteed to be expanded by bash internally and do not get executed by /bin/[ instead.

GNU tools and non-GNU userlands

Gentoo/Alt projects, a part from Gentoo GNU/kFreeBSD, aims to have a complete system that uses native versions of all the system's tools, of libc, and so on. However, there are some part of Gentoo's base system that does not work with BSD-like tools (not because they are broken, just because they are strictly POSIX). To work around this problem, we install a series of GNU tools g-prefixed. In a Gentoo/Alt system profile, you can always find these tools: GNU sed (as gsed), GNU make (as gmake), GNU awk (as gawk), GNU patch (as gpatch) GNU diff (as gdiff) and usually GNU cmp (as cmp, for compatibility with a couple other scripts). If you need GNU-style find command, you can also install findutils package that provides gfind and gxargs.

To allow users who prefers the GNU-style tools be comfortable, there is an ebuild sys-apps/userland-gnu that depends on coreutils and other GNU packages, that are always g-prefixed, and then links them inside /usr/libexec/gnu without the g-prefix. After adding them to $PATH, it's possible to use GNU tools in command line.

It's always preferred to use just the POSIX options, to be able to run the same script identical on Gentoo/Linux and Gentoo/Alt. In case you cannot rewrite the code not to use the GNU extensions, just add a dependency over the right package that provides the tool, and then do a simple test:

  1. Check for the g-prefixed tool
  2. Check that it works as expected for a GNU tool (usually this means that it accepts version option and reports GNU, FSF or the name of the package there)

And then select the right one you need.

Important: Inside an ebuild there are a few aliases that are used to make sure that they doen't break apart, so calling make, sed, patch and awk will call the GNU version of the tools.

Warning: The GNU tools' aliases works only if the tools are called by themselves, they won't work inside scripts called by the ebuild, and they won't work if called by find .. -exec or by xargs. In those cases, it's usually better to check for the right tool to call. An important exception is the usage of the sed command to call GNU sed: being widely used and difficult to check or fix, Portage 2.1_pre9 and later provides a wrapper script that calls GNU sed in any case, when used from ebuilds, if the $ESED variable is not set, in which case the called sed will be the one there indicated. This allows the usage of BSD sed when building BSD packages for instance.

To help with porting, there are a few constructs that are usually used out of habit that need to be fixed:

  1. cp -a: this is a GNUism, as the -a option is not present on POSIX cp. Its replacement is told to be -dpPR, but -d is not posix itself, so -pPR is what you should replace -a.
  2. cp --parents: this other GNUism is used to copy a series of files from a tree maintaining their prefix. There's no equivalent option in BSD userland, so this should be avoided. If you need this, instead use the treecopy function in portability eclass, that works exactly as a cp --parents -pPR call.
  3. seq doesn't exist on BSD userland, but there's a quick replacement: jot. Unfortunately its syntax is too variable, and poses a problem to manage. To avoid this, portability eclass has a seq function replacement that calls jot with the right parameters when called on a BSD userland. Still, make sure you're not trying to use some extra options to seq

Note: The -d option does not make a difference in almost all the cases, as it counts only when you have symlinks directly on the command line argument.

Using pmake

There are a few packages that require the use of pmake (parallel make, by NetBSD, the package we use is from Debian) to build on GNU userland, as the makefiles are incompatible with GNU make. As the name of this flavor of make varies depending on the userland you're in (it's pmake on GNU userland, bsdmake in Darwin userland and simply make in BSD userland. To avoid this trouble, you can use get_bmake function from portability eclass.

Code Listing 2.1: using get_bmake

DEPEND="virtual/pmake"
...

src_compile() {
    $(get_bmake) || die "make failed"
}

If the package builds using ports-like interface, as done by FreeBSD system packages, bsdmk eclass (currently on Gentoo/Alt overlay) provides a simple way to handle the knobs: just add to ${mymakeopts} the list of knobs to pass during the pkg_setup() function, and then call mkmake and mkinstall to compile and install the packages as specified.

Note about different make

As the make command changes name depending on the system where it's being used, there is an important thing to keep in mind: recursive makefiles are often used to build subdirectories of a source tree, but sometimes they calls directly a new make command. This breaks when the makefiles are called with other versions.

To avoid this problem all the modern make commands sets an automatic variable $(MAKE) that carries the name of the command used to launch the make chain. Instead of calling a generic make, all the makefiles should then call $(MAKE) to be safe with different naming of the command.

Another fortunately less common problem is when a package decides that $(MAKE) is not an automatic variable and try to overwrite it to set to something else than what it is by default. This usually breaks compilation.

Both kind of errors requires patches to the original sources, that should be sent upstream as usual.

3.c. Programming

Linking to dlopen()

On glibc-based systems, the dlopen() function and other functions to handle run-time dynamic linking resides in the libdl library that must be linked explicitly in the program. On BSD systems instead those functions are provided by libc.

Some software does not check if it needs to link to libdl and always links to it. This breaks on Gentoo/*BSD systems. To avoid this, autotool-ed projects can use a simple m4 macro, that can be found in gentoo-alt/m4s module (derived from xine-lib's macro collection) in the dl.m4 file.

This simple AM_DL macro added to configure.ac (or configure.in) takes care of looking for the right library to link to, and sets DYNAMIC_LD_LIBS. Add that to the LIBADD variable for the target and it will work fine on both glibc-based and BSD-derived systems.

For packages that do not have a build system that can be fixed to recognize whether libdl is needed, it's possible to use the dlopen_lib function in the portability eclass. This function will return -ldl where present, and nothing where it is not present, so one could use:

Code Listing 3.1: using $(dlopen_lib)

append-ldflags $(dlopen_lib)

To make sure it gets linked where needed.

Linkers issues

A practice that can be an issue for Gentoo/Alt projects is assuming that the linker that will be used to build a package is GNU and provided by binutils. Some operating systems like Darwin uses another kind of linker that is not completely compatible with the GNU one.

The most common error is to add --with-gnu-ld to the list of arguments used to call econf. This is superfluos, as autoconf is smart enough to figure out by itself when it's using GNU ld and when not. It also breaks when the ld is not GNU as expected.

Another problem is with linking of suid binaries. Gentoo Linux guidelines tell to link them with -Wl,-z,now option to get a non-lazy binding. Unfortunately this option - while supported by many other linkers - is not always called this way. To avoid this problem, you can use the bindnow-flags function (in flag-o-matic eclass), that finds the flags to append to have the non-lazy binding on the current linker.

Code Listing 3.2: appending flags for now binding

inherit flag-o-matic
...
  append-flags $(bindnow-flags)

As appending those flags is not always the best solution, it's usually preferred to patch the sources to use those flags just when linking the suid binaries. This can be tricky to allow use of non-GNU linkers. The solution is to use an undefined macro BINDNOW_FLAGS, and then either export the variabile in src_compile or use it to call the emake command.

Code Listing 3.3: example of emake call when overriding bindnow flags

inherit flag-o-matic
...
  emake BINDNOW_FLAGS="$(bindnow-flags)" || die "emake failed"

malloc.h Header

Some time ago, on some systems, in order to have the malloc() function, you had to include the malloc.h header. Currently, this header is deprecated and should not be included, instead the stdlib.h header is enough to get the right prototype for the function.

When using glibc or uclibc, including malloc.h just adds stdlib.h to includes. On other systems it simply does not exist. On FreeBSD, malloc.h exists, but it is a "trap". It basically throws a compilation error, stopping the build process. This can be discouraging for users, but it's a good way to know what software needs to be fixed to not try to include that file.

There are two simple ways to deal with this problem:

  • Remove the line that includes malloc.h and prepare a patch for upstream devs (if needed, add stdlib.h to the includes, to have malloc's definition)
  • Add a test for malloc.h in configure.ac (or configure.in), and protect the inclusion with a #ifdef HAVE_MALLOC_H .. #endif block, it works because the #error call bails out the preprocessor as well.

The first way is preferred, as malloc.h is a deprecated header and should not be used, although some projects that have to deal with very very very old systems would like to protect it with an additional check, even if this means having to deal with a longer configure stage.

Locale Libraries

One of the most used components in GNU software is gettext, a tool that allows the creation of i18n-capable packages (library and programs) with a relatively small amount of work and non-intrusive changes. Unfortunately, during the past years, the way gettext was integrated into GNU/Linux systems changed, creating a problem with Gentoo/FreeBSD now. Originally, the needed intl functions were always provided by gettext itself. Howerver, recent versions of GNU libc provides them inside the standard library itself, thus not requiring anymore the linking to libintl as is required for system using other libc's.

Similarly, libiconv is a GNU library that provides ways to convert text between different characters encodings. Its functions used to be always be provided always by libiconv, but now they are also embedded inside GNU libc. gettext, to provide its functionalities, uses libiconv; at the same time, libiconv can use gettext to proivde i18n support for itself. This is not a problem for GNU libc users, as both libintl and libiconv are inside libc, but it's a problem for non-glibc systems as this would add a circular depedency. To avoid this, nls support in libiconv is forcefully disabled.

Almost every package that depends on libiconv/gettext and uses autotools has already support to link to the right libraries on non-glibc systems. Unfortunately, this is not always enough: gettext guide states what the packages must do to make NLS support optional, but this is not always followed as intended, and intl functions are called also if NLS is disabled during configure stage, causing failure in linking on non-glibc systems (this doesn't appear as a problem on glibc systems, as the functions are always available on libc, and it doesn't need to be linked against, while on systems where libiconv and libintl are used it needs to be explicitely linked against that). This can be simply avoided protecting under #ifdef ENABLE_NLS .. #endif blocks the calls to setlocale(), testdomain() and other intl functions. This way, they will be called only when gettext is requested and linked against.

There's then the opposite problem: when building with NLS support, some packages fail with undefined references to functions like libintl_gettext. This happens because the package does not really add the variables to link against to the linking command, that is, it misses to link to libintl when the functions are not provided by the libc. For autotooled packages the library that contains the library to link against for libintl_* functions is LTLIBINTL, while the one for libiconv_* function is LTLIBICONV. Don't be confused by the LT prefix, those are not dependent on libtool presence, but rather means that libintl/libiconv were built with libtool, so passes -L${libdir} -lintl commandline instead of pointing directly to the .so file.

Code Listing 3.4: Makefile.am that links correctly against libintl

..
somebinary_LDADD = $(LTLIBINTL)
..

The way gettext and libiconv are used by some GNU software, with respect to generic software, actually adds a couple more problems to Gentoo/*BSD systems. Packages like tar, gettext, glib2 and libiconv themselves create, for some reason, a ${libdir}/charset.alias. This file is going to have collisions with every package that creates one, so this will not be a good thing. The solution is to let libiconv install the only instance of it, and remove it from every other package, that's why some packages have one rm -f /usr/$(get_libdir)/charset.alias line. Remember that the -f is needed, as the file won't be created by Gentoo/Linux with glibc.

Another problem can be defining the dependencies for packages. It's always a bit of a problem knowing if gettext must be a runtime dependency or just a build time dependency, and whether it is related to the nls USE flag or not. On a glibc-based system gettext is a build-time dependency if nls USE flag is enabled (and the package does not regenerate autotools support files), or an unconditional build-time dependency when autopoint needs to be run. On a non-glibc system, gettext is also a run-time dependency when building with nls useflag enabled. While currently gettext and libiconv are in the list of system packages for Gentoo/*BSD ports, the complete dependencies should be stated as:

Code Listing 3.5: gettext dependancy sample

RDEPEND="nls? ( virtual/libintl )"
DEPEND="nls? ( sys-devel/gettext )"

Obviously this is true when nls USE flag is present and is honored by both the ebuild and the configure script. However, please remember that --disable-nls presence on configure --help does not always mean that nls support can be disabled or is even present.

Similarly, the packages that uses the iconv() function and thus requires libiconv package when building on non-GLIBC systems, have to depend on virtual/libiconv, that doesn't add extra dependencies on GLIBC users but satisfy the dependencies for non-GLIBC users.

yacc and byacc

Other packages that needs special treatment for Gentoo/*BSD are yacc and byacc. Their sources are present inside the base system of FreeBSD and others BSD, but they are different from the original yacc/byacc, so it's better to use these versions, more updated than the ones released and in portage.

For this reason, when a package depends on yacc or byacc, it should put a || ( ) dependency with the package providing the same command on FreeBSD: sys-freebsd/freebsd-ubin.

If that dependency becomes widespread, a new virtual would be proposed.

Code Listing 3.6: Dependencies for a package needing yacc.

DEPEND="...
    || ( dev-util/yacc sys-freebsd/freebsd-ubin )"

4. Starting a Gentoo/Alt port

4.a. Introduction

Preamble

Starting a new Gentoo/Alt port is not too difficult, when you know how to do it and what needs to be considered. This guide will explain the basic generic steps needed to start the porting work.

Because of the Linux nature or the base of Gentoo/Alt structure, some of the internals are based on an Unix-like structure, while the QA checks on the compiled binaries are done considering ELF binaries as result. Tweaking of these checks is a complex process and needs to be done with the help of the devs who wrote those checks. For this reason, they won't be treated in this guide.

There are quite a few decision that one should start looking at when starting a new Gentoo/Alt project, as therea are many different parameters that might change the way the changes should be made. For every decision, this guide will try to provide a selection of problems and solution to them, trying to give help for every case.

You probably can try to port Gentoo/Alt on different conditions than the ones explained here. They are just general guidelines to explain how the things were done on current working ports.

Support

It's usually useful, when creating a new port, to get in touch with the other developers working on Gentoo/Alt. This can be done through the gentoo-alt mailing list or through the channel #gentoo-alt on Freenode network.

Mailing list and IRC channel are a good way to ask for solution to problems that are not treated in this guide (because of difference in the environment or simply because they were not present a tthe time of writing), and to follow the development of common decision inside and outside the project.

Also, if you're going to use Gentoo Portage for your port, you probably also want to watch the alt@gentoo.org mail alias on Bugzilla to see what is going on with portability of most ebuilds or scripts or other things that you might encounter in your process.

Choices

There are many choices one have to do when starting a Gentoo/Alt project. The first and probably most important one is to choose if making a primary package manager or a secondary. The first case is what is being done by Gentoo/FreeBSD, while the latter is what is being done by Gentoo/OSX.

After deciding this there are other things that should be consdiered, starting, for example, from the kind of init system you want to use, if you want to just use the one used by your operating system, or replace it with the one used by Gentoo Linux.

Every decision has its own rights and wrongs, and they should always be chosen carefully. Sometimes it's also possible to provide different implementations that allow the user to select what wants to do.

Defining the userland

Just one decision should be done as soon as possible and should be notified to Gentoo/Alt mailing list and developers, and regards the userland. Every system has its own native userland, sometimes using options different than other userlands.

The most clear distinction is between GNU userland, used by almost every Linux-based distribution, and the BSD userland, used by FreeBSD and other BSDs. The ${USERLAND} variable used by Gentoo representes the set of commands used by the base system and their options handling. For example, in a BSD userland, the GNU packages installs with a g- prefix, and the non prefixed commands are BSD, accepting a different range of options and arguments.

Note: The name of the userlands is quite arbitrary, so a GNU userland is actually the userland as it is in a default Gentoo Linux installation.

When defining a new value for ${USERLAND}, you should send an email to gentoo-alt mailing list telling what it represents, which difference there are between that and the default "GNU" userland, and who provides the basic commands like make, sed, awk, patch, tar. This means that a given userland might use GNU make as make, but still use GNU sed as gsed (this is actually done by Darwin userland).

The userland selection will change the way things will be installed afterwards and also the way some part of Portage will behave, so please choice carefully what you want to set and declare.

Note: Some commands that interacts with the kernel, such as ifconfig and ps, are considered part of the userland. This is not exact, but it's a way to make sure that their user interface is consistent with the rest of the system. Ports of GNU userland on other operating systems should make sure that they can provide equivalent commands with similar syntaxes to the ones used on Linux.

4.b. Porting as primary manager

What does it mean

A primary package manager is a package manager that takes care of every file, library and dependency of the package it manages. When creating a port that is a primary package manager, every file present in the system must be managed by portage itself.

There are many reasons why not every port can be a primary package manager. To do that, you need to have access to the sources of all the operating system and be able to patch them, usually. This means that you cannot create a primary package manager for a proprietary operating system where you don't have the sources for the base system. In those cases, you must rely on the secondary package management.

The primary package management is what Portage born to do, and what Gentoo Linux does. Adapting Portage to be the primary package manager in another operating system, when you have sources, it's usually simple enough to be feasible without too much hacking, and should be considered the starting point for projects that wants to create a secondary package manager.

How to bootstrap

With the term bootstrap this guide will usually refer to the process of creating the first base from where to start doing the port work for portage code, ebuilds and eclasses. While a bootstrapped system is not a complete Gentoo system, it should be able to install many packages with a simple emerge command. From such a system you can usually create a stage, that will be the actual starting point for new Gentoo/Alt systems.

The bootstrap process is sometimes tricky, as it requires to patch, compile and tweak many packages by hand. It also might require to be done once per version of the operating system, and also once per hardware architecture you want to add, if the sources are not cross-compilable (and also in that case, it can be tricky as Portage has very little crosscompile support).

The first thing to do is installing the dependencies of Portage itself, this means Python, bash, GNU make, GNU sed, GNU awk and GNU patch. Depending on what your "classic" userland uses for them, you might need to install them with a g- prefix, making them gmake, gsed, gawk and gpatch.

Note: Unless you're going to work on a GNU/* project, such as GNU/Hurd or GNU/kFreeBSD, is usually suggested to leave the native userland of your operating system as default. Who wants to have the GNU syntax on basic commands while being at user can then make use of sys-devel/userland-gnu ebuild, that installs symlinks to GNU-like commands in /usr/libexec/gnu, so that users can simply add that to path to have a GNU-like interface.

Additionally, you might want to install also rsync to be able to get the portage tree with emerge sync command. This is not mandatory, though, as you can work on the first steps using a NFS-mounted tree or simply downloading a snapshot of the tree to work on. This way is also suggested to be able to get easily the difference between the original ebuilds and the ones edited to let them work on your system, when needed.

Python is the critical part, as it needs to be patched with the same patches that are applied by the ebuild itself. Please refer to the latest ebuild in Portage to get the updated patches and make sure they are applied before building and installing it. Also, it should be installed on /usr, not in /usr/local as it defaults.

Bash is instead a quite simple package. The only note to this is that, while many systems can install bash as an extra package, and then install its binary in /usr/bin, that won't work easily on Gentoo/Alt projects, so it should be installed as /bin/bash. This path is important as many scripts and other things in portage refers to that directly.

The other packages (GNU make, GNU sed, GNU awk and GNU patch) are quite simple to handle. They can be installed in /usr/local, while it's suggested to install them in /usr as an ebuild would do. The only thing is that, if you decide to prefix them with g-, you should run the ./configure in a slighly different way.

Code Listing 2.1: calling ./configure for GNU make, GNU sed, GNU akw or GNU patch

The --program-prefix option is only necessary when you want to g-prefix them
./configure --prefix=/usr --program-prefix=g

Once you built and installed all those packages, you can start installing Portage itself. Right now, Portage package does not have an installation script nor it is autotooled, so you need to install it by hand. Depending on the version currently in portage, you might be needed to patch the source tarball. For both the patches and the installation procedure, it's highly suggested to refer to the ebuild for that version of Portage itself.

To run Portage, you anyway need a few things to clean up before. The first thing is adding a portage user and group. This group should have uid/gid set at 250. Also, for many things you need a wheel group. This group is used on BSD derived system insetad of the root group used by Linux and Solaris. If the operating system under which you're porting Portage does not have a wheel group, add one with either gid 0 or 10 (the first is an alias to root group, as done by BSDs, the latter is instead the wheel replacement used on Linux).

Dealing with library naming changes (ELF only)

Note: This part is specific to ELF only targets as it involves ELF shared objects, if your port does not use ELF binaries, you can skip this entirely.

There's one thing that might be tricky when starting a port for a totally open source operating system, if that uses so-called contrib packages, like libraries and similar, in other words libraries developed by other open source projects and released separately, used inside the system sources with the sources copied verbatim: when using the same library by the standalone package, it might change soname from the version in the operating system.

A little explanation: the soname is the internal name of the library, used by the dynamic loader to know that the library is the right one (that is, it uses the right ABI) for the executable is loading. Usually the soname corresponds either to the whole name of the library (libfoo.so.3.4) or to the name with the first version stated (libfoo.so.3.4). Most of the dynamic linkers doesn't really take in consideration that the soname is the same, but uses the soname to look up the file on disk.

Especially on *BSD based systems, the libraries are named with a single version after the .so extension, while on GNU-based systems or with a GNU setting in libtool, the name is with two or three parts, to avoid breaking the linkage of executables for every minor update of the library that does not really break the ABI.

When doing the bootstrap of a system that uses this setup, you'll end up with packages pointing to libraries named in a different way than the same libraries in portage. For instance a default FreeBSD 5.4 install will have libiconv.so.4 while portage will install libiconv.so.2.3. To solve these problems, after making sure the version of the library is the same or that the ABI is compatible (no missing symbols), you can do some symlinks to let the dynamic loader to load the new library (2.3). These hacks has to be removed after the whole system is re-emerged, so that they are not needed in the final stage.

Things to change in Portage and eclasses

There are a few things that usually needs to be checked when porting Portage on a new operating system. The most important one is the ldconfig and its way to update the libraries path. Portage uses ldconfig inside env-update script to tell the dynamic loader where to look for libraries.

As the syntax and the way ldconfig work varies vastly on different operating systems, this must be changed in portage itself. This must be looked at with the help of Portage developers, and can be discussed on gentoo-alt mailing list.

Another important thing is to update enewuser, enewgroup, egetent and egethome functions in eutils.eclass and portability.eclass. Those functions are used to create new users and new group, to get data about existing users and groups, and to get the home directory for a given user. They users ${CHOST} variable to find out how to do that, so you need to add a value for your own value.

If your operating system uses a linker (ld) different from GNU's one, you should also add it to the bindnow_flags function inside flag-o-matic.eclass, and you're suggested to improve the nowbinding.m4 macro file to select the right flags. The flags used for "bindnow" binding are used to avoid lazy binding of libraries on setuid binaries. Please refer to your own linker manual to find which flag should be used.

Print

Page updated May 2, 2006

Summary: Documents related to Gentoo/Alt testing, including procedures and AT application process.

Michael Kohl
Author/Editor

Diego Pettenò
Author

Chris White
Editor

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.