round, roundf: Avoid compiler warning in configure test.
[gnulib.git] / doc / relocatable-maint.texi
blob50b446bcffc4f4adc1bfa49f13a5e6d25300db50
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 other binary distributions 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
29 does this job.
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:
36 @itemize
37 @item
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.
42 @item
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.
51 @item
52 On Windows, the executable's own directory is searched for libraries,
53 so installing shared libraries into the executable's directory is
54 sufficient.
55 @end itemize
57 You can make your program relocatable by following these steps:
59 @enumerate
60 @item
61 Import the @code{relocatable-prog} module.
63 @item
64 In every program, add to @code{main} as the first statement (even
65 before setting the locale or doing anything related to libintl):
67 @example
68 set_program_name (argv[0]);
69 @end example
71 The prototype for this function is in @file{progname.h}.
73 @item
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.
76 Example:
78 @example
79 bindtextdomain (PACKAGE, LOCALEDIR);
80 @end example
82 @noindent
83 becomes:
85 @example
86 bindtextdomain (PACKAGE, relocate (LOCALEDIR));
87 @end example
89 The prototype for this function is in @file{relocatable.h}.
91 There is also a variant of this function, named @code{relocate2}, that
92 makes it easy to reclaim the memory allocated by the call.
94 @item
95 The @code{set_program_name} function can also configure some
96 additional libraries to relocate files that they access, by defining
97 corresponding C preprocessor symbols to 1.  The libraries for which
98 this is supported and the corresponding preprocessor symbols are:
100 @table @asis
101 @item libcharset
102 @code{DEPENDS_ON_LIBCHARSET}
104 @item libiconv
105 @code{DEPENDS_ON_LIBICONV}
107 @item libintl
108 @code{DEPENDS_ON_LIBINTL}
109 @end table
111 Defining the symbol for a library makes every program in the package
112 depend on that library, whether the program really uses the library or
113 not, so this feature should be used with some caution.
115 @item
116 If your package installs shell scripts, also import the
117 @code{relocatable-script} module.  Then, near the beginning of each
118 shell script that your package installs, add the following:
120 @example
121 @@relocatable_sh@@
122 if test "@@RELOCATABLE@@" = yes; then
123   exec_prefix="@@exec_prefix@@"
124   bindir="@@bindir@@"
125   orig_installdir="$bindir" # see Makefile.am's *_SCRIPTS variables
126   func_find_curr_installdir # determine curr_installdir
127   func_find_prefixes
128   relocate () @{
129     echo "$1/" \
130     | sed -e "s%^$@{orig_installprefix@}/%$@{curr_installprefix@}/%" \
131     | sed -e 's,/$,,'
132   @}
133 else
134   relocate () @{
135     echo "$1"
136   @}
139 # Get some relocated directory names.
140 sysconfdir=`relocate "@@sysconfdir@@"`
141 some_datadir=`relocate "@@datadir@@/something"`
142 @end example
144 You must adapt the definition of @code{orig_installdir}, depending on
145 where the script gets installed.  Also, at the end, instead of
146 @code{sysconfdir} and @code{some_datadir}, transform those variables
147 that you need.
149 @item
150 If your package installs Perl scripts, also import the
151 @code{relocatable-perl} module.  Then, near the beginning of each
152 Perl script that your package installs, add the following:
154 @example
155 @@relocatable_pl@@
156 if ("@@RELOCATABLE@@" eq "yes") @{
157   my $exec_prefix = "@@exec_prefix@@";
158   my $orig_installdir = "@@bindir@@"; # see Makefile.am's *_SCRIPTS variables
159   my ($orig_installprefix, $curr_installprefix) = find_prefixes($orig_installdir, find_curr_installdir());
160   sub relocate @{ # the subroutine is defined whether or not the enclosing block is executed
161     my ($dir) = @@_;
162     if ("@@RELOCATABLE@@" eq "yes") @{
163       $dir =~ s%^$orig_installprefix/%$curr_installprefix/%;
164       $dir =~ s,/$,,;
165     @}
166     return $dir;
167   @}
170 # Get some relocated directory names.
171 $sysconfdir = relocate("@@sysconfdir@@");
172 $some_datadir = relocate(@@datadir@@/something");
173 @end example
175 You must adapt the definition of @code{$orig_installdir}, depending on
176 where the script gets installed.  Also, at the end, instead of
177 @code{sysconfdir} and @code{some_datadir}, transform those variables
178 that you need.
180 @item
181 In your @file{Makefile.am}, for every program @command{foo} that gets
182 installed in, say, @file{$(bindir)}, you add:
184 @example
185 foo_CPPFLAGS = -DINSTALLDIR=\"$(bindir)\"
186 if RELOCATABLE_VIA_LD
187 foo_LDFLAGS = `$(RELOCATABLE_LDFLAGS) $(bindir)`
188 endif
189 @end example
191 @item
192 You may also need to add a couple of variable assignments to your
193 @file{configure.ac}.
195 If your package (or any package you rely on, e.g.@: gettext-runtime)
196 will be relocated together with a set of installed shared libraries,
197 then set @var{RELOCATABLE_LIBRARY_PATH} to a colon-separated list
198 of those libraries' directories, e.g.
199 @example
200 RELOCATABLE_LIBRARY_PATH='$(libdir)'
201 @end example
203 If your @file{config.h} is not in @file{$(top_builddir)}, then set
204 @var{RELOCATABLE_CONFIG_H_DIR} to its directory, e.g.
205 @example
206 RELOCATABLE_CONFIG_H_DIR='$(top_builddir)/src'
207 @end example
208 @end enumerate