Проблемы компиляции Python 3.2 и 2.7 с использованием pythonbrew - PullRequest
3 голосов
/ 17 июня 2011

Я пытаюсь собрать несколько версий Python, используя Pythonbrew , но у меня возникают некоторые неудачные тесты.Это на работающей виртуальной машине: Ubuntu 8.04 32bit

Это происходит при использовании опции --enable-shared

Ошибки файла build.logпоказаны ниже:

Python 3.2

Вот неудачные тесты для Python 3.2:

LD_LIBRARY_PATH=/opt/standingcloud/stack/pythonbrew/build/Python-3.2: ./python -E -c 'import sys ; from sysconfig import get_platform ; print(get_platform()+"-"+sys.version[0:3])' >platform
find ./Lib -name '*.py[co]' -print | xargs rm -f
LD_LIBRARY_PATH=/opt/standingcloud/stack/pythonbrew/build/Python-3.2: ./python -Wd -E -bb  ./Lib/test/regrtest.py -l 
== CPython 3.2 (r32:88445, Jun 16 2011, 15:07:10) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)]
==   Linux-2.6.18.8-linode22-i686-with-debian-lenny-sid little-endian
==   /opt/standingcloud/stack/pythonbrew/build/Python-3.2/build/test_python_18839
Testing with flags: sys.flags(debug=0, division_warning=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=1, verbose=0, bytes_warning=2, quiet=0)

....SNIP....

[197/349] test_os
test test_os failed -- Traceback (most recent call last):
  File "/opt/standingcloud/stack/pythonbrew/build/Python-3.2/Lib/test/test_os.py", line 646, in test_exist_ok_existing_directory
    os.makedirs(path, mode=mode, exist_ok=True)
  File "/opt/standingcloud/stack/pythonbrew/build/Python-3.2/Lib/os.py", line 152, in makedirs
    mkdir(name, mode)
OSError: [Errno 17] File exists: '@test_18839_tmp/dir1'

....SNIP....

321 tests OK.
1 test failed:
    test_os
27 tests skipped:
    test_codecmaps_cn test_codecmaps_hk test_codecmaps_jp
    test_codecmaps_kr test_codecmaps_tw test_curses test_dbm_gnu
    test_dbm_ndbm test_gdb test_ioctl test_kqueue test_ossaudiodev
    test_pep277 test_smtpnet test_socketserver test_sqlite
    test_startfile test_timeout test_tk test_ttk_guionly
    test_unicode_file test_urllib2net test_urllibnet test_winreg
    test_winsound test_xmlrpc_net test_zipfile64
5 skips unexpected on linux2:
    test_dbm_gnu test_dbm_ndbm test_ioctl test_tk test_ttk_guionly
sys:1: ResourceWarning: unclosed file <_io.TextIOWrapper name='/dev/null' mode='a' encoding='ANSI_X3.4-1968'>
make: *** [test] Error 1

Python 2.7.1

Вот неудачныетесты для Python 2.7.1:

./python -Wd -3 -E -tt  ./Lib/test/regrtest.py -l 
== CPython 2.7.1 (r271:86832, Jun 16 2011, 17:59:28) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)]
==   Linux-2.6.18.8-linode22-i686-with-debian-lenny-sid little-endian
==   /opt/standingcloud/stack/pythonbrew/build/Python-2.7.1/build/test_python_19286

....SNIP....

test test_file2k failed -- Traceback (most recent call last):
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7.1/Lib/test/test_file2k.py", line 219, in testStdin
    self.assertRaises(IOError, sys.stdin.seek, -1)
AssertionError: IOError not raised

....SNIP....

343 tests OK.
2 tests failed:
    test_file test_file2k
41 tests skipped:
    test_aepack test_al test_applesingle test_bsddb test_bsddb185
    test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_hk
    test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses
    test_dbm test_gdb test_gdbm test_gl test_imgfile test_ioctl
    test_kqueue test_linuxaudiodev test_macos test_macostools
    test_ossaudiodev test_pep277 test_scriptpackages test_smtpnet
    test_socketserver test_sqlite test_startfile test_sunaudiodev
    test_timeout test_tk test_ttk_guionly test_unicode_file
    test_urllib2net test_urllibnet test_winreg test_winsound
    test_zipfile64
8 skips unexpected on linux2:
    test_bsddb test_bsddb3 test_dbm test_gdb test_gdbm test_ioctl
    test_tk test_ttk_guionly
make: *** [test] Error 1

Python 2.7

Вот неудачные тесты для Python 2.7:

LD_LIBRARY_PATH=/opt/standingcloud/stack/pythonbrew/build/Python-2.7: ./python -E -c 'import sys ; from sysconfig import get_platform ; print get_platform()+"-"+sys.version[0:3]' >platform
find ./Lib -name '*.py[co]' -print | xargs rm -f
LD_LIBRARY_PATH=/opt/standingcloud/stack/pythonbrew/build/Python-2.7: ./python -Wd -3 -E -tt ./Lib/test/regrtest.py -l 
== CPython 2.7 (r27:82500, Jun 16 2011, 15:25:09) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu4)]
==   Linux-2.6.18.8-linode22-i686-with-debian-lenny-sid little-endian
==   /opt/standingcloud/stack/pythonbrew/build/Python-2.7/build/test_python_13541

....SNIP....

test_distutils
/usr/bin/ld: cannot find -lpython2.7
collect2: ld returned 1 exit status
test test_distutils failed -- Traceback (most recent call last):
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/distutils/tests/test_build_ext.py", line 269, in test_get_outputs
    cmd.run()
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/distutils/command/build_ext.py", line 340, in run
    self.build_extensions()
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/distutils/command/build_ext.py", line 449, in build_extensions
    self.build_extension(ext)
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/distutils/command/build_ext.py", line 531, in build_extension
    target_lang=language)
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/distutils/ccompiler.py", line 741, in link_shared_object
    extra_preargs, extra_postargs, build_temp, target_lang)
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/distutils/unixccompiler.py", line 258, in link
    raise LinkError, msg
LinkError: command 'gcc' failed with exit status 1

....SNIP....

test test_file failed -- multiple errors occurred; run in verbose mode for details
test_file2k
test test_file2k failed -- Traceback (most recent call last):
  File "/opt/standingcloud/stack/pythonbrew/build/Python-2.7/Lib/test/test_file2k.py", line 211, in testStdin
    self.assertRaises(IOError, sys.stdin.seek, -1)
AssertionError: IOError not raised

....SNIP....

339 tests OK.
3 tests failed:
    test_distutils test_file test_file2k
1 test altered the execution environment:
    test_site
41 tests skipped:
    test_aepack test_al test_applesingle test_bsddb test_bsddb185
    test_bsddb3 test_cd test_cl test_codecmaps_cn test_codecmaps_hk
    test_codecmaps_jp test_codecmaps_kr test_codecmaps_tw test_curses
    test_dbm test_gdb test_gdbm test_gl test_imgfile test_ioctl
    test_kqueue test_linuxaudiodev test_macos test_macostools
    test_ossaudiodev test_pep277 test_scriptpackages test_smtpnet
    test_socketserver test_sqlite test_startfile test_sunaudiodev
    test_timeout test_tk test_ttk_guionly test_unicode_file
    test_urllib2net test_urllibnet test_winreg test_winsound
    test_zipfile64
8 skips unexpected on linux2:
    test_bsddb test_bsddb3 test_dbm test_gdb test_gdbm test_ioctl
    test_tk test_ttk_guionly
make: [test] Error 1 (ignored)

Ответы [ 3 ]

4 голосов
/ 05 мая 2012

Я думаю, что нашел способ сделать эту работу без установки LD_LIBRARY_PATH.

Я обнаружил, что есть переменная окружения под названием LD_RUN_PATH, которая похожа на LD_LIBRARY_PATH, за исключением того, что вы устанавливаете ее при компиляции программы, и она запоминает этот путь всякий раз, когда она выполняется ( поэтому вам не нужно устанавливать LD_LIBRARY_PATH во время выполнения).

Так что, если вы правильно установили LD_RUN_PATH при запуске pythonbrew для установки Python, он должен находить свою собственную разделяемую библиотеку всякий раз, когда вы ее запускаете. Например, следующая команда оказалась для меня успешной, включая установку distutils и pip, так что установка модуля готова к выполнению без дальнейшей настройки.

LD_RUN_PATH=$HOME/.pythonbrew/pythons/Python-2.7.3/lib pythonbrew install -j2 -C '--enable-shared' --force -v 2.7.3

Тогда я могу сделать pythonbrew use 2.7.3, чтобы активировать его, и он просто работает, без установки каких-либо переменных окружения в вашей оболочке init или чего-либо еще.

Конечно, вам нужно заранее знать, где pythonbrew установит ваш Python, чтобы вы могли правильно установить LD_RUN_PATH. Как правило, это будет $HOME/.pythonbrew/pythons/Python-$VERSION/lib, но если это не сработает, вы всегда можете узнать об этом, установив его один раз (без --enable-shared), а затем найдя каталог lib.

Я полагаю, что ошибки происходят, потому что после установки с --enable-shared ваш установленный Python находит общую библиотеку Python системы и использует ее, что вызывает проблемы, если есть какое-либо несоответствие в том, как были построены два Питона. Использование решения LD_LIBRARY_PATH или LD_RUN_PATH заставляет ваш Python использовать собственную разделяемую библиотеку.

4 голосов
/ 30 ноября 2011

В настоящее время мне удается заставить pythonbrew работать с 2.7.2, выполняя следующие действия:

a) Сначала установите все зависимости, необходимые для компиляции python.

'curl' # not for build, but for steps after
'build-essential',
'libbz2-dev',
'libsqlite3-dev',
'zlib1g-dev',
'libxml2-dev',
'libxslt1-dev',
'libreadline5', # lenny
'libreadline5-dev', # lenny
'libgdbm-dev',
'libgdb-dev',
'libxml2',
'libssl-dev',
'tk-dev',
'libgdbm-dev',
'libexpat1-dev',
'libncursesw5-dev'

b) Теперь установите 2.7.2:

pythonbrew install --configure="--with-threads --enable-shared" -j2 -v 2.7.2

Устанавливается, но обнаружена следующая ошибка :

/ home / python-deploy / .pythonbrew / pythons / Python-2.7.2 / bin / python: ошибка при загрузке общих библиотек: libpython2.7.so.1.0: невозможно открыть файл общего объекта: такого файла или каталога нет

* Чтобы избежать ошибки после сборки при попытке установить setuptools, используйте параметр --no-setuptools, и вам может потребоваться использовать --force на некоторых платформах, как тест gdbне удается из-за ошибки в самом тесте.

pythonbrew install --configure="--with-threads--enable-shared" \
                   --force \
                   --no-setuptools \
                   --jobs=2 \
                   --verbose 2.7.2 

c) Самый простой обходной путь - это сделать (с правильным путем к вашей установке pythonbrew):

pythonbrew use 2.7.2
export LD_LIBRARY_PATH=$HOME/.pythonbrew/pythons/Python-2.7.2/lib

или добавитьнавсегда, поместите путь lib для pythonbrew в файл, расположенный в /etc/ld.so.conf.d, и этот путь будет добавлен при запуске или сразу после запуска ldconfig:

sudo echo /home/user/.pythonbrew/pythons/Python-2.7.2/lib >> /etc/ld.so.conf.d/pythonbrew.conf
sudo ldconfig

d) Установитьsetuptools или распространяйте вручную, т.е.

curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py && easy_install pip

И вы должны быть готовы к работе.Протестировано только с 2.7.2 на бродячем Debian Lenny VM.

3 голосов
/ 13 сентября 2012

Ответ Райана Томпсона хорош ... LD_RUN_PATH - правильное лекарство.

Однако вместо жесткого кодирования абсолютного пути можно использовать:

LD_RUN_PATH='$ORIGIN/../lib'

... где $ORIGIN - это PWD работающего двоичного файла (например, python).

# objdump -x /home/arisinger/.pythonbrew/pythons/Python-2.7.3/bin/python|grep RPATH
  RPATH                $ORIGIN/../lib
# ldd .pythonbrew/pythons/Python-2.7.3/bin/python
    [...]
    libpython2.7.so.1.0 => /home/arisinger/.pythonbrew/pythons/Python-2.7.3/bin/../lib/libpython2.7.so.1.0 (0x00007f43994f6000)
    [...]

... выше также правильно установит pip и т. Д. Наконец, с man ld.so:

$ORIGIN and rpath
    ld.so  understands the string $ORIGIN (or equivalently ${ORIGIN}) in an
    rpath specification (DT_RPATH or DT_RUNPATH) to mean the directory con‐
    taining  the  application  executable.  Thus, an application located in
    somedir/app could be compiled with gcc  -Wl,-rpath,'$ORIGIN/../lib'  so
    that  it  finds  an  associated shared library in somedir/lib no matter
    where somedir is located in the directory hierarchy.  This  facilitates
    the  creation  of  "turn-key"  applications  that  do  not  need  to be
    installed into special directories, but can instead  be  unpacked  into
    any directory and still find their own shared libraries.

РЕДАКТИРОВАТЬ: печально venvs ломается, потому что virtualenv копирует двоичный файл python (изменяя $ORIGIN), но не копирует (или символическую ссылку) библиотеку, поэтому C / builtin динамические модули в venv заканчивают тем, что связывались с системным питоном ... плохо :-( ...

... IMO, это ошибка, которую нужно исправить (в virtualenv?), Но простой обходной путь - вручную скопировать / символическую ссылку libpythonX.Y.so* в lib / dir venv ... или сделать что-то немного противное выглядит как (примечание XYZ):

LD_RUN_PATH='$ORIGIN/../lib:$ORIGIN/../../../../pythons/Python-X.Y.Z/lib'

... выбирайте все, что менее неприятно для вас; оба проверены на работу.

...