Compiling python in linux

2. Using Python on Unix platformsВ¶

2.1. Getting and installing the latest version of PythonВ¶

2.1.1. On LinuxВ¶

Python comes preinstalled on most Linux distributions, and is available as a package on all others. However there are certain features you might want to use that are not available on your distro’s package. You can easily compile the latest version of Python from source.

In the event that Python doesn’t come preinstalled and isn’t in the repositories as well, you can easily make packages for your own distro. Have a look at the following links:

for Debian users

for OpenSuse users

for Fedora users

for Slackware users

2.1.2. On FreeBSD and OpenBSDВ¶

FreeBSD users, to add the package use:

OpenBSD users, to add the package use:

For example i386 users get the 2.5.1 version of Python using:

2.1.3. On OpenSolarisВ¶

You can get Python from OpenCSW. Various versions of Python are available and can be installed with e.g. pkgutil -i python27 .

2.2. Building PythonВ¶

If you want to compile CPython yourself, first thing you should do is get the source. You can download either the latest release’s source or just grab a fresh clone. (If you want to contribute patches, you will need a clone.)

The build process consists of the usual commands:

Configuration options and caveats for specific Unix platforms are extensively documented in the README.rst file in the root of the Python source tree.

make install can overwrite or masquerade the python3 binary. make altinstall is therefore recommended instead of make install since it only installs exec_prefix /bin/python version .

These are subject to difference depending on local installation conventions; prefix ( $ ) and exec_prefix ( $ ) are installation-dependent and should be interpreted as for GNU software; they may be the same.

For example, on most Linux systems, the default for both is /usr .

Recommended location of the interpreter.

prefix /lib/python version , exec_prefix /lib/python version

Recommended locations of the directories containing the standard modules.

prefix /include/python version , exec_prefix /include/python version

Recommended locations of the directories containing the include files needed for developing Python extensions and embedding the interpreter.

2.4. MiscellaneousВ¶

To easily use Python scripts on Unix, you need to make them executable, e.g. with

and put an appropriate Shebang line at the top of the script. A good choice is usually

which searches for the Python interpreter in the whole PATH . However, some Unices may not have the env command, so you may need to hardcode /usr/bin/python3 as the interpreter path.

To use shell commands in your Python scripts, look at the subprocess module.

2.5. Custom OpenSSLВ¶

To use your vendor’s OpenSSL configuration and system trust store, locate the directory with openssl.cnf file or symlink in /etc . On most distribution the file is either in /etc/ssl or /etc/pki/tls . The directory should also contain a cert.pem file and/or a certs directory.

Download, build, and install OpenSSL. Make sure you use install_sw and not install . The install_sw target does not override openssl.cnf .

Build Python with custom OpenSSL (see the configure –with-openssl and –with-openssl-rpath options)

Patch releases of OpenSSL have a backwards compatible ABI. You don’t need to recompile Python to update OpenSSL. It’s sufficient to replace the custom OpenSSL installation with a newer version.

Источник

Как скомпилировать Python

Я хочу рассказать об удивительном событии, о котором я узнал пару месяцев назад. Оказывается, одна популярная python-утилита уже более года распространяется в виде бинарных файлов, которые компилируются прямо из python. И речь не про банальную упаковку каким-нибудь PyInstaller-ом, а про честную Ahead-of-time компиляцию целого python-пакета. Если вы удивлены так же как и я, добро пожаловать под кат.

Читайте также:  Как отключить проверку защитника windows

Объясню, почему я считаю это событие по-настоящему удивительным. Существует два вида компиляции: Ahead-of-time (AOT), когда весь код компилируется до запуска программы и Just in time compiler (JIT), когда непосредственно компиляция программы под требуемую архитектуру процессора осуществляется во время ее выполнения. Во втором случае первоначальный запуск программы осуществляется виртуальной машиной или интерпретатором.

Если сгруппировать популярные языки программирования по типу компиляции, то получим следующий список:

Ahead-of-time compiler: C, C++, Rust, Kotlin, Nim, D, Go, Dart;

Just in time compiler: Lua, С#, Groovy, Dart.

В python из коробки нет JIT компилятора, но отдельные библиотеки, предоставляющие такую возможность, существуют давно

Смотря на эту таблицу, можно заметить определенную закономерность: статически типизированные языки находятся в обеих строках. Некоторые даже могут распространяться с двумя версиями компиляторов: Kotlin может исполняться как с JIT JavaVM, так и с AOT Kotlin/Native. То же самое можно сказать про Dart (версии 2). A вот динамически типизированные языки компилируются только JIT-ом, что впрочем вполне логично.

При запуске виртуальная машина сначала накапливает информацию о типах переменных, затем после накопления статистики, запускается компиляция наиболее нагруженных частей программы. Виртуальная машина отслеживает типы аргументов и переключает выполнение программы между уже скомпилированными и не скомпилированными участками кода в зависимости от текущих значений переменных.

При использовании JIT компиляции типы не очень то и нужны, ведь информация о типах собирается во время работы программы. Поэтому все популярные динамически типизированные языки программирования распространяются именно с JIT компилятором. Но как быть с AOT компиляцией кода, в котором нет типов? Меня очень заинтересовал этот вопрос, и я полез разбираться.

Итак, вернемся к утилите, о которой говорилось в начале статьи. Речь про mypy — наиболее популярный синтаксический анализатор python-кода.

С апреля 2019 года эта утилита распространяется в скомпилированном виде, о чем рассказывается в блоге проекта. А для компиляции используется еще одна утилита от тех же авторов — mypyc. Погуглив немного, я нашел достаточно большую статью “Путь к проверке типов 4 миллионов строк Python-кода” про становление и развитие mypy (на Хабре доступен перевод: часть 1, часть 2, часть 3). Там немного рассказывается о целях создания mypyc: столкнувшись с недостаточной производительностью mypy при разборе крупных python-проектов в Dropbox, разработчики добавили кеширование результатов проверки кода, а затем возможность запуска утилиты как сервиса. Но исчерпав очевидные возможности оптимизации, столкнулись с выбором: переписать все на go или на cython. В результате проект пошел по третьему пути — написание своего AOT python-компилятора.

Дело в том, что для правильной работы mypy и так необходимо построить то же синтаксическое дерево, что и интерпретатору во время исполнения кода. То есть mypy уже “понимает” python, но использует эту информацию только для статистического анализа, а вот mypyc может преобразовывать эту информацию в полноценный бинарный код.

Думаю тут многие решили, что разобрались в вопросе того, как скомпилировать динамически типизированный python-код. Python c версии 3.4 поддерживает аннотацию типов, а mypy как раз и используется для проверки корректности аннотаций. Получается, python как бы уже и не динамически типизированный язык, что позволяет применить AOT компиляцию. Но загвоздка в том, что mypyc может компилировать и неаннотированный код!

Функция bubble_sort

Для примера рассмотрим функцию сортировки “пузырьком”. Файл lib.py:

У типов нет аннотаций, но это не мешает mypyc ее скомпилировать. Чтобы запустить компиляцию, нужно установить mypyc. Он не распространяется отдельным пакетом, но если у вас установлен mypy, то и mypyc уже присутствует в системе! Запускаем mypyc, следующей командой:

После запуска в проекте будут созданы следующие директории:

.mypy_cache — mypy кэш, mypyc неявно запускает mypy для разбора программы и получения AST;

build — артефакты сборки;

lib.cpython-38-x86_64-linux-gnu.so — собственно сборка под целевую платформу. Данный файл представляет из себя готовый CPython Extension.

CPython Extension — встроенный в CPython механизм взаимодействия с кодом, написанным на С/C++. По сути это динамическая библиотека, которую CPython умеет загружать при импорте нашего модуля lib. Через данный механизм осуществляется взаимодействие с модулями, написанными на python.

Компиляция состоит из двух фаз:

Читайте также:  Флешка для установки mac os mojave

Компиляция python кода в код С;

Компиляция С в бинарный .so файл, для этого mypyc сам запускает gcc (gcc и python-dev также должен быть установлены).

Файл lib.cpython-38-x86_64-linux-gnu.so имеет преимущество перед lib.py при импорте на соответствующей платформе, и исполняться теперь будет именно он.

Ну и давайте сравним производительность модуля до и после компиляции. Для этого создадим файл main.py с кодом запуска сортировки:

Получим примерно следующие результаты:

Ожидаемо скомпилированный код оказался быстрее (

в 2 раза), что неплохо, так как для такого результата нам потребовалось запустить лишь одну команду. Хотя от скомпилированного кода привычно ожидаешь большего.

Чтобы ответить на вопрос “как компилируется динамически типизированный код”, придется заглянуть в представление этой функции на С. Но разобрать ее будет достаточно сложно, поэтому давайте попробуем разобраться с примером попроще.

Функция sum(a, b)

Скомпилируем функцию суммы от двух переменных:

Перед запуском компиляции я ожидал увидеть примерно следующий код на С:

Однако результат оказался cущественно иным (код немного упрощен):

Рассмотрим, что тут происходит. Во-первых, так как мы не знаем типы входных переменных, функция в качестве аргументов принимает указатели на объекты класса PyObject, по сути это внутренние CPython структуры. Далее компилятор должен сложить эти объекты, но как, если настоящие типы аргументов неизвестны во время компиляции: это могут быть целые числа, числа с плавающей точкой, списки и вообще не факт, что аргументы можно складывать, тогда нужно вернуть ошибку. И что же делает в этом случае mypyc?

Как оказалось, все очень просто: он просит CPython самостоятельно сложить эти аргументы. Функция PyNumber_Add — это внутренняя функция СPython, которая доступна из расширения, ведь СPython отлично умеет складывать свои объекты.

Взаимодействие CPython c Extension можно изобразить следующим диалогом:

— А посчитай-ка мне функцию sum для A, B;

— Хорошо, но скажи сначала, сколько будет A + B;

— Хорошо, тогда держи ответ — С.

Вот такой нехитрый прием используется при компиляции динамического кода: компилируем все, что можем, а все остальное отдаем интерпретатору.

Конечно, данный пример выглядит гротескно, но даже несмотря на такую неэффективность, mypyc позволяет добиться существенного прироста производительности, как в примере с сортировкой.

Функция sum(a: int, b: int)

Итак, у нас получилось скомпилировать python, и мы разобрались с тем, как это работает, а также увидели определенную неэффективность полученного результата. Теперь попробуем разобраться в том, как можно это улучшить. Очевидно, что основная проблема заключается во множественном взаимодействии CPython — Extension. Но как это побороть?

Для повышения эффективности, нужно, чтобы расширение, получив управление, могло как можно дольше оставлять его у себя без обращения к CPython. Если бы у mypyc была информация о типах переменных, то он бы мог самостоятельно произвести сложение без возврата управления. Но вывести типы самостоятельно mypyc не может, он даже не контролирует код, из которого осуществляется вызов функции sum. Соответственно, ему нужно помочь, проставив аннотации вручную. Давайте посмотрим, как поменяется результирующая С-функция, если добавить аннотацию типов:

Скомпилированный результат на C (немного очищенный):

Главное, что можно заметить: функция существенно поменялась, а значит, компилятор реагирует на появление аннотации. Давайте разбираться, что изменилось.

Теперь CPyDef_sum получает на вход не указатели на PyObject, а структуры CPyTagged. Это все еще не int, но уже и не часть CPython, а часть библиотек mypyc, которую он добавляет в скомпилированный код расширения. Для ее инициализации в рантайме сначала проверяется тип, так что теперь функция sum работает только с int и обойти аннотацию не получится.

Далее происходит вызов CPyTaggetAdd вместо PyNumber_Add. Это уже внутренняя функция mypyc. Если заглянуть в код CPyTaggetAdd, то можно понять, что там происходит проверка диапазонов значений a и b, и если они укладываются в int, то происходит простое суммирование, а также проверка на переполнение:

Таким образом, наш диалог CPython — Extension превращается из абсурдного в нормальный:

— А посчитай-ка мне функцию sum для A, B;

— Хорошо, тогда держи ответ С.

Функция bubble_sort(data: List[int])

Настало время вернуться к функции сортировки, чтобы провести замеры скорости. Изменим начальную функцию, добавив аннотацию для data:

Скомпилируем результат и замерим время сортировки:

Источник

getKT

All Linux distributions come with latest stable python release. Yet, if you want to try out new python for its elegant new features. You can compile and install it side by existing python.

Читайте также:  Не видит сеть windows 10 pro

Steps to Install Python from source

  • Clone Python repository
  • Compile Python
  • Install Python (altinstall)
  • Git (version control system )
  • build-essentials

It is recommended not to replace python that comes with OS. You may mess up with internals since many OS internals (commands) rely on default python instead install side by existing python using “make altinstall”

Clone Python Repository

You can choose to download python source at “Python Source Release” or you can proceed with git with luxury to switch between any version you want.

switch to cloned directory using “cd cpython”

Checkout to required python release

You can list all python releases (tags) using command “git tag

Following command will help to list last 20 release in descending order

For the sake of this article I’m switching to release v3.8.0 using “git checkout” command

You can verify your current branch(version) switched to by using command “git branch

Install build-essentials

Before proceeding further, consider updating package information and upgrading system

Above commands may take a while. Wait for them to complete to proceed further.

Install tools required to build and install python

Compile and Install Python

Compile Python

Compile Python using following commands

To install python with shared libraries run ” ./configure –enable-shared “.

./configure script takes another optional command line options–prefix. It can be used to set where final built files will be placed(installed).
Example: ./configure –prefix=/opt/python3.8

If –prefix option is used with ./configure script. It is not necessary to use “make altinstall” instead you can run “make install

  • ./configure script checks all dependencies and prepares for build. If it is complaining about anything, make sure it is fixed before proceeding further(compilation).
  • make tool will build files
  • make install will install (or) it will put files into the destination specified by –prefix option of ./configure

After command make you may see optional modules which are not built with following message

If you think, you need any of the modules mentioned above are required. Don’t hesitate to install those dependencies and then repeat “./configure; make” followed by “make install” if everything goes well with make.

Install dependencies(development files) to build python optional modules mentioned in the above output message of make command

Once above development packages are installed. Run “make” to build(compile) python with dependencies installed followed by “make install” .

Use make altinstall if you would like to install python with out replacing default python if –prefix option is not used with ./configure script

If –prefix option is specified to ./configure script, built files will placed in that specified directory else files will be placed inside /usr/local by default. That is, inside “/usr/local/bin”, “usr/local/lib” etc.

You can find python command location using command “which python3.8”. Note: replace python3.8 with the version you have installed

Access Python’s Configuration Options

Once python is compiled and installed. We can access the configuration options that python was compiled with using module called “sysconfig

Following python code will print configuration options that python was compiled with

On the other hand you can also use the command “pyton3.8-config” (python*-config) to get information about python configuration

If you build and install python with ./configure’s –prefix option, all files will be placed in single directory specified with folders inside as follows,

  • bin directory contains all executable files
  • include directory contains all python header files like Python.h that are required for writing c extensions or python wrappers. Usually this directory will be passed with -I flag to gcc when compiling to embedded python
  • lib directory contains all python modules and libraries
  • share directory contains man pages that can be read with man command

Источник

Оцените статью