view doc/relocatable-maint.texi @ 14450:fdc55132bd6b

Tests for module 'unictype/joiningtype-byname'. * modules/unictype/joiningtype-byname-tests: New file. * tests/unictype/test-joiningtype_byname.c: New file.
author Bruno Haible <>
date Mon, 21 Mar 2011 22:58:36 +0100
parents 09288814c405
line wrap: on
line source

@node Supporting Relocation
@section Supporting Relocation

It has been a pain for many users of GNU packages for a long time that
packages are not relocatable.  It means a user cannot copy a program,
installed by another user on the same machine, to his home directory,
and have it work correctly (including i18n).  So many users need to go
through @code{configure; make; make install} with all its
dependencies, options, and hurdles.

Red Hat, Debian, and similar package systems solve the ``ease of
installation'' problem, but they hardwire path names, usually to
@file{/usr} or @file{/usr/local}.  This means that users need root
privileges to install a binary package, and prevents installing two
different versions of the same binary package.

A relocatable program can be moved or copied to a different location
on the file system.  It is possible to make symlinks to the installed
and moved programs, and invoke them through the symlink. It is
possible to do the same thing with a hard link @emph{only} if the hard
link file is in the same directory as the real program.

The @code{relocatable-prog} module aims to ease the process of making a
GNU program relocatable.  It helps overcome two obstacles.  First, it aids
with relocating the hard-coded references to absolute file names that
GNU programs often contain.  These references must be fixed up at
runtime if a program is to be successfully relocated.  The
@code{relocatable-prog} module provides a function @code{relocate} that
does this job.

Second, the loader must be able to find shared libraries linked to
relocatable executables or referenced by other shared libraries linked
to relocatable executables.  The @code{relocatable-prog} module helps out
here in a platform-specific way:

On GNU/Linux, it adds a linker option (@option{-rpath}) that causes
the dynamic linker to search for libraries in a directory relative to
the location of the invoked executable.

On other Unix systems, it installs a wrapper executable.  The wrapper
sets the environment variable that controls shared library searching
(usually @env{LD_LIBRARY_PATH}) and then invokes the real executable.

This approach does not always work.  On OpenBSD and OpenServer,
prereleases of Libtool 1.5 put absolute file names of libraries in
executables, which prevents searching any other locations.

On Windows, the executable's own directory is searched for libraries,
so installing shared libraries into the executable's directory is
@end itemize

You can make your program relocatable by following these steps:

Import the @code{relocatable-prog} module.

In every program, add to @code{main} as the first statement (even
before setting the locale or doing anything related to libintl):

set_program_name (argv[0]);
@end example

The prototype for this function is in @file{progname.h}.

Everywhere where you use a constant pathname from installation-time,
wrap it in @code{relocate} so it gets translated to the run-time situation.

bindtextdomain (PACKAGE, LOCALEDIR);
@end example


bindtextdomain (PACKAGE, relocate (LOCALEDIR));
@end example

The prototype for this function is in @file{relocatable.h}.

The @code{set_program_name} function can also configure some
additional libraries to relocate files that they access, by defining
corresponding C preprocessor symbols to 1.  The libraries for which
this is supported and the corresponding preprocessor symbols are:

@table @asis
@item libcharset

@item libiconv

@item libintl
@end table

Defining the symbol for a library makes every program in the package
depend on that library, whether the program really uses the library or
not, so this feature should be used with some caution.

If your package installs shell scripts, also import the
@code{relocatable-script} module.  Then, near the beginning of each
shell script that your package installs, add the following:

if test "@@RELOCATABLE@@" = yes; then
  orig_installdir="$bindir" # see's *_SCRIPTS variables
  func_find_curr_installdir # determine curr_installdir
  # Relocate the directory variables that we use.
    echo "$gettext_dir/" \
    | sed -e "s%^$@{orig_installprefix@}/%$@{curr_installprefix@}/%" \
    | sed -e 's,/$,,'`
@end example

You must adapt the definition of @code{orig_installdir}, depending on
where the script gets installed.  Also, at the end, instead of
@code{gettext_dir}, transform those variables that you need.

In your @file{}, for every program @command{foo} that gets
installed in, say, @file{$(bindir)}, you add:

foo_CPPFLAGS = -DINSTALLDIR=\"$(bindir)\"
@end example

You may also need to add a couple of variable assignments to your

If your package (or any package you rely on, e.g.@: gettext-runtime)
will be relocated together with a set of installed shared libraries,
then set @var{RELOCATABLE_LIBRARY_PATH} to a colon-separated list
of those libraries' directories, e.g.
@end example

If your @file{config.h} is not in @file{$(top_builddir)}, then set
@var{RELOCATABLE_CONFIG_H_DIR} to its directory, e.g.
@end example
@end enumerate