First (uncontroversial) part of issue 9807.

* Expose the build flags to Python as sys.abiflags
* Shared library libpythonX.Y<abiflags>.so
* python-config --abiflags
* Make two distutils tests that failed with --enable-shared (even before this
  patch) succeed.
* Fix a few small style issues.
This commit is contained in:
Barry Warsaw 2010-10-16 01:04:07 +00:00
parent d8d835bd1d
commit 8cf4eae522
9 changed files with 386 additions and 299 deletions

View file

@ -955,6 +955,11 @@ always available.
module for informational purposes; modifying this value has no effect on the module for informational purposes; modifying this value has no effect on the
registry keys used by Python. Availability: Windows. registry keys used by Python. Availability: Windows.
.. data:: abiflags
On POSIX systems where Python is build with the standard ``configure``
script, this contains the ABI flags as specified by :pep:`3149`.
.. rubric:: Citations .. rubric:: Citations
.. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf . .. [C99] ISO/IEC 9899:1999. "Programming languages -- C." A public draft of this standard is available at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf .

View file

@ -754,9 +754,9 @@ def get_libraries(self, ext):
else: else:
from distutils import sysconfig from distutils import sysconfig
if sysconfig.get_config_var('Py_ENABLE_SHARED'): if sysconfig.get_config_var('Py_ENABLE_SHARED'):
template = "python%d.%d" pythonlib = 'python{}.{}{}'.format(
pythonlib = (template % sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff,
(sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) sys.abiflags)
return ext.libraries + [pythonlib] return ext.libraries + [pythonlib]
else: else:
return ext.libraries return ext.libraries

View file

@ -1,17 +1,16 @@
import sys import sys
import os import os
import tempfile
import shutil import shutil
from io import StringIO from io import StringIO
from distutils.core import Extension, Distribution from distutils.core import Distribution
from distutils.command.build_ext import build_ext from distutils.command.build_ext import build_ext
from distutils import sysconfig from distutils import sysconfig
from distutils.tests.support import TempdirManager from distutils.tests.support import TempdirManager
from distutils.tests.support import LoggingSilencer from distutils.tests.support import LoggingSilencer
from distutils.extension import Extension from distutils.extension import Extension
from distutils.errors import (UnknownFileError, DistutilsSetupError, from distutils.errors import (
CompileError) CompileError, DistutilsSetupError, UnknownFileError)
import unittest import unittest
from test import support from test import support
@ -42,6 +41,20 @@ def setUp(self):
from distutils.command import build_ext from distutils.command import build_ext
build_ext.USER_BASE = site.USER_BASE build_ext.USER_BASE = site.USER_BASE
def _fixup_command(self, cmd):
# When Python was build with --enable-shared, -L. is not good enough
# to find the libpython<blah>.so. This is because regrtest runs it
# under a tempdir, not in the top level where the .so lives. By the
# time we've gotten here, Python's already been chdir'd to the
# tempdir.
#
# To further add to the fun, we can't just add library_dirs to the
# Extension() instance because that doesn't get plumbed through to the
# final compiler command.
if not sys.platform.startswith('win'):
library_dir = sysconfig.get_config_var('srcdir')
cmd.library_dirs = [('.' if library_dir is None else library_dir)]
def test_build_ext(self): def test_build_ext(self):
global ALREADY_TESTED global ALREADY_TESTED
xx_c = os.path.join(self.tmp_dir, 'xxmodule.c') xx_c = os.path.join(self.tmp_dir, 'xxmodule.c')
@ -49,6 +62,7 @@ def test_build_ext(self):
dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]}) dist = Distribution({'name': 'xx', 'ext_modules': [xx_ext]})
dist.package_dir = self.tmp_dir dist.package_dir = self.tmp_dir
cmd = build_ext(dist) cmd = build_ext(dist)
self._fixup_command(cmd)
if os.name == "nt": if os.name == "nt":
# On Windows, we must build a debug version iff running # On Windows, we must build a debug version iff running
# a debug build of Python # a debug build of Python
@ -235,7 +249,8 @@ def test_check_extensions_list(self):
cmd.finalize_options() cmd.finalize_options()
#'extensions' option must be a list of Extension instances #'extensions' option must be a list of Extension instances
self.assertRaises(DistutilsSetupError, cmd.check_extensions_list, 'foo') self.assertRaises(DistutilsSetupError,
cmd.check_extensions_list, 'foo')
# each element of 'ext_modules' option must be an # each element of 'ext_modules' option must be an
# Extension instance or 2-tuple # Extension instance or 2-tuple
@ -302,6 +317,7 @@ def test_get_outputs(self):
dist = Distribution({'name': 'xx', dist = Distribution({'name': 'xx',
'ext_modules': [ext]}) 'ext_modules': [ext]})
cmd = build_ext(dist) cmd = build_ext(dist)
self._fixup_command(cmd)
cmd.ensure_finalized() cmd.ensure_finalized()
self.assertEquals(len(cmd.get_outputs()), 1) self.assertEquals(len(cmd.get_outputs()), 1)

View file

@ -468,6 +468,8 @@ def test_attributes(self):
self.assertTrue(vi > (1,0,0)) self.assertTrue(vi > (1,0,0))
self.assertIsInstance(sys.float_repr_style, str) self.assertIsInstance(sys.float_repr_style, str)
self.assertIn(sys.float_repr_style, ('short', 'legacy')) self.assertIn(sys.float_repr_style, ('short', 'legacy'))
if not sys.platform.startswith('win'):
self.assertIsInstance(sys.abiflags, str)
def test_43581(self): def test_43581(self):
# Can't use sys.stdout, as this is a StringIO object when # Can't use sys.stdout, as this is a StringIO object when

View file

@ -36,6 +36,7 @@ AR= @AR@
RANLIB= @RANLIB@ RANLIB= @RANLIB@
SVNVERSION= @SVNVERSION@ SVNVERSION= @SVNVERSION@
SOABI= @SOABI@ SOABI= @SOABI@
LDVERSION= @LDVERSION@
GNULD= @GNULD@ GNULD= @GNULD@
@ -102,6 +103,7 @@ MANDIR= @mandir@
INCLUDEDIR= @includedir@ INCLUDEDIR= @includedir@
CONFINCLUDEDIR= $(exec_prefix)/include CONFINCLUDEDIR= $(exec_prefix)/include
SCRIPTDIR= $(prefix)/lib SCRIPTDIR= $(prefix)/lib
ABIFLAGS= @ABIFLAGS@
# Detailed destination directories # Detailed destination directories
BINLIBDEST= $(LIBDIR)/python$(VERSION) BINLIBDEST= $(LIBDIR)/python$(VERSION)
@ -445,7 +447,7 @@ $(LIBRARY): $(LIBRARY_OBJS)
$(AR) $(ARFLAGS) $@ $(MODOBJS) $(AR) $(ARFLAGS) $@ $(MODOBJS)
$(RANLIB) $@ $(RANLIB) $@
libpython$(VERSION).so: $(LIBRARY_OBJS) libpython$(LDVERSION).so: $(LIBRARY_OBJS)
if test $(INSTSONAME) != $(LDLIBRARY); then \ if test $(INSTSONAME) != $(LDLIBRARY); then \
$(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \
$(LN) -f $(INSTSONAME) $@; \ $(LN) -f $(INSTSONAME) $@; \
@ -566,6 +568,11 @@ Python/dynload_shlib.o: $(srcdir)/Python/dynload_shlib.c Makefile
-DSOABI='"$(SOABI)"' \ -DSOABI='"$(SOABI)"' \
-o $@ $(srcdir)/Python/dynload_shlib.c -o $@ $(srcdir)/Python/dynload_shlib.c
Python/sysmodule.o: $(srcdir)/Python/sysmodule.c Makefile
$(CC) -c $(PY_CORE_CFLAGS) \
-DABIFLAGS='"$(ABIFLAGS)"' \
-o $@ $(srcdir)/Python/sysmodule.c
$(IO_OBJS): $(IO_H) $(IO_OBJS): $(IO_H)
# Use a stamp file to prevent make -j invoking pgen twice # Use a stamp file to prevent make -j invoking pgen twice

View file

@ -6,7 +6,7 @@ import sys
import sysconfig import sysconfig
valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags',
'ldflags', 'extension-suffix', 'help'] 'ldflags', 'extension-suffix', 'help', 'abiflags']
def exit_with_usage(code=1): def exit_with_usage(code=1):
print("Usage: {0} [{1}]".format( print("Usage: {0} [{1}]".format(
@ -56,3 +56,6 @@ for opt in opt_flags:
elif opt == '--extension-suffix': elif opt == '--extension-suffix':
print(sysconfig.get_config_var('SO')) print(sysconfig.get_config_var('SO'))
elif opt == '--abiflags':
print(sys.abiflags)

View file

@ -1520,6 +1520,10 @@ _PySys_Init(void)
PyLong_FromVoidPtr(PyWin_DLLhModule)); PyLong_FromVoidPtr(PyWin_DLLhModule));
SET_SYS_FROM_STRING("winver", SET_SYS_FROM_STRING("winver",
PyUnicode_FromString(PyWin_DLLVersionString)); PyUnicode_FromString(PyWin_DLLVersionString));
#endif
#ifdef ABIFLAGS
SET_SYS_FROM_STRING("abiflags",
PyUnicode_FromString(ABIFLAGS));
#endif #endif
if (warnoptions == NULL) { if (warnoptions == NULL) {
warnoptions = PyList_New(0); warnoptions = PyList_New(0);

576
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -602,18 +602,23 @@ AC_MSG_RESULT($LIBRARY)
# #
# INSTSONAME is the name of the shared library that will be use to install # INSTSONAME is the name of the shared library that will be use to install
# on the system - some systems like version suffix, others don't # on the system - some systems like version suffix, others don't
#
# LDVERSION is the shared library version number, normally the Python version
# with the ABI build flags appended.
AC_SUBST(LDLIBRARY) AC_SUBST(LDLIBRARY)
AC_SUBST(DLLLIBRARY) AC_SUBST(DLLLIBRARY)
AC_SUBST(BLDLIBRARY) AC_SUBST(BLDLIBRARY)
AC_SUBST(LDLIBRARYDIR) AC_SUBST(LDLIBRARYDIR)
AC_SUBST(INSTSONAME) AC_SUBST(INSTSONAME)
AC_SUBST(RUNSHARED) AC_SUBST(RUNSHARED)
AC_SUBST(LDVERSION)
LDLIBRARY="$LIBRARY" LDLIBRARY="$LIBRARY"
BLDLIBRARY='$(LDLIBRARY)' BLDLIBRARY='$(LDLIBRARY)'
INSTSONAME='$(LDLIBRARY)' INSTSONAME='$(LDLIBRARY)'
DLLLIBRARY='' DLLLIBRARY=''
LDLIBRARYDIR='' LDLIBRARYDIR=''
RUNSHARED='' RUNSHARED=''
LDVERSION="$(VERSION)"
# LINKCC is the command that links the python executable -- default is $(CC). # LINKCC is the command that links the python executable -- default is $(CC).
# If CXX is set, and if it is needed to link a main function that was # If CXX is set, and if it is needed to link a main function that was
@ -724,18 +729,18 @@ if test $enable_shared = "yes"; then
AC_DEFINE(Py_ENABLE_SHARED, 1, [Defined if Python is built as a shared library.]) AC_DEFINE(Py_ENABLE_SHARED, 1, [Defined if Python is built as a shared library.])
case $ac_sys_system in case $ac_sys_system in
CYGWIN*) CYGWIN*)
LDLIBRARY='libpython$(VERSION).dll.a' LDLIBRARY='libpython$(LDVERSION).dll.a'
DLLLIBRARY='libpython$(VERSION).dll' DLLLIBRARY='libpython$(LDVERSION).dll'
;; ;;
SunOS*) SunOS*)
LDLIBRARY='libpython$(VERSION).so' LDLIBRARY='libpython$(LDVERSION).so'
BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(VERSION)' BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)'
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
INSTSONAME="$LDLIBRARY".$SOVERSION INSTSONAME="$LDLIBRARY".$SOVERSION
;; ;;
Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*) Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*)
LDLIBRARY='libpython$(VERSION).so' LDLIBRARY='libpython$(LDVERSION).so'
BLDLIBRARY='-L. -lpython$(VERSION)' BLDLIBRARY='-L. -lpython$(LDVERSION)'
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
case $ac_sys_system in case $ac_sys_system in
FreeBSD*) FreeBSD*)
@ -747,27 +752,27 @@ if test $enable_shared = "yes"; then
hp*|HP*) hp*|HP*)
case `uname -m` in case `uname -m` in
ia64) ia64)
LDLIBRARY='libpython$(VERSION).so' LDLIBRARY='libpython$(LDVERSION).so'
;; ;;
*) *)
LDLIBRARY='libpython$(VERSION).sl' LDLIBRARY='libpython$(LDVERSION).sl'
;; ;;
esac esac
BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(VERSION)' BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)'
RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH} RUNSHARED=SHLIB_PATH=`pwd`:${SHLIB_PATH}
;; ;;
OSF*) OSF*)
LDLIBRARY='libpython$(VERSION).so' LDLIBRARY='libpython$(LDVERSION).so'
BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(VERSION)' BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(LDVERSION)'
RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH}
;; ;;
Darwin*) Darwin*)
LDLIBRARY='libpython$(VERSION).dylib' LDLIBRARY='libpython$(LDVERSION).dylib'
BLDLIBRARY='-L. -lpython$(VERSION)' BLDLIBRARY='-L. -lpython$(LDVERSION)'
RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}' RUNSHARED='DYLD_LIBRARY_PATH=`pwd`:${DYLD_LIBRARY_PATH}'
;; ;;
AIX*) AIX*)
LDLIBRARY='libpython$(VERSION).so' LDLIBRARY='libpython$(LDVERSION).so'
RUNSHARED=LIBPATH=`pwd`:${LIBPATH} RUNSHARED=LIBPATH=`pwd`:${LIBPATH}
;; ;;
@ -776,7 +781,7 @@ else # shared is disabled
case $ac_sys_system in case $ac_sys_system in
CYGWIN*) CYGWIN*)
BLDLIBRARY='$(LIBRARY)' BLDLIBRARY='$(LIBRARY)'
LDLIBRARY='libpython$(VERSION).dll.a' LDLIBRARY='libpython$(LDVERSION).dll.a'
;; ;;
esac esac
fi fi
@ -823,7 +828,8 @@ if test -z "$LN" ; then
fi fi
# For calculating the .so ABI tag. # For calculating the .so ABI tag.
SOABI_QUALIFIERS="" AC_SUBST(ABIFLAGS)
ABIFLAGS=""
# Check for --with-pydebug # Check for --with-pydebug
AC_MSG_CHECKING(for --with-pydebug) AC_MSG_CHECKING(for --with-pydebug)
@ -836,7 +842,7 @@ then
[Define if you want to build an interpreter with many run-time checks.]) [Define if you want to build an interpreter with many run-time checks.])
AC_MSG_RESULT(yes); AC_MSG_RESULT(yes);
Py_DEBUG='true' Py_DEBUG='true'
SOABI_QUALIFIERS="${SOABI_QUALIFIERS}d" ABIFLAGS="${ABIFLAGS}d"
else AC_MSG_RESULT(no); Py_DEBUG='false' else AC_MSG_RESULT(no); Py_DEBUG='false'
fi], fi],
[AC_MSG_RESULT(no)]) [AC_MSG_RESULT(no)])
@ -2473,7 +2479,7 @@ AC_ARG_WITH(pymalloc,
if test -z "$with_pymalloc" if test -z "$with_pymalloc"
then then
with_pymalloc="yes" with_pymalloc="yes"
SOABI_QUALIFIERS="${SOABI_QUALIFIERS}m" ABIFLAGS="${ABIFLAGS}m"
fi fi
if test "$with_pymalloc" != "no" if test "$with_pymalloc" != "no"
then then
@ -3586,7 +3592,7 @@ AH_TEMPLATE(Py_UNICODE_SIZE,
case "$unicode_size" in case "$unicode_size" in
4) 4)
AC_DEFINE(Py_UNICODE_SIZE, 4) AC_DEFINE(Py_UNICODE_SIZE, 4)
SOABI_QUALIFIERS="${SOABI_QUALIFIERS}u" ABIFLAGS="${ABIFLAGS}u"
;; ;;
*) AC_DEFINE(Py_UNICODE_SIZE, 2) ;; *) AC_DEFINE(Py_UNICODE_SIZE, 2) ;;
esac esac
@ -3635,10 +3641,16 @@ AC_C_BIGENDIAN
# would get a shared library ABI version tag of 'cpython-32dmu' and shared # would get a shared library ABI version tag of 'cpython-32dmu' and shared
# libraries would be named 'foo.cpython-32dmu.so'. # libraries would be named 'foo.cpython-32dmu.so'.
AC_SUBST(SOABI) AC_SUBST(SOABI)
AC_MSG_CHECKING(ABIFLAGS)
AC_MSG_RESULT($ABIFLAGS)
AC_MSG_CHECKING(SOABI) AC_MSG_CHECKING(SOABI)
SOABI='cpython-'`echo $VERSION | tr -d .`${SOABI_QUALIFIERS} SOABI='cpython-'`echo $VERSION | tr -d .`${ABIFLAGS}
AC_MSG_RESULT($SOABI) AC_MSG_RESULT($SOABI)
AC_MSG_CHECKING(LDVERSION)
LDVERSION='$(VERSION)$(ABIFLAGS)'
AC_MSG_RESULT($LDVERSION)
# SO is the extension of shared libraries `(including the dot!) # SO is the extension of shared libraries `(including the dot!)
# -- usually .so, .sl on HP-UX, .dll on Cygwin # -- usually .so, .sl on HP-UX, .dll on Cygwin
AC_MSG_CHECKING(SO) AC_MSG_CHECKING(SO)