From ed8daa069a6c8ed34f7856c42402ec46f305e670 Mon Sep 17 00:00:00 2001 From: Joshua Root Date: Tue, 18 May 2021 15:11:59 -0700 Subject: [PATCH] python: use Python's sys.prefix and sys.exec_prefix for PYTHON_PREFIX and PYTHON_EXEC_PREFIX; new configure options --with-python_prefix and --with-python_exec_prefix to set explicitly. This change fixes https://bugs.gnu.org/35322. * m4/python.m4 (AM_PATH_PYTHON): use Python's sys.prefix and sys.exec_prefix for PYTHON_PREFIX and PYTHON_EXEC_PREFIX, instead of $prefix and $exec_prefix. But use a variable reference to ${prefix} if it is contained within sys.prefix; similarly for exec_prefix. Also support new configure options to set explicitly. (PYTHON_PREFIX, PYTHON_EXEC_PREFIX): AC_SUBST these. (am_cv_python_pythondir): use our new $am_cv_python_prefix, substituting ${PYTHON_PREFIX}. (am_cv_python_pyexecdir): likewise. * doc/automake.texi (Python): PYTHON_PREFIX, PYTHON_EXEC_PREFIX, document new approach. * t/instmany-python.sh: set PYTHON_PREFIX as needed. * t/python-vars.sh (PYTHON_EXEC_PREFIX, PYTHON_PREFIX): also set from Python's sys.{exec_,}prefix; use ${PYTHON_{EXEC,}PREFIX} instead of ${exec_,}prefix. --- doc/automake.texi | 80 +++++++++++++++++++--------------- m4/python.m4 | 101 +++++++++++++++++++++++++++++++++++-------- t/instmany-python.sh | 16 +++---- t/python-vars.sh | 39 +++++++++-------- 4 files changed, 159 insertions(+), 77 deletions(-) diff --git a/doc/automake.texi b/doc/automake.texi index 8f5a9fcee..0accec82d 100644 --- a/doc/automake.texi +++ b/doc/automake.texi @@ -25,7 +25,7 @@ This manual is for GNU Automake (version @value{VERSION}, @value{UPDATED}), a program that creates GNU standards-compliant Makefiles from template files. -Copyright @copyright{} 1995--2020 Free Software Foundation, Inc. +Copyright @copyright{} 1995--2021 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -7801,31 +7801,34 @@ This variable is a shell expression that is used to set the Automake provides support for Python compilation with the @code{PYTHON} primary. A typical setup is to call -@code{AM_PATH_PYTHON} in @file{configure.ac} and use a line like the -following in @file{Makefile.am}: +@code{AM_PATH_PYTHON} in @file{configure.ac} and use a line like this +in @file{Makefile.am}: @example python_PYTHON = tree.py leave.py @end example -Any files listed in a @code{_PYTHON} variable will be byte-compiled -with @command{py-compile} at install time. @command{py-compile} -actually creates both standard (@file{.pyc}) and optimized -(@file{.pyo}) byte-compiled versions of the source files. Note that -because byte-compilation occurs at install time, any files listed in -@code{noinst_PYTHON} will not be compiled. Python source files are -included in the distribution by default; prepend @code{nodist_} (as in -@code{nodist_python_PYTHON}) to omit them. +Python source files are included in the distribution by default; +prepend @code{nodist_} (as in @code{nodist_python_PYTHON}) to omit +them. -Automake ships with an Autoconf macro called @code{AM_PATH_PYTHON} -that will determine some Python-related directory variables (see -below). If you have called @code{AM_PATH_PYTHON} from -@file{configure.ac}, then you may use the variables +@cindex @file{.pyc}, @file{.pyo} files +At install time, any files listed in a @code{_PYTHON} variable will be +byte-compiled with @command{py-compile}. @command{py-compile} creates +both standard (@file{.pyc}) and optimized (@file{.pyo}) byte-compiled +versions of the source files. Because byte-compilation occurs at +install time, files listed in @code{noinst_PYTHON} will not be +compiled. + +Automake ships with an Autoconf macro named @code{AM_PATH_PYTHON} that +determines some Python-related directory variables (see below). If +you have called @code{AM_PATH_PYTHON} from @file{configure.ac}, then +you may use the variables @c Keep in sync with primary-prefix-couples-documented-valid.sh -@code{python_PYTHON} or @code{pkgpython_PYTHON} to list Python source -files in your @file{Makefile.am}, depending on where you want your files -installed (see the definitions of @code{pythondir} and -@code{pkgpythondir} below). +@code{python_PYTHON} and @code{pkgpython_PYTHON} to list Python source +files in your @file{Makefile.am}, depending on whether you want your +files installed in @code{pythondir} or @code{pkgpythondir}, +respectively. @defmac AM_PATH_PYTHON (@ovar{version}, @ovar{action-if-found}, @ovar{action-if-not-found}) @@ -7839,15 +7842,15 @@ If an interpreter is found and satisfies @var{version}, then run. If @var{action-if-not-found} is not specified, as in the following -example, the default is to abort @command{configure}. +example, the default is to abort @command{configure}: @example -AM_PATH_PYTHON([2.2]) +AM_PATH_PYTHON([2.5]) @end example @noindent This is fine when Python is an absolute requirement for the package. -If Python >= 2.5 was only @emph{optional} to the package, +If Python @geq{} 2.5 was only @emph{optional} for the package, @code{AM_PATH_PYTHON} could be called as follows. @example @@ -7858,7 +7861,7 @@ If the @env{PYTHON} variable is set when @code{AM_PATH_PYTHON} is called, then that will be the only Python interpreter that is tried. @code{AM_PATH_PYTHON} creates the following output variables based on -the Python installation found during configuration. +the Python installation found during configuration: @end defmac @vtable @code @@ -7877,26 +7880,33 @@ AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :]) @end example @item PYTHON_VERSION +@vindex sys.version_info @r{Python variable} The Python version number, in the form @var{major}.@var{minor} -(e.g., @samp{2.5}). This is currently the value of +(e.g., @samp{2.5}). This is set to be the value of @samp{'%u.%u' % sys.version_info[:2]}. @item PYTHON_PREFIX -The string @samp{$@{prefix@}}. This term may be used in future work -that needs the contents of Python's @samp{sys.prefix}, but general -consensus is to always use the value from @command{configure}. - -@item PYTHON_EXEC_PREFIX -The string @samp{$@{exec_prefix@}}. This term may be used in future work -that needs the contents of Python's @samp{sys.exec_prefix}, but general -consensus is to always use the value from @command{configure}. +@itemx PYTHON_EXEC_PREFIX +@opindex --with-python_prefix +@opindex --with-python_exec_prefix +@vindex sys.prefix @r{Python variable} +@vindex sys.exec_prefix @r{Python variable} +The value of Python's @samp{sys.prefix} (resp.@: +@samp{sys.exec_prefix}) variable. Sometimes the same as the standard +@samp{$@{prefix@}} (@samp{$@{exec_prefix@}}), but differs on some +platforms such as Mac@tie{}OS@tie{}x (where Python is usually +installed as a Framework). Can be set explicitly with the +@option{--with-python_prefix} (@option{--with-python_exec_prefix}) +@file{configure} option. @item PYTHON_PLATFORM +@vindex sys.platform @r{Python variable} The canonical name used by Python to describe the operating system, as given by @samp{sys.platform}. This value is sometimes needed when building Python extensions. @item pythondir +@cindex @file{site-packages} Python directory The directory name for the @file{site-packages} subdirectory of the standard Python install tree. @@ -7922,9 +7932,9 @@ This is a convenience variable that is defined as @samp{$(pyexecdir)/$(PACKAGE)}. @end vtable -All of these directory variables have values that start with either -@samp{$@{prefix@}} or @samp{$@{exec_prefix@}} unexpanded. This works -fine in @file{Makefiles}, but it makes these variables hard to use in +All of these directory variables have values that can start with either +@samp{$@{prefix@}} or @samp{$@{exec_prefix@}}, unexpanded. This works +fine in @file{Makefile}s, but it makes these variables hard to use in @file{configure}. This is mandated by the GNU coding standards, so that the user can run @samp{make prefix=/foo install}. The Autoconf manual has a section with more details on this topic diff --git a/m4/python.m4 b/m4/python.m4 index b2302baa3..56d9eb2bb 100644 --- a/m4/python.m4 +++ b/m4/python.m4 @@ -3,7 +3,7 @@ ## From Andrew Dalke ## Updated by James Henstridge and other contributors. ## ------------------------ -# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -93,16 +93,83 @@ AC_DEFUN([AM_PATH_PYTHON], dnl version is not of interest. AC_CACHE_CHECK([for $am_display_PYTHON version], [am_cv_python_version], - [am_cv_python_version=`$PYTHON -c "import sys; print('%u.%u' % sys.version_info[[:2]])"`]) + [am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[[:2]])"`]) AC_SUBST([PYTHON_VERSION], [$am_cv_python_version]) - dnl Use the values of $prefix and $exec_prefix for the corresponding + dnl Use the values of sys.prefix and sys.exec_prefix for the corresponding dnl values of PYTHON_PREFIX and PYTHON_EXEC_PREFIX. These are made dnl distinct variables so they can be overridden if need be. However, dnl general consensus is that you shouldn't need this ability. + dnl Also allow directly setting the prefixes via configure args. - AC_SUBST([PYTHON_PREFIX], ['${prefix}']) - AC_SUBST([PYTHON_EXEC_PREFIX], ['${exec_prefix}']) + if test "x$prefix" = xNONE + then + am__usable_prefix=$ac_default_prefix + else + am__usable_prefix=$prefix + fi + + AC_ARG_WITH([python_prefix], + [AS_HELP_STRING([--with-python_prefix], + [override the default PYTHON_PREFIX])], + [ am_python_prefix_subst="$withval" + am_cv_python_prefix="$withval" + AC_MSG_CHECKING([for $am_display_PYTHON prefix]) + AC_MSG_RESULT([$am_cv_python_prefix])], + [ + AC_CACHE_CHECK([for $am_display_PYTHON prefix], [am_cv_python_prefix], + [am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"`]) + + dnl If sys.prefix is a subdir of $prefix, replace the literal value of $prefix + dnl with a variable reference so it can be overridden. + case $am_cv_python_prefix in + $am__usable_prefix*) + am__strip_prefix=`echo "$am__usable_prefix" | sed 's|.|.|g'` + am_python_prefix_subst=`echo "$am_cv_python_prefix" | sed "s,^$am__strip_prefix,\\${prefix},"` + ;; + *) + am_python_prefix_subst=$am_cv_python_prefix + ;; + esac + ]) + AC_SUBST([PYTHON_PREFIX], [$am_python_prefix_subst]) + + AC_ARG_WITH([python_exec_prefix], + [AS_HELP_STRING([--with-python_exec_prefix], + [override the default PYTHON_EXEC_PREFIX])], + [ am_python_exec_prefix_subst="$withval" + am_cv_python_exec_prefix="$withval" + AC_MSG_CHECKING([for $am_display_PYTHON exec_prefix]) + AC_MSG_RESULT([$am_cv_python_exec_prefix])], + [ + dnl --with-python_prefix was given - use its value for python_exec_prefix too + AS_IF([test -n "$with_python_prefix"], [am_python_exec_prefix_subst="$with_python_prefix" + am_cv_python_exec_prefix="$with_python_prefix" + AC_MSG_CHECKING([for $am_display_PYTHON exec_prefix]) + AC_MSG_RESULT([$am_cv_python_exec_prefix])], + [ + AC_CACHE_CHECK([for $am_display_PYTHON exec_prefix], [am_cv_python_exec_prefix], + [am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"`]) + dnl If sys.exec_prefix is a subdir of $exec_prefix, replace the + dnl literal value of $exec_prefix with a variable reference so it can + dnl be overridden. + if test "x$exec_prefix" = xNONE + then + am__usable_exec_prefix=$am__usable_prefix + else + am__usable_exec_prefix=$exec_prefix + fi + case $am_cv_python_exec_prefix in + $am__usable_exec_prefix*) + am__strip_prefix=`echo "$am__usable_exec_prefix" | sed 's|.|.|g'` + am_python_exec_prefix_subst=`echo "$am_cv_python_exec_prefix" | sed "s,^$am__strip_prefix,\\${exec_prefix},"` + ;; + *) + am_python_exec_prefix_subst=$am_cv_python_exec_prefix + ;; + esac + ])]) + AC_SUBST([PYTHON_EXEC_PREFIX], [$am_python_exec_prefix_subst]) dnl At times (like when building shared libraries) you may want dnl to know which OS platform Python thinks this is. @@ -140,11 +207,11 @@ except ImportError: dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON script directory], [am_cv_python_pythondir], - [if test "x$prefix" = xNONE + [if test "x$am_cv_python_prefix" = x then - am_py_prefix=$ac_default_prefix + am_py_prefix=$am__usable_prefix else - am_py_prefix=$prefix + am_py_prefix=$am_cv_python_prefix fi am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig @@ -157,13 +224,13 @@ sys.stdout.write(sitedir)"` case $am_cv_python_pythondir in $am_py_prefix*) am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` - am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,\\${PYTHON_PREFIX},"` ;; *) case $am_py_prefix in /usr|/System*) ;; *) - am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + am_cv_python_pythondir="\${PYTHON_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; @@ -182,30 +249,30 @@ sys.stdout.write(sitedir)"` dnl Query distutils for this directory. AC_CACHE_CHECK([for $am_display_PYTHON extension module directory], [am_cv_python_pyexecdir], - [if test "x$exec_prefix" = xNONE + [if test "x$am_cv_python_exec_prefix" = x then - am_py_exec_prefix=$am_py_prefix + am_py_exec_prefix=$am__usable_exec_prefix else - am_py_exec_prefix=$exec_prefix + am_py_exec_prefix=$am_cv_python_exec_prefix fi am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: - sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig - sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') sys.stdout.write(sitedir)"` case $am_cv_python_pyexecdir in $am_py_exec_prefix*) am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` - am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,\\${PYTHON_EXEC_PREFIX},"` ;; *) case $am_py_exec_prefix in /usr|/System*) ;; *) - am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + am_cv_python_pyexecdir="\${PYTHON_EXEC_PREFIX}/lib/python$PYTHON_VERSION/site-packages" ;; esac ;; diff --git a/t/instmany-python.sh b/t/instmany-python.sh index dce3594b5..8b90c78d0 100644 --- a/t/instmany-python.sh +++ b/t/instmany-python.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2008-2020 Free Software Foundation, Inc. +# Copyright (C) 2008-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -119,18 +119,18 @@ cd build test -n "$orig_INSTALL" $MAKE # Try whether native install (or install-sh) works. -$MAKE install +$MAKE install PYTHON_PREFIX="$instdir" test -n "$(find "$instdir" -name python1.py)" # Multiple uninstall should work, too. -$MAKE uninstall -$MAKE uninstall +$MAKE uninstall PYTHON_PREFIX="$instdir" +$MAKE uninstall PYTHON_PREFIX="$instdir" test $(find "$instdir" -type f -print | wc -l) -eq 0 # Try whether we don't exceed the low limit. PATH=$nPATH; export PATH -run_make INSTALL=my-install install +run_make INSTALL=my-install PYTHON_PREFIX="$instdir" install test -n "$(find "$instdir" -name python1.py)" -run_make INSTALL=my-install uninstall +run_make INSTALL=my-install PYTHON_PREFIX="$instdir" uninstall test $(find "$instdir" -type f -print | wc -l) -eq 0 PATH=$oPATH; export PATH @@ -143,14 +143,14 @@ for file in python3.py python$nfiles.py do chmod a-r $srcdir/$file test ! -r $srcdir/$file || skip_ "cannot drop file read permissions" - $MAKE install && exit 1 + $MAKE install PYTHON_PREFIX="$instdir" && exit 1 chmod u+r $srcdir/$file done for file in npython3.py npython$nfiles.py do chmod a-r $srcdir/$file - $MAKE install && exit 1 + $MAKE install PYTHON_PREFIX="$instdir" && exit 1 chmod u+r $srcdir/$file done diff --git a/t/python-vars.sh b/t/python-vars.sh index b53018b37..dedee0455 100644 --- a/t/python-vars.sh +++ b/t/python-vars.sh @@ -1,5 +1,5 @@ #! /bin/sh -# Copyright (C) 2011-2020 Free Software Foundation, Inc. +# Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -23,17 +23,17 @@ required=python # In case the user's config.site defines pythondir or pyexecdir. CONFIG_SITE=/dev/null; export CONFIG_SITE -# Update the definition below if the documentation changes. -# Note that the value of the 'pythondir' and 'pyexecdir' variables can -# vary among different python installations, so we need more relaxed -# and ad-hoc checks for them. Also, more proper "functional" checks -# on them should be done in the 'python-virtualenv.sh' test. +# Update the definition below if the documentation changes. The values +# of the 'pythondir' and 'pyexecdir' variables vary among different +# python installations, so we need more relaxed and ad-hoc checks for +# them. Also, more proper "functional" checks on them should be done in +# the 'python-virtualenv.sh' test. # # This version identification is duplicated in python.m4 (and the manual). -PYTHON_VERSION=$($PYTHON -c 'import sys; print("%u.%u" % sys.version_info[:2])') || exit 1 -PYTHON_PLATFORM=$($PYTHON -c 'import sys; print(sys.platform)') || exit 1 -PYTHON_EXEC_PREFIX='${exec_prefix}' -PYTHON_PREFIX='${prefix}' +PYTHON_VERSION=$($PYTHON -c 'import sys; print ("%u.%u" % sys.version_info[:2])') || exit 1 +PYTHON_PLATFORM=$($PYTHON -c 'import sys; print (sys.platform)') || exit 1 +PYTHON_EXEC_PREFIX=$($PYTHON -c 'import sys; print (sys.exec_prefix)') || exit 1 +PYTHON_PREFIX=$($PYTHON -c 'import sys; print (sys.prefix)') || exit 1 pkgpythondir="\${pythondir}/$me" pkgpyexecdir="\${pyexecdir}/$me" @@ -62,17 +62,17 @@ check-local: test-in test-am test-in: cat pythondir - case `cat pythondir` in '$${prefix}'/*);; *) exit 1;; esac + case `cat pythondir` in '$${PYTHON_PREFIX}'/*);; *) exit 1;; esac cat pyexecdir - case `cat pyexecdir` in '$${exec_prefix}'/*);; *) exit 1;; esac + case `cat pyexecdir` in '$${PYTHON_EXEC_PREFIX}'/*);; *) exit 1;; esac cat $(srcdir)/vars-exp cat $(builddir)/vars-got diff $(srcdir)/vars-exp $(builddir)/vars-got ## Note: this target's rules will be extended in the "for" loop below. test-am: - case '$(pythondir)' in '$(prefix)'/*);; *) exit 1;; esac - case '$(pyexecdir)' in '$(exec_prefix)'/*);; *) exit 1;; esac + case '$(pythondir)' in '$(PYTHON_PREFIX)'/*);; *) exit 1;; esac + case '$(pyexecdir)' in '$(PYTHON_EXEC_PREFIX)'/*);; *) exit 1;; esac END echo @pythondir@ > pythondir.in @@ -85,7 +85,7 @@ for var in $pyvars; do eval val=\$$var echo "var=$val" >> vars-exp echo "var=@$var@" >> vars-got.in - echo "${tab}test x'\$($var)' = x'$val'" >> Makefile.am + echo "${tab}test x'\$($var)' = x'$val' || test \"\$NO_CHECK_PYTHON_PREFIX\"" >> Makefile.am done cat Makefile.am @@ -98,10 +98,15 @@ for var in pythondir pyexecdir $pyvars; do grep "^$var *=" Makefile.in done +instdir=$(pwd)/inst + $AUTOCONF -./configure PYTHON="$PYTHON" +./configure --prefix="$instdir" PYTHON="$PYTHON" $MAKE test-in test-am -$MAKE distcheck +# This tries to install to $PYTHON_PREFIX, which may not be writable. +# Override it to something safe, but then of course we have to skip +# checking that it is what we originally set it to. +$MAKE distcheck PYTHON_PREFIX="$instdir" NO_CHECK_PYTHON_PREFIX=1 : -- 2.47.2