Debianzing программа Python, чтобы получить .deb

Цель

Чтобы создать устанавливаемый .deb файл (или пакет). Который при нажатии будет устанавливать программное обеспечение на машину с Linux, а значок будет помещен на панель GNOME. Чтобы запустить это приложение оттуда.

На что я ссылался

Я сослался на два руководства по дебианизации.

Руководство 1

Руководство 2

В первом было видео, которое было невозможно понять, отчасти из-за акцента, отчасти потому, что оно безнадежно устарело (залито в 2007 году).

А второй был полностью текстовым. Я дошел до 4-го шага, собирает пакет. Но когда я это сделал, я получил вывод, который не соответствовал тому, что было дано в руководстве.

Что мне нужно

У меня есть простая программа на питоне. Он берет ваш возраст, а затем распечатывает его, если возраст меньше, равен или превышает 18 лет. Для этой программы существует только один файл и никаких других зависимостей. И я хочу встроить это в .deb.

Характеристики

-Питон 2.7

- Линукс Минт

Редактировать

Я следовал точной структуре каталогов, как вы и указали. И заменил все myscript на cowsandbulls. Сборка завершена, и я получил Debian. Когда я установил его, а затем запустил команду cowsandbulls из терминала, я получил следующую ошибку:

Traceback (most recent call last):
  File "/usr/bin/cowsandbulls", line 9, in <module>
    load_entry_point('cowsandbulls==1.0', 'gui_scripts', 'cowsandbulls')()
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 337, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2311, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2017, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
ImportError: No module named cowsandbulls

person IcyFlame    schedule 01.07.2013    source источник


Ответы (2)


Я только что протестировал stdeb (см. https://pypi.python.org/pypi/stdeb), пакет Python для превращения любого другого пакета Python в пакет Debian.

Сначала я установил stdeb:

apt-get install python-stdeb

Затем я сделал простой скрипт под названием myscript.py со следующим содержимым:

def main():
    print "Hello world, says myscript!"
    # wait for input from the user
    raw_input()

if __name__ == '__main__':
    main()

Важно отметить, что ваша структура каталогов должна быть:

somewhere/myscript/
    setup.py
    myscript/
        __init__.py
        myscript.py

В файле setup.py вы делаете что-то вроде:

import os
from setuptools import setup
from nvpy import nvpy

setup(
    name = "myscript",
    version = "1.0",
    author = "Charl P. Botha",
    author_email = "[email protected]",
    description = "Demo of packaging a Python script as DEB",
    license = "BSD",
    url = "https://github.com/cpbotha/nvpy",
    packages=['myscript'],
    entry_points = {
        'console_scripts' : ['myscript = myscript.myscript:main']
    },
    data_files = [
        ('share/applications/', ['vxlabs-myscript.desktop'])
    ],
    classifiers=[
        "License :: OSI Approved :: BSD License",
    ],
)

Директива console_scripts важна, и она создаст исполняемый скрипт с именем my_script, который будет доступен для всей системы после установки результирующего DEB. Если ваш сценарий использует что-то вроде tkinter или wxpython и имеет графический интерфейс пользователя, вам следует использовать gui_scripts вместо console_scripts.

Директива data_files установит подходящий файл рабочего стола в /usr/share/applications, чтобы вы также могли запускать myscript из среды рабочего стола. vxlabs-myscript.desktop выглядит так:

[Desktop Entry]
Version=1.0
Type=Application
Name=myscript
Comment=Minimal stdeb example
# myscript should wait for user input at the end, else the terminal
# window will disappear immediately.
Exec=myscript
Icon=/usr/share/icons/gnome/48x48/apps/file-manager.png
Categories=Utility;
# desktop should run this in a terminal application
Terminal=true
StartupNotify=true
StartupWMClass=myscript

Чтобы построить DEB, вы делаете следующее на верхнем уровне myscript:

python setup.py --command-packages=stdeb.command bdist_deb

Что создаст .deb в каталоге deb_dist.

После установки DEB, который я создал таким образом, я мог запустить myscript из командной строки, а также вызвать его из среды рабочего стола.

Вот репозиторий GitHub с приведенным выше примером кода: https://github.com/cpbotha/stdeb-minimal-example

person Charl Botha    schedule 01.07.2013
comment
Сэр: каким должно быть содержание __init__.py? - person IcyFlame; 01.07.2013
comment
__init__.py — это пустой файл, но он должен быть у вас, иначе самый внутренний каталог myscript не будет восприниматься как пакет и не будет доступен для импорта. Ссылка на github, которую я разместил внизу своего ответа, содержит весь код. - person Charl Botha; 01.07.2013
comment
можно ли изменить точку входа на имя какой-то другой функции? - person IcyFlame; 01.07.2013
comment
конечно, вы можете, если рассматриваемый модуль является импортируемым, а функция вызывается. :) - person Charl Botha; 01.07.2013
comment
Это ошибка, которую вы увидите, если забудете __init__.py в том же каталоге, что и ваш собственный файл .py, содержащий точку входа. Просто чтобы быть уверенным на 100%, это два символа подчеркивания, два символа подчеркивания, точка py. - person Charl Botha; 01.07.2013
comment
Понятно! Большое спасибо! Модуль myscript должен иметь то же имя, что и сам файл .py. Я что-то напутал! - person IcyFlame; 01.07.2013
comment
Я не понимаю, как использовать файл setup.py, на который вы мне указали. Не могли бы вы добавить некоторые разъяснения для того же самого? Я получил директиву data_files. Но я не знаю, что с этим делать. - person IcyFlame; 01.07.2013
comment
Добавлен пример файла .desktop для ответа. Я считаю, что мой ответ теперь на 100% завершен и самодостаточен. :) SO тоже не любит это долгое обсуждение, так что давайте остановимся на этом. - person Charl Botha; 01.07.2013
comment
Да сэр...! Это полный ответ со всеми особенностями. И этот процесс намного проще, чем в двух руководствах, на которые я ссылался. Большое спасибо за ответ..! (P.S.: да, я заметил, что это длинновато. Но это было необходимо!) - person IcyFlame; 01.07.2013
comment
@CharlBotha Я практиковался с вашим примером кода, который я скачал с GitHub. Я получаю следующую ошибку: error: can't copy 'vxlabs-myscript.desktop': doesn't exist or not a regular file. Я ничего не менял в вашей файловой структуре. Файл очень много присутствует в папке. Вы знаете, что может происходить? (У меня была такая же проблема с моим собственным проектом, поэтому я попробовал ваш) - person Stefan van den Akker; 09.10.2014
comment
Я понял. Видимо, в моем случае необходимо было создать файл MANIFEST.in в той же директории, что и файл setup.py с содержимым include vxlabs-myscript.desktop. - person Stefan van den Akker; 09.10.2014
comment
Совет: в имени не должно быть пробелов. Если в нем есть пробелы, вы получите Невозможно вызвать метод as_string для неопределенного значения в /usr/share/perl5/Dpkg/Changelog.pm, строка 249. - person Sameera K; 27.05.2020
comment
что делает параметр пакетов в setup.py? - person Watch With Veer; 15.04.2021

Правильный способ создания пакета deb — использовать dpkg-buildpackage, но иногда это немного сложно. Вместо этого вы можете использовать dpkg -b <folder>, и он создаст ваш пакет Debian.

Это основы для создания пакета Debian с dpkg -b <folder> с любым двоичным файлом или любым скриптом, который запускается автоматически без необходимости ручной компиляции (Python, Bash, Pearl и Ruby):

  1. Создайте файлы и папки, чтобы воссоздать следующую структуру:
    ProgramName-Version/
    ProgramName-Version/DEBIAN
    ProgramName-Version/DEBIAN/control
    ProgramName-Version/usr/
    ProgramName-Version/usr/bin/
    ProgramName-Version/usr/bin/your_script

Скрипты, размещенные в /usr/bin/, вызываются непосредственно из терминала. Обратите внимание, что я не добавлял расширение к сценарию.

Кроме того, вы можете заметить, что структура пакета deb будет соответствовать структуре программы после ее установки. Поэтому, если вы следуете этой логике, если ваша программа имеет один файл, вы можете напрямую поместить его в ProgramName-Version/usr/bin/your_script, но если у вас несколько файлов, вы должны поместить их в ProgramName-Version/usr/share/ProgramName/all your files и поместить только один файл в /usr/bin/, который будет вызывать ваши скрипты из /usr/share/ProgramName/.

  1. Измените все права доступа к папке на root:

    chown root:root -R /path/to/ProgramName-Version
    
  2. Измените разрешения скрипта:

    chmod 0755 /path/to/the/script
    
  3. Наконец, вы можете запустить: dpkg -b /path/to/the/ProgramName-Version и ваш пакет deb будет создан! (Вы также можете добавить сценарии post/pre inst и все, что хотите; это работает как обычный пакет Debian.)


Вот пример файла control. Вам нужно только скопировать и вставить его в пустой файл с именем «control» и поместить его в папку DEBIAN.

Package: ProgramName
Version: VERSION
Architecture: all
Maintainer: YOUR NAME <EMAIL>
Depends: python2.7, etc , etc,
Installed-Size: in_kb
Homepage: http://foo.com
Description: Here you can put a one line description. This is the short Description.
 Here you put the long description, indented by 1 space.

Если вы хотите построить с помощью dpkg -b <folder>, вы можете использовать эту программу, которая сделает все одной командой. Если вы регулярно собираете пакеты, делать все то, что я упомянул, очень сложно!

*Руководство взято из Основы пакетов Debian.

person Community    schedule 28.09.2014
comment
Проблема с этим ответом в том, что он не отвечает на вопрос, который сводится к тому, как создать необходимую структуру через файл setup.py? т.е. как перейти от стандартного пакета Python к файлу .deb. Есть ли способ для pip установить в chroot, который может видеть dpkg-buildpackage? - person davidA; 06.10.2020