1 @node Supporting Relocation
2 @section Supporting Relocation
4 It has been a pain for many users of GNU packages for a long time that
5 packages are not relocatable. It means a user cannot copy a program,
6 installed by another user on the same machine, to his home directory,
7 and have it work correctly (including i18n). So many users need to go
8 through @code{configure; make; make install} with all its
9 dependencies, options, and hurdles.
11 Red Hat, Debian, and similar package systems solve the ``ease of
12 installation'' problem, but they hardwire path names, usually to
13 @file{/usr} or @file{/usr/local}. This means that users need root
14 privileges to install a binary package, and prevents installing two
15 different versions of the same binary package.
17 A relocatable program can be moved or copied to a different location
18 on the file system. It is possible to make symlinks to the installed
19 and moved programs, and invoke them through the symlink. It is
20 possible to do the same thing with a hard link @emph{only} if the hard
21 link file is in the same directory as the real program.
23 The @code{relocatable-prog} module aims to ease the process of making a
24 GNU program relocatable. It helps overcome two obstacles. First, it aids
25 with relocating the hard-coded references to absolute file names that
26 GNU programs often contain. These references must be fixed up at
27 runtime if a program is to be successfully relocated. The
28 @code{relocatable-prog} module provides a function @code{relocate} that
31 Second, the loader must be able to find shared libraries linked to
32 relocatable executables or referenced by other shared libraries linked
33 to relocatable executables. The @code{relocatable-prog} module helps out
34 here in a platform-specific way:
38 On GNU/Linux, it adds a linker option (@option{-rpath}) that causes
39 the dynamic linker to search for libraries in a directory relative to
40 the location of the invoked executable.
43 On other Unix systems, it installs a wrapper executable. The wrapper
44 sets the environment variable that controls shared library searching
45 (usually @env{LD_LIBRARY_PATH}) and then invokes the real executable.
47 This approach does not always work. On OpenBSD and OpenServer,
48 prereleases of Libtool 1.5 put absolute file names of libraries in
49 executables, which prevents searching any other locations.
52 On Windows, the executable's own directory is searched for libraries,
53 so installing shared libraries into the executable's directory is
57 You can make your program relocatable by following these steps:
61 Import the @code{relocatable-prog} module.
64 In every program, add to @code{main} as the first statement (even
65 before setting the locale or doing anything related to libintl):
68 set_program_name (argv[0]);
71 The prototype for this function is in @file{progname.h}.
74 Everywhere where you use a constant pathname from installation-time,
75 wrap it in @code{relocate} so it gets translated to the run-time situation.
79 bindtextdomain (PACKAGE, LOCALEDIR);
86 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
89 The prototype for this function is in @file{relocatable.h}.
92 If your package installs shell scripts, also import the
93 @code{relocatable-script} module. Then, near the beginning of each
94 shell script that your package installs, add the following:
98 if test "@@RELOCATABLE@@" = yes; then
99 exec_prefix="@@exec_prefix@@"
101 orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables
102 func_find_curr_installdir # determine curr_installdir
104 # Relocate the directory variables that we use.
106 echo "$gettext_dir/" \
107 | sed -e "s%^$@{orig_installprefix@}/%$@{curr_installprefix@}/%" \
112 You must adapt the definition of @code{orig_installdir}, depending on
113 where the script gets installed. Also, at the end, instead of
114 @code{gettext_dir}, transform those variables that you need.
117 In your @file{Makefile.am}, for every program @command{foo} that gets
118 installed in, say, @file{$(bindir)}, you add:
121 foo_CPPFLAGS = -DINSTALLDIR=\"$(bindir)\"
122 if RELOCATABLE_VIA_LD
123 foo_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(bindir)`
128 You may also need to add a couple of variable assignments to your
131 If your package (or any package you rely on, e.g.@: gettext-runtime)
132 will be relocated together with a set of installed shared libraries,
133 then set @var{RELOCATABLE_LIBRARY_PATH} to a colon-separated list
134 of those libraries' directories, e.g.
136 RELOCATABLE_LIBRARY_PATH='$(libdir)'
139 If your @file{config.h} is not in @file{$(top_builddir)}, then set
140 @var{RELOCATABLE_CONFIG_H_DIR} to its directory, e.g.
142 RELOCATABLE_CONFIG_H_DIR='$(top_builddir)/src'
146 Set @var{RELOCATABLE_STRIP} to @code{:}. This is needed so that
147 @samp{make install} installs executables without stripping them.