Skip to content

Commit 39afa2d

Browse files
aixtoolsncoghlan
authored andcommitted
bpo-38021: Modify AIX platform_tag so it covers PEP 425 needs (GH-17303)
Provides a richer platform tag for AIX that we expect to be sufficient for PEP 425 binary distribution identification. Any backports to earlier Python versions will be handled via setuptools. Patch by Michael Felt.
1 parent 94d2c8d commit 39afa2d

File tree

8 files changed

+155
-5
lines changed

8 files changed

+155
-5
lines changed

Doc/distutils/apiref.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,24 @@ other utility module.
11421142

11431143
* ``macosx-10.6-intel``
11441144

1145+
For AIX, Python 3.9 and later return a string starting with "aix", followed
1146+
by additional fields (separated by ``'-'``) that represent the combined
1147+
values of AIX Version, Release and Technology Level (first field), Build Date
1148+
(second field), and bit-size (third field). Python 3.8 and earlier returned
1149+
only a single additional field with the AIX Version and Release.
1150+
1151+
Examples of returned values on AIX:
1152+
1153+
* ``aix-5307-0747-32`` # 32-bit build on AIX ``oslevel -s``: 5300-07-00-0000
1154+
1155+
* ``aix-7105-1731-64`` # 64-bit build on AIX ``oslevel -s``: 7100-05-01-1731
1156+
1157+
* ``aix-7.2`` # Legacy form reported in Python 3.8 and earlier
1158+
1159+
.. versionchanged:: 3.9
1160+
The AIX platform string format now also includes the technology level,
1161+
build date, and ABI bit-size.
1162+
11451163

11461164
.. function:: convert_path(pathname)
11471165

Lib/_aix_support.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"""Shared AIX support functions."""
2+
3+
import sys
4+
from sysconfig import get_config_var
5+
6+
# subprocess is not necessarily available early in the build process
7+
# if not available, the config_vars are also definitely not available
8+
# supply substitutes to bootstrap the build
9+
try:
10+
import subprocess
11+
_have_subprocess = True
12+
_tmp_bd = get_config_var("AIX_BUILDDATE")
13+
_bgt = get_config_var("BUILD_GNU_TYPE")
14+
except ImportError: # pragma: no cover
15+
_have_subprocess = False
16+
_tmp_bd = None
17+
_bgt = "powerpc-ibm-aix6.1.7.0"
18+
19+
# if get_config_var("AIX_BUILDDATE") was unknown, provide a substitute,
20+
# impossible builddate to specify 'unknown'
21+
_MISSING_BD = 9898
22+
try:
23+
_bd = int(_tmp_bd)
24+
except TypeError:
25+
_bd = _MISSING_BD
26+
27+
# Infer the ABI bitwidth from maxsize (assuming 64 bit as the default)
28+
_sz = 32 if sys.maxsize == (2**31-1) else 64
29+
30+
31+
def _aix_tag(vrtl, bd):
32+
# type: (List[int], int) -> str
33+
# vrtl[version, release, technology_level]
34+
return "aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(vrtl[0], vrtl[1], vrtl[2], bd, _sz)
35+
36+
37+
# extract version, release and technology level from a VRMF string
38+
def _aix_vrtl(vrmf):
39+
# type: (str) -> List[int]
40+
v, r, tl = vrmf.split(".")[:3]
41+
return [int(v[-1]), int(r), int(tl)]
42+
43+
44+
def _aix_bosmp64():
45+
# type: () -> Tuple[str, int]
46+
"""
47+
Return a Tuple[str, int] e.g., ['7.1.4.34', 1806]
48+
The fileset bos.mp64 is the AIX kernel. It's VRMF and builddate
49+
reflect the current ABI levels of the runtime environment.
50+
"""
51+
if _have_subprocess:
52+
# We expect all AIX systems to have lslpp installed in this location
53+
out = subprocess.check_output(["/usr/bin/lslpp", "-Lqc", "bos.mp64"])
54+
out = out.decode("utf-8").strip().split(":") # type: ignore
55+
# Use str() and int() to help mypy see types
56+
return str(out[2]), int(out[-1])
57+
else:
58+
from os import uname
59+
60+
osname, host, release, version, machine = uname()
61+
return "{}.{}.0.0".format(version, release), _MISSING_BD
62+
63+
64+
def aix_platform():
65+
# type: () -> str
66+
"""
67+
AIX filesets are identified by four decimal values: V.R.M.F.
68+
V (version) and R (release) can be retreived using ``uname``
69+
Since 2007, starting with AIX 5.3 TL7, the M value has been
70+
included with the fileset bos.mp64 and represents the Technology
71+
Level (TL) of AIX. The F (Fix) value also increases, but is not
72+
relevant for comparing releases and binary compatibility.
73+
For binary compatibility the so-called builddate is needed.
74+
Again, the builddate of an AIX release is associated with bos.mp64.
75+
AIX ABI compatibility is described as guaranteed at: https://www.ibm.com/\
76+
support/knowledgecenter/en/ssw_aix_72/install/binary_compatability.html
77+
78+
For pep425 purposes the AIX platform tag becomes:
79+
"aix-{:1x}{:1d}{:02d}-{:04d}-{}".format(v, r, tl, builddate, bitsize)
80+
e.g., "aix-6107-1415-32" for AIX 6.1 TL7 bd 1415, 32-bit
81+
and, "aix-6107-1415-64" for AIX 6.1 TL7 bd 1415, 64-bit
82+
"""
83+
vrmf, bd = _aix_bosmp64()
84+
return _aix_tag(_aix_vrtl(vrmf), bd)
85+
86+
87+
# extract vrtl from the BUILD_GNU_TYPE as an int
88+
def _aix_bgt():
89+
# type: () -> List[int]
90+
assert _bgt
91+
return _aix_vrtl(vrmf=_bgt)
92+
93+
94+
def aix_buildtag():
95+
# type: () -> str
96+
"""
97+
Return the platform_tag of the system Python was built on.
98+
"""
99+
return _aix_tag(_aix_bgt(), _bd)

Lib/distutils/util.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ def get_host_platform():
7979
machine += ".%s" % bitness[sys.maxsize]
8080
# fall through to standard osname-release-machine representation
8181
elif osname[:3] == "aix":
82-
return "%s-%s.%s" % (osname, version, release)
82+
from _aix_support import aix_platform
83+
return aix_platform()
8384
elif osname[:6] == "cygwin":
8485
osname = "cygwin"
8586
rel_re = re.compile (r'[\d.]+', re.ASCII)

Lib/sysconfig.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,8 @@ def get_platform():
665665
machine += ".%s" % bitness[sys.maxsize]
666666
# fall through to standard osname-release-machine representation
667667
elif osname[:3] == "aix":
668-
return "%s-%s.%s" % (osname, version, release)
668+
from _aix_support import aix_platform
669+
return aix_platform()
669670
elif osname[:6] == "cygwin":
670671
osname = "cygwin"
671672
import re
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Provide a platform tag for AIX that is sufficient for PEP425 binary
2+
distribution identification.
3+
4+
Patch by Michael Felt

configure

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10028,7 +10028,21 @@ $as_echo "no" >&6; }
1002810028

1002910029
fi
1003010030
rm -f core conftest.err conftest.$ac_objext \
10031-
conftest$ac_exeext conftest.$ac_ext;;
10031+
conftest$ac_exeext conftest.$ac_ext
10032+
# BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag
10033+
# of the AIX system used to build/package Python executable. This tag serves
10034+
# as a baseline for bdist module packages
10035+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the system builddate" >&5
10036+
$as_echo_n "checking for the system builddate... " >&6; }
10037+
AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }')
10038+
10039+
cat >>confdefs.h <<_ACEOF
10040+
#define AIX_BUILDDATE $AIX_BUILDDATE
10041+
_ACEOF
10042+
10043+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $AIX_BUILDDATE" >&5
10044+
$as_echo "$AIX_BUILDDATE" >&6; }
10045+
;;
1003210046
*) ;;
1003310047
esac
1003410048

@@ -10267,7 +10281,6 @@ fi
1026710281

1026810282

1026910283

10270-
1027110284
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
1027210285
if test -n "$ac_tool_prefix"; then
1027310286
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.

configure.ac

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2858,7 +2858,17 @@ case "$ac_sys_system" in
28582858
AC_MSG_RESULT(yes)
28592859
],[
28602860
AC_MSG_RESULT(no)
2861-
]);;
2861+
])
2862+
dnl The AIX_BUILDDATE is obtained from the kernel fileset - bos.mp64
2863+
# BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the platform_tag
2864+
# of the AIX system used to build/package Python executable. This tag serves
2865+
# as a baseline for bdist module packages
2866+
AC_MSG_CHECKING(for the system builddate)
2867+
AIX_BUILDDATE=$(lslpp -Lcq bos.mp64 | awk -F: '{ print $NF }')
2868+
AC_DEFINE_UNQUOTED([AIX_BUILDDATE], [$AIX_BUILDDATE],
2869+
[BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the build system.])
2870+
AC_MSG_RESULT($AIX_BUILDDATE)
2871+
;;
28622872
*) ;;
28632873
esac
28642874

pyconfig.h.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
/* Define if building universal (internal helper macro) */
99
#undef AC_APPLE_UNIVERSAL_BUILD
1010

11+
/* BUILD_GNU_TYPE + AIX_BUILDDATE are used to construct the PEP425 tag of the
12+
build system. */
13+
#undef AIX_BUILDDATE
14+
1115
/* Define for AIX if your compiler is a genuine IBM xlC/xlC_r and you want
1216
support for AIX C++ shared extension modules. */
1317
#undef AIX_GENUINE_CPLUSPLUS

0 commit comments

Comments
 (0)