automake-patches
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]