AIX下编译Python

目录

AIX 上安装的 Python 版本为 2.5.2,缺少 Python 2.7 版本添加的诸多新功能,也无法尝试 Python 3.X 版本全新的特性。

cma20n03:/cma/u/nwp/bin $ python -V
Python 2.6.2

好在我们可以手动编译。

编译 Python 2

版本:Python 2.7.12

运行下面的 configure 命令:

./configure --prefix=YOUR_INSTALL_DIR --disable-ipv6 \
  --with-libs=-L/opt/freeware/lib --disable-shared --without-computed-gotos \
  CC=xlc CXX=xlC

进行编译:

make

运行测试:

make test

会发现如下错误:

./python -Wd -3 -E -tt  ./Lib/test/regrtest.py -l
Traceback (most recent call last):
  File "./Lib/test/regrtest.py", line 230, in <module>
    TEMPDIR = os.path.abspath(tempfile.gettempdir())
  File "...省略.../Python-2.7.12/Lib/tempfile.py", line 274, in gettempdir
    tempdir = _get_default_tempdir()
  File "...省略.../Python-2.7.12/Lib/tempfile.py", line 196, in _get_default_tempdir
    fd = _os.open(filename, flags, 0o600)
OverflowError: signed integer is greater than maximum
make: The error code from the last command is 1.

查看源文件后,发现该错误因变量 flags 过大导致。

出错函数中,flags值如下:

flags = _text_openflags

而定义 _text_openflags 的代码在 Lib/tempfile.py 文件的开头:

_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
if hasattr(_os, 'O_NOINHERIT'):
    _text_openflags |= _os.O_NOINHERIT
if hasattr(_os, 'O_NOFOLLOW'):
    _text_openflags |= _os.O_NOFOLLOW
_bin_openflags = _text_openflags
if hasattr(_os, 'O_BINARY'):
    _bin_openflags |= _os.O_BINARY
if hasattr(_os, 'TMP_MAX'):
    TMP_MAX = _os.TMP_MAX
else:
    TMP_MAX = 10000

通过添加 print 语句,分析每个步骤的值,发现在 O_NOFOLLOW 行,_text_openflags 的值突然增大。

检测 O_NOFOLLOW 的值:

>>> import os as _os
>>> _os.O_NOFOLLOW
137438953472

显然不正常,该测试失败的原因就在这里,但未找到 O_NOFOLLOW 值过大的原因。

检查 AIX 中 Python 2.6 版本的情况:

>>> import os
>>> hasattr(os, 'O_NOFOLLOW')
False

可见 AIX 的 os 模块中,不应该含有 O_NOFOLLOW 变量。可以暂时将 tempfile.py 中的 O_NOFOLLOW 行注释掉:

_text_openflags = _os.O_RDWR | _os.O_CREAT | _os.O_EXCL
if hasattr(_os, 'O_NOINHERIT'):
    _text_openflags |= _os.O_NOINHERIT
# added by windroc
#if hasattr(_os, 'O_NOFOLLOW'):
#    _text_openflags |= _os.O_NOFOLLOW
_bin_openflags = _text_openflags
if hasattr(_os, 'O_BINARY'):
    _bin_openflags |= _os.O_BINARY
if hasattr(_os, 'TMP_MAX'):
    TMP_MAX = _os.TMP_MAX
else:
    TMP_MAX = 10000

就可以正常使用该函数。但 make test 依旧无法完成,不过不影响一般使用。后续使用中将继续观察。

最后,使用 make install 安装到指定目录。

编译 Python 3

版本:Python 3.5.2
运行与编译 Python 2 相同的 configure 命令:

./configure --prefix=YOUR_INSTALL_DIR --disable-ipv6 \
  --with-libs=-L/opt/freeware/lib --disable-shared --without-computed-gotos \
  CC=xlc CXX=xlC

编译

make

运行测试

make test

与 Python 2 同样的问题,需要修改 tempfile.py 文件,修改方法见上一节,不再重复。
修改后,依旧无法通过测试,后续将在使用中继续观察。
最后,使用 make install 安装到指定目录。

参考资料

我整理的 AIX 上编译 Python 的 Gist