From 04f98d2deab1b909a33c9991ca33cb1d50e8ce65 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 1 Mar 2007 02:08:18 +0000 Subject: [PATCH] Documentation of 'relocatable' module - for maintainers. --- doc/relocatable-maint.texi | 142 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 doc/relocatable-maint.texi diff --git a/doc/relocatable-maint.texi b/doc/relocatable-maint.texi new file mode 100644 index 000000000..a8fce10ce --- /dev/null +++ b/doc/relocatable-maint.texi @@ -0,0 +1,142 @@ +@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 filesystem. 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} 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} 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} module helps out +here in a platform-specific way: + +@itemize +@item +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. + +@item +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. + +@item +On Windows, the executable's own directory is searched for libraries, +so installing shared libraries into the executable's directory is +sufficient. +@end itemize + +You can make your program relocatable by following these steps: + +@enumerate +@item +Import the @code{relocatable} module. + +@item +In every program, add to @code{main} as the first statement (even +before setting the locale or doing anything related to libintl): + +@example +set_program_name (argv[0]); +@end example + +The prototype for this function is in @file{progname.h}. + +@item +Everywhere where you use a constant pathname from installation-time, +wrap it in @code{relocate} so it gets translated to the run-time situation. +Example: + +@example +bindtextdomain (PACKAGE, LOCALEDIR); +@end example + +@noindent +becomes: + +@example +bindtextdomain (PACKAGE, relocate (LOCALEDIR)); +@end example + +The prototype for this function is in @file{relocatable.h}. + +@item +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: + +@example +@@relocatable_sh@@ +if test "@@RELOCATABLE@@" = yes; then + exec_prefix="@@exec_prefix@@" + bindir="@@bindir@@" + orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables + func_find_curr_installdir # determine curr_installdir + func_find_prefixes + # Relocate the directory variables that we use. + gettext_dir=`echo "$gettext_dir/" | sed -e +"s%^$@{orig_installprefix@}/%$@{curr_installprefix@}/%" | sed -e 's,/$,,'` +fi +@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. + +@item +In your @file{Makefile.am}, for every program @command{foo} that gets +installed in, say, @file{$(bindir)}, you add: + +@example +foo_CFLAGS = -DINSTALLDIR=\"$(bindir)\" +if RELOCATABLE_VIA_LD +foo_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(bindir)` +endif +@end example + +@item +You may also need to add one or two variable assignments to your +@file{configure.ac}. + +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. +@example +RELOCATABLE_LIBRARY_PATH='$(libdir)' +@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. +@example +RELOCATABLE_CONFIG_H_DIR='$(top_builddir)/src' +@end example +@end enumerate -- 2.11.0