Как скомпилировать python в linux
Перейти к содержимому

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

  • автор:

Как скомпилировать в единый бинарный файл приложение на Python в Linux?

Нашел только этот вопрос Упаковка Python проекта в единый exe файл он про Windows. В питоне есть такие вещи как типо make или cargo build после которых получаешь независимый от библиотек и прочего бинарный файл?

Отслеживать
задан 30 мар 2020 в 0:03
493 4 4 серебряных знака 17 17 бронзовых знаков

В чистом виде не бывает, всё что есть — костыли, просто запаковывающие интерпретатор и библиотеки в один архив, и это не является компиляцией (в Windows то же самое)

30 мар 2020 в 0:14
Pyinstaller, да вообще-то почти любая инструция от винды также сработает
30 мар 2020 в 0:15

а как же очень известный проект типо youtube-dl у которого в релизах находится бинарный файл без всяких зависимостей? или они тоже костыли городят с закапыванием интерпретатора? github.com/ytdl-org/youtube-dl/releases/latest/download/…

30 мар 2020 в 0:27
А в код посмотреть слабо? github.com/ytdl-org/youtube-dl/blob/master/setup.py
30 мар 2020 в 11:32

@Ivan да, у youtube-dl тоже костыли. Если вы скормите этот бинарный файл в unzip, то он найдёт в этом файле архив и распакует оттуда библиотеки. А вот интерпретртора в этом файле нет — он должен быть установлен в систему заранее. Если же вы скачаете виндовый youtube-dl.exe, то там в комплекте будет ещё интерпретатор Python 3.4.4 (в виде dll-файла перед архивом) и в архиве стандартные библиотеки для него. Это всё тоже не компиляция, просто упаковка в самораспаковывающийся архив.

30 мар 2020 в 12:58

0

Сортировка: Сброс на вариант по умолчанию

Знаете кого-то, кто может ответить? Поделитесь ссылкой на этот вопрос по почте, через Твиттер или Facebook.

  • python
  • linux

Форум русскоязычного сообщества Ubuntu

Страница сгенерирована за 0.037 секунд. Запросов: 25.

  • Сайт
  • Об Ubuntu
  • Скачать Ubuntu
  • Семейство Ubuntu
  • Новости
  • Форум
  • Помощь
  • Правила
  • Документация
  • Пользовательская документация
  • Официальная документация
  • Семейство Ubuntu
  • Материалы для загрузки
  • Совместимость с оборудованием
  • RSS лента
  • Сообщество
  • Наши проекты
  • Местные сообщества
  • Перевод Ubuntu
  • Тестирование
  • RSS лента

© 2012 Ubuntu-ru — Русскоязычное сообщество Ubuntu Linux.
© 2012 Canonical Ltd. Ubuntu и Canonical являются зарегистрированными торговыми знаками Canonical Ltd.

Как запустить скрипт Python в Linux

Одним из самых популярных языков программирования является Python. Его часто используют программисты для написания различных системных скриптов для Linux (арендовать vps сервер python). Например, если в Windows не хватает системных возможностей, то используется программа PoweShell. В Linux на такой случай предусмотрен именно язык Python. Особенность Python в том, что на нем написано огромное количество системных программ, в частности менеджер apt, видеоредактор OpenShot, а также множество скриптов, которые вы можете установить с помощью утилиты. Дальше рассмотрим, как запустить Python скрипт в Linux с помощью терминала различными способами.

Запускаем скрипт Python в Linux

В качестве примера испольуем Python скрипт. Но не будем брать уже существующий, а создаим новым — собственный:

Чтобы запустить скрипт необходимо передать его интерпретатору Python. Для этого просто откройте терминал с помощью сочетания клавиш Ctrl + Alt + T, перейдите в папку со скриптом и выполните:

Если вы хотите, чтобы после выполнения скрипта открылась консоль, в которой можно интерактивно выполнять команды языка Python используйте опцию -i:

Как видим, при запуске apt или openshot не надо писать слово python. Это намного удобнее. Давайте разберемся как это реализовать. Если вы не хотите указывать интерпретатор в командной строке, его надо указать в самом скрипте. Для этого в скрипт добавим строчку:

Сохраните изменения, а затем сделайте файл скрипта исполняемым с помощью такой команды:

$ chmod ugo+x script.py

После этого можно запустить скрипт Python просто обращаясь к его файлу:

Если убрать расширение .py и переместить скрипт в каталог, который находится в переменной PATH, например /usr/bin/, то его можно будет выполнять вот так:

Запуск команды python Linux выполняется довольно просто и для этого даже есть несколько способов. Можете пользоваться любым из них.

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

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

Объясню, почему я считаю это событие по-настоящему удивительным. Существует два вида компиляции: 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:

def bubble_sort(data): n = len(data) for i in range(n - 1): for j in range(n - i - 1): if data[j] > data[j + 1]: buff = data[j] data[j] = data[j + 1] data[j + 1] = buff return data

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

> mypyc lib.py

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

  • .mypy_cache — mypy кэш, mypyc неявно запускает mypy для разбора программы и получения AST;
  • build — артефакты сборки;
  • lib.cpython-38-x86_64-linux-gnu.so — собственно сборка под целевую платформу. Данный файл представляет из себя готовый CPython Extension.

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

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

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

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

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

import lib data = lib.bubble_sort(list(range(5000, 0, -1))) assert data == list(range(1, 5001))

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *