mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2025-08-17 12:41:05 +03:00
The change causes makeinfo 5.2 to fail: env LANG= LC_MESSAGES= LC_ALL= LANGUAGE= makeinfo --no-split --reference-limit=2000 gnulib.texi ./relocatable-maint.texi:153: misplaced { ... Escaping the braces as per the attached patch seems to fix this.
206 lines
6.7 KiB
Plaintext
206 lines
6.7 KiB
Plaintext
@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 other binary distributions 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:
|
|
|
|
@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-prog} 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
|
|
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
|
|
@code{DEPENDS_ON_LIBCHARSET}
|
|
|
|
@item libiconv
|
|
@code{DEPENDS_ON_LIBICONV}
|
|
|
|
@item libintl
|
|
@code{DEPENDS_ON_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.
|
|
|
|
@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 () @{
|
|
echo "$1/" \
|
|
| sed -e "s%^$@{orig_installprefix@}/%$@{curr_installprefix@}/%" \
|
|
| sed -e 's,/$,,'
|
|
@}
|
|
else
|
|
relocate () @{
|
|
echo "$1"
|
|
@}
|
|
fi
|
|
|
|
# Get some relocated directory names.
|
|
sysconfdir=`relocate "@@sysconfdir@@"`
|
|
some_datadir=`relocate "@@datadir@@/something"`
|
|
@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{sysconfdir} and @code{some_datadir}, transform those variables
|
|
that you need.
|
|
|
|
@item
|
|
If your package installs Perl scripts, also import the
|
|
@code{relocatable-perl} module. Then, near the beginning of each
|
|
Perl script that your package installs, add the following:
|
|
|
|
@example
|
|
@@relocatable_pl@@
|
|
if ("@@RELOCATABLE@@" eq "yes") @{
|
|
my $exec_prefix = "@@exec_prefix@@";
|
|
my $orig_installdir = "@@bindir@@"; # see Makefile.am's *_SCRIPTS variables
|
|
my ($orig_installprefix, $curr_installprefix) = find_prefixes($orig_installdir, find_curr_installdir());
|
|
sub relocate @{ # the subroutine is defined whether or not the enclosing block is executed
|
|
my ($dir) = @@_;
|
|
if ("@@RELOCATABLE@@" eq "yes") @{
|
|
$dir =~ s%^$orig_installprefix/%$curr_installprefix/%;
|
|
$dir =~ s,/$,,;
|
|
@}
|
|
return $dir;
|
|
@}
|
|
@}
|
|
|
|
# Get some relocated directory names.
|
|
$sysconfdir = relocate("@@sysconfdir@@");
|
|
$some_datadir = relocate(@@datadir@@/something");
|
|
@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{sysconfdir} and @code{some_datadir}, 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_CPPFLAGS = -DINSTALLDIR=\"$(bindir)\"
|
|
if RELOCATABLE_VIA_LD
|
|
foo_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(bindir)`
|
|
endif
|
|
@end example
|
|
|
|
@item
|
|
You may also need to add a couple of 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
|