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:
- Check for the g-prefixed tool
- 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:
-
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.
-
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.
-
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 |
./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.
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-2.5 license. The Gentoo Name and Logo Usage Guidelines apply.
|