[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: new FAQ entry: don't user hard-coded paths
From: |
Alexandre Duret-Lutz |
Subject: |
FYI: new FAQ entry: don't user hard-coded paths |
Date: |
Sat, 12 Feb 2005 22:24:22 +0100 |
User-agent: |
Gnus/5.110003 (No Gnus v0.3) Emacs/21.3.50 (gnu/linux) |
I'm installing this on HEAD and branch-1-9.
This is essentially an formated copy of this mail
http://lists.gnu.org/archive/html/bug-automake/2005-01/msg00153.html
from a thread that started here
http://lists.gnu.org/archive/html/bug-automake/2004-12/msg00106.html
2005-02-12 Alexandre Duret-Lutz <address@hidden>
* automake.in (read_am_file): Define variable containing long
* doc/automake.texi (Hard-Coded Install Paths): New node.
(Extending, Extending aclocal, Python): Link to it.
(Extending): Don't show how to install a file in /etc/ directly,
this is insane.
Index: doc/automake.texi
===================================================================
RCS file: /cvs/automake/automake/doc/automake.texi,v
retrieving revision 1.44.2.37
diff -u -r1.44.2.37 automake.texi
--- doc/automake.texi 8 Feb 2005 21:41:53 -0000 1.44.2.37
+++ doc/automake.texi 12 Feb 2005 21:22:53 -0000
@@ -254,6 +254,7 @@
* renamed objects:: Why are object files sometimes renamed?
* Per-Object Flags:: How to simulate per-object flags?
* Multiple Outputs:: Writing rules for tools with many output files
+* Hard-Coded Install Paths:: Installing to Hard-Coded Locations
History of Automake
@@ -1971,6 +1972,11 @@
aclocal_DATA = mymacro.m4 myothermacro.m4
@end example
address@hidden
+Please do use @file{$(datadir)/aclocal}, and not something based on
+the result of @code{aclocal --print-ac-dir}. @xref{Hard-Coded Install
+Paths}, for arguments.
+
A file of macros should be a series of properly quoted
@code{AC_DEFUN}'s (@pxref{Macro Definitions, , , autoconf, The
Autoconf Manual}). The @command{aclocal} programs also understands
@@ -5330,7 +5336,8 @@
that the user can run @code{make prefix=/foo install}. The Autoconf
manual has a section with more details on this topic
(@pxref{Installation Directory Variables, , Installation Directory
-Variables, autoconf, The Autoconf Manual}).
+Variables, autoconf, The Autoconf Manual}). See also @ref{Hard-Coded
+Install Paths}.
@node Documentation
@@ -7018,12 +7025,17 @@
use @code{uninstall-local}. It doesn't make sense to uninstall just
data or just executables.
-For instance, here is one way to install a file in @file{/etc}:
+For instance, here is one way to erase a subdirectory during
address@hidden clean} (@pxref{Clean}).
address@hidden
-install-data-local:
- $(INSTALL_DATA) $(srcdir)/afile $(DESTDIR)/etc/afile
address@hidden example
address@hidden
+clean-local:
+ -rm -rf testSubDir
address@hidden smallexample
+
+Older version of this manual used to show how to use
address@hidden to install a file to some hard-coded
+location, but you should avoid this. (@pxref{Hard-Coded Install Paths})
@cindex @code{-hook} targets
@cindex hook targets
@@ -7412,6 +7424,7 @@
* renamed objects:: Why are object files sometimes renamed?
* Per-Object Flags:: How to simulate per-object flags?
* Multiple Outputs:: Writing rules for tools with many output files
+* Hard-Coded Install Paths:: Installing to Hard-Coded Locations
@end menu
@node CVS
@@ -8433,6 +8446,135 @@
portable, but they can be convenient in packages that assume GNU
@command{make}.
+
address@hidden Hard-Coded Install Paths
address@hidden Installing to Hard-Coded Locations
+
address@hidden
+My package needs to install some configuration file. I tried to use
+the following rule, but @code{make distcheck} fails. Why?
+
address@hidden
+# Do not do this.
+install-data-local:
+ $(INSTALL_DATA) $(srcdir)/afile $(DESTDIR)/etc/afile
address@hidden example
address@hidden display
+
address@hidden
+My package needs to populate the installation directory of another
+package at install-time. I can easily compute that installation
+directory in @file{configure}, but if I install files therein,
address@hidden distcheck} fails. How else should I do?
address@hidden display
+
+These two setups share their symptoms: @code{make distcheck} fails
+because they are installing files to hard-coded paths. In the later
+case the path is not really hard-coded in the package, but we can
+consider it to be hard-coded in the system (or in whichever tool that
+supplies the path). As long as the path does not use any of the
+standard directory variables (@code{$(prefix)}, @code{$(bindir)},
address@hidden(datadir)}, etc.), the effect will be the same:
+user-installations are impossible.
+
+When a (non-root) user wants to install a package, he usually has no
+right to install anything in @code{/usr} or @code{/usr/local}. So he
+does something like @code{./configure --prefix ~/usr} to install
+package in his own @code{~/usr} tree.
+
+If a package attempts to install something to some hard-coded path
+(e.g., @file{/etc/afile}), regardless of this @code{--prefix} setting,
+then the installation will fail. @code{make distcheck} performs such
+a @code{--prefix} installation, hence it will fail too.
+
+Now, there are some easy solutions.
+
+The above @code{install-data-local} example for installing
address@hidden/etc/afile} would be better replaced by
+
address@hidden
+sysconf_DATA = afile
address@hidden smallexample
+
address@hidden
+by default @code{sysconfdir} will be @code{$(prefix)/etc}, because
+this is what the GNU Standards require. When such a package is
+installed on a FHS compliant system, the installer will have to set
address@hidden/etc}. As the maintainer of the package you
+should not be concerned by such site policies: use the appropriate
+standard directory variable to install your files so that installer
+can easily redefine these variables to match their site conventions.
+
+Installing files that should be used by another package, is slightly
+more involved. Let's take an example and assume you want to install
+shared library that is a Python extension module. If you ask Python
+where to install the library, it will answer something like this:
+
address@hidden
+% @kbd{python -c 'from distutils import sysconfig;
+ print sysconfig.get_python_lib(1,0)'}
+/usr/lib/python2.3/site-packages
address@hidden example
+
+If you indeed use this absolute path to install your shared library,
+non-root users will not be able to install the package, hence
+distcheck fails.
+
+Let's do better. The @code{sysconfig.get_python_lib()} function
+actually accepts a third argument that will replace Python's
+installation prefix.
+
address@hidden
+% @kbd{python -c 'from distutils import sysconfig;
+ print sysconfig.get_python_lib(1,0,"address@hidden@}")'}
address@hidden@}/lib/python2.3/site-packages
address@hidden example
+
+You can also use this new path. If you do
address@hidden @bullet
address@hidden
+root users can install your package with the same @code{--prefix}
+as Python (you get the behavior of the previous attempt)
+
address@hidden
+non-root users can install your package too, they will have the
+extension module in a place that is not searched by Python but they
+can work around this using environment variables (and if you installed
+scripts that use this shared library, it's easy to tell Python were to
+look in the beginning of your script, so the script works in both
+cases).
address@hidden itemize
+
+The @code{AM_PATH_PYTHON} macro uses similar commands to define
address@hidden(pythondir)} and @code{$(pyexecdir)} (@pxref{Python}).
+
+Of course not all tools are as advanced as Python regarding that
+substitution of @var{prefix}. So another strategy is to figure the
+part of the of the installation directory that must be preserved. For
+instance here is how @code{AM_PATH_LISPDIR} (@pxref{Emacs Lisp})
+computes @code{$(lispdir)}:
+
address@hidden
+$EMACS -batch -q -eval '(while load-path
+ (princ (concat (car load-path) "\n"))
+ (setq load-path (cdr load-path)))' >conftest.out
+lispdir=`sed -n \
+ -e 's,/$,,' \
+ -e
'/.*\/lib\/x*emacs\/site-lisp$/@{s,.*/lib/\(x*emacs/site-lisp\)$,address@hidden@}/\1,;p;q;@}'
\
+ -e
'/.*\/share\/x*emacs\/site-lisp$/@{s,.*/share/\(x*emacs/site-lisp\),address@hidden@}/\1,;p;q;@}'
\
+ conftest.out`
address@hidden example
+
+I.e., it just picks the first directory that looks like
address@hidden/lib/*emacs/site-lisp} or @file{*/share/*emacs/site-lisp} in
+the search path of emacs, and then substitutes @address@hidden@}} or
address@hidden@address@hidden appropriately.
+
+The emacs case looks complicated because it processes a list and
+expect two possible layouts, otherwise it's easy, and the benefit for
+non-root users are really worth the extra @command{sed} invocation.
+
+
@node History
@chapter History of Automake
--
Alexandre Duret-Lutz
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: new FAQ entry: don't user hard-coded paths,
Alexandre Duret-Lutz <=