Хотя в архиве Ubuntu имеются тысячи пакетов, есть ещё много программ, которыми никто не занимается. Если вы знаете о какой-то замечательной программе, о которой, по вашему мнению, стоит узнать более широкому кругу пользователей, вы можете попробовать приложить свою руку к созданию пакета для Ubuntu или PPA. Это руководство проведёт вас через этапы создания пакета для новой программы.
Сначала вам следует прочитать статью Подготовка, чтобы подготовить свою среду разработки.
4.1. Проверка программы¶
Первым этапом создания пакета является получение tar-файла из апстрима («апстримом» мы называем авторов приложений) и проверка того, что он нормально компилируется и запускается.
Это руководство проведёт вас через процесс создания пакета для небольшого приложения GNU Hello, доступного на GNU.org.
Download GNU Hello:
$ wget -O hello-2.10.tar.gz «http://ftp.gnu.org/gnu/hello/hello-2.10.tar.gz»
Now uncompress it:
$ tar xf hello-2.10.tar.gz $ cd hello-2.10
Это приложение использует систему сборки autoconf, так что нам нужно запустить ./configure для подготовки к компиляции.
Linux: сборка пакетов из исходников
This will check for the required build dependencies. As hello is a simple example, build-essential and texinfo should provide everything we need. For more complex programs, the command will fail if you do not have the needed libraries and development files. Install the needed packages and repeat until the command runs successfully.:
$ ./configure
Теперь нужно скомпилировать исходный код:
$ make
Если компиляция завершилась успешно, можно установить и запустить программу:
$ sudo make install $ hello
4.2. Создание пакета¶
bzr-builddeb includes a plugin to create a new package from a template. The plugin is a wrapper around the dh_make command. Run the command providing the package name, version number, and path to the upstream tarball:
$ sudo apt-get install dh-make bzr-builddeb $ cd .. $ bzr dh-make hello 2.10 hello-2.10.tar.gz
Note: unfortunately the bzr dh-make subcommand is no longer available in releases later than Ubuntu 20.04; so, you might need a container or virtual machine (see LXD) running Ubuntu 20.04 for this particular step.
Когда он спросит тип пакета, выберите s : одиночный бинарник. Это импортирует код в ветку и создаст папку debian/ . Взгляните на её содержимое: большинство автоматически созданных файлов требуются лишь для специализированных пакетов (например, модули Emacs), так что можно начать с удаления лишних файлов:
$ cd hello/debian $ rm *ex *EX
Теперь нужно внести изменения в каждый из файлов.
In debian/changelog change the version number to an Ubuntu version: 2.10-0ubuntu1 (upstream version 2.10, Debian version 0, Ubuntu version 1). Also change unstable to the current development Ubuntu release such as trusty .
Большая часть процесса компиляции пакета совершается скриптами из debhelper . Так как поведение debhelper меняется при выходе старшей версии, файл compat сообщает debhelper ‘у какую именно версию использовать. Имеет смысл использовать наиболее свежую версию: 9 .
Урок 18 — Пакет программ Microsoft Office бесплатный и мобильный | Компьютерные курсы 2020 (Win 10)
Файл control содержит все метаданные пакета. Первый абзац описывает пакет исходных кодов. Второй и следующие абзацы описывают двоичные пакеты, которые должны быть собраны. Нам понадобится добавить пакеты, необходимые для компиляции приложения в Build-Depends: . Для hello он должен включать, как минимум:
Build-Depends: debhelper (>= 9)
And append texinfo , as noted earlier:
Build-Depends: debhelper (>= 9), texinfo
Также нужно заполнить описание программы в поле Description: .
copyright нужно заполнить в соответствии с лицензией на источник из апстрима. Согласно файлу hello/COPYING, это лицензия GNU GPL 3 или более поздняя её версия.
docs должен содержать любые файлы документации из апстрима, которые, по вашему мнению, должны быть включены в готовый пакет.
README.source и README.Debian необходимы, лишь если ваш пакет имеет какие-то нестандартные функции. У нас таких нет, так что можно удалить эти файлы.
source/format можно оставить как есть, он описывает формат версии пакета исходного кода, который должен быть 3.0 (quilt) .
rules — самый сложный файл. Это Makefile, который компилирует код и превращает его в двоичный пакет. К счастью, основную часть работы в наши дни автоматически выполняет debhelper 7 , так что универсальная цель % просто запускает сценарий dh , который делает всё, что необходимо.
Все эти файлы подробнее описаны в статье обзор каталога debian.
Finally commit the code to your packaging branch (make sure to bzr add any untracked files that changed; for example, debian/source/format ):
$ bzr add debian/source/format $ bzr commit -m «Initial commit of Debian packaging.»
4.3. Сборка пакета¶
Теперь нам нужно проверить, что наши исходные файлы для пакета успешно компилируются и собираются в двоичный .deb-пакет:
$ bzr builddeb — -us -uc $ cd ../../
bzr builddeb — это команда для сборки пакета в его текущем местоположении. -us -uc сообщает что подписывать пакет с помощью GPG не требуется. Результат будет помещён в каталог «..».
Note: if it fails with You must run ./configure before running ‘make’. , add this to debian/rules (make sure to bzr add/commit it) and retry bzr builddeb :
override_dh_auto_clean: [ -f Makefile ] || ./configure dh_auto_clean
Просмотреть содержимое пакета можно с помощью:
$ lesspipe hello_2.10-0ubuntu1_amd64.deb
Установите пакет и проверьте, что он работает (позднее при желании вы сможете удалить его командой sudo apt-get remove hello ):
$ sudo dpkg —install hello_2.10-0ubuntu1_amd64.deb
Можете также установить все пакеты сразу с помощью:
$ sudo debi
4.4. Дальнейшие шаги¶
Даже если двоичный .deb-пакет успешно собирается, ваши исходные файлы для пакета могут содержать ошибки. Многие ошибки могут автоматически обнаруживаться нашим инструментом lintian , который можно применить к файлу метаданных .dsc, двоичным пакетам .deb или файлу .changes:
$ lintian hello_2.10-0ubuntu1.dsc $ lintian hello_2.10-0ubuntu1_amd64.deb
Чтобы увидеть подробное описание ошибок, используйте флаг lintian —info или команду lintian-info .
Для пакетов Python имеется также инструмент lintian4python , осуществляющий некоторые дополнительные проверки lintian.
После создания исправления для файлов пакета можно пересобрать его с параметром -nc (“no clean”), чтобы не начинать сборку с самого начала:
$ bzr builddeb — -nc -us -uc
Убедившись, что пакет успешно собирается локально, вы должны проверить, правильно ли его сборка будет проходить в чистой системе, с помощью pbuilder . Поскольку вскоре мы собираемся загрузить его в PPA (персональный архив пакетов), эту загрузку нужно снабдить цифровой подписью, чтобы Launchpad мог удостовериться, что загрузку сделали вы (узнать о том, что загрузка будет подписана, можно по отсутствию передаваемых bzr builddeb флагов -us и -uc , которые мы использовали ранее). Для подписывания своей работы вам понадобится настроить GPG. Если вы ещё не настроили pbuilder-dist или GPG, сделайте это сейчас:
$ bzr builddeb -S $ cd ../build-area $ pbuilder-dist trusty build hello_2.10-0ubuntu1.dsc
После того как вы останетесь довольны получившимся пакетом, нужно, чтобы его проверили другие люди. Вы можете выгрузить ветку на Launchpad для проверки:
$ bzr push lp:~/+junk/hello-package
Выгрузка в PPA позволит удостовериться, что пакет собирается нормально, а также позволит вам и остальным тестировать бинарные пакеты. Вам потребуется создать PPA на Launchpad, после чего выгрузить пакет с помощью dput :
$ dput ppa:/ hello_2.10-0ubuntu1.changes
Попросить провести review можно на канале IRC #ubuntu-motu , или в списке рассылки MOTU. В некоторых случаях может потребоваться участие конкретной команды: в подобных случаях команда GNU поможет разобраться.
4.5. Отправка на включение¶
Существует несколько путей, которыми пакет может попасть в Ubuntu. В большинстве случаев лучшим путём может быть прохождение сначала через Debian. Это позволит вашему пакету стать доступным для наибольшего количества пользователей, так как он будет доступен не только в Debian и Ubuntu, но и во всех дистрибутивах, созданных на их основе. Вот несколько полезных ссылок по отправке новых пакетов в Debian:
- Debian Mentors FAQ — debian-mentors создан для менторства новых и перспективных разработчиков Debian. Это то место, где можно найти спонсора для загрузки Вашего пакета в архив.
- Work-Needing and Prospective Packages — информация о том как отправлять баги “Intent to Package” (Назначение пакету) и “Request for Package” (Запрос пакета), а также списки открытых ITP и RFP.
- Руководство Разработчика Debian, 5.1. Создание пакетов — бесценный документ для создателей пакетов как под Ubuntu, так и под Debian. Данная глава описывает процесс отправки новых пакетов.
В некоторых случаях имеет смысл отправляться прямо в Ubuntu. Например, если Debian находится в состоянии “freeze”: тогда ваш пакет врядли успеет войти в Ubuntu к ближайшему релизу. Этот процесс описан на странице “Новые Пакеты” Ubuntu Wiki.
Источник: packaging.ubuntu.com
Создание пакета приложения (C++)
Узнайте, как создать пакет приложения для приложения Windows с помощью API упаковки.
Если вы хотите создать пакет классического приложения вручную, можно также использовать средство MakeAppx.exe, которое использует API упаковки. Дополнительные сведения см. в статье Средство упаковки приложений (MakeAppx.exe).
Если вы используете Visual Studio, рекомендуется использовать мастер упаковки Visual Studio для упаковки приложения. Дополнительные сведения см. в статье Упаковка приложения UWP с помощью Visual Studio.
Инструкции
Шаг 1. Создание модуля записи пакетов
Чтобы создать модуль записи пакетов, вызовите метод IAppxFactory::CreatePackageWriter . Первый параметр — это выходной поток, в который будет записан пакет. Второй параметр является указателем на структуру APPX_PACKAGE_SETTINGS , указывающую параметры пакета. Третий параметр является выходным параметром, который получает указатель на указатель IAppxPackageWriter .
#include #include #include // We store the produced package under this file name. const LPCWSTR OutputPackagePath = L»HelloWorld.appx»; int wmain() < HRESULT hr = S_OK; // Specify the appropriate COM threading model hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); if (SUCCEEDED(hr)) < // Create a package writer IAppxPackageWriter* packageWriter = NULL; hr = GetPackageWriter(OutputPackagePath, >> // // Creates an app package writer with default settings. // // Parameters: // outputFileName // Fully qualified name of the app package (.appx file) to be created. // writer // On success, receives the created instance of IAppxPackageWriter. // HRESULT GetPackageWriter( _In_ LPCWSTR outputFileName, _Outptr_ IAppxPackageWriter** writer) < const LPCWSTR Sha256AlgorithmUri = L»https://www.w3.org/2001/04/xmlenc#sha256″; HRESULT hr = S_OK; IStream* outputStream = NULL; IUri* hashMethod = NULL; APPX_PACKAGE_SETTINGS packageSettings = ; IAppxFactory* appxFactory = NULL; // Create a stream over the output file for the package hr = SHCreateStreamOnFileEx( outputFileName, STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, // default file attributes TRUE, // create file if it does not exist NULL, // no template // Create default package writer settings, including hash algorithm URI // and Zip format. if (SUCCEEDED(hr)) < hr = CreateUri( Sha256AlgorithmUri, Uri_CREATE_CANONICALIZE, 0, // reserved parameter >if (SUCCEEDED(hr)) < packageSettings.forceZip32 = TRUE; packageSettings.hashMethod = hashMethod; >// Create a new Appx factory if (SUCCEEDED(hr)) < hr = CoCreateInstance( __uuidof(AppxFactory), NULL, CLSCTX_INPROC_SERVER, __uuidof(IAppxFactory), (LPVOID*)( >// Create a new package writer using the factory if (SUCCEEDED(hr)) < hr = appxFactory->CreatePackageWriter( outputStream, > // Clean up allocated resources if (appxFactory != NULL) < appxFactory->Release(); appxFactory = NULL; > if (hashMethod != NULL) < hashMethod->Release(); hashMethod = NULL; > if (outputStream != NULL) < outputStream->Release(); outputStream = NULL; > return hr; >
Шаг 2. Добавление файлов полезных данных для приложения в пакет
Вызовите метод IAppxPackageWriter::AddPayloadFile , чтобы добавить файлы в пакет. Первый параметр — это относительный путь к файлу. Второй параметр указывает тип содержимого файла. Третий параметр задает параметры из перечисления APPX_COMPRESSION_OPTION . Четвертый параметр — входной поток для файла.
// Path where all input files are stored const LPCWSTR DataPath = L»Data\»; // Add all payload files to the package writer for (int i = 0; SUCCEEDED(hr) (i < PayloadFilesCount); i++) < IStream* fileStream = NULL; hr = GetFileStream(DataPath, PayloadFilesName[i], if (SUCCEEDED(hr)) < packageWriter->AddPayloadFile( PayloadFilesName[i], PayloadFilesContentType[i], PayloadFilesCompression[i], fileStream); > if (fileStream != NULL) < fileStream->Release(); fileStream = NULL; > > >
В предыдущем коде используются эти определения переменных и GetFileStream вспомогательная функция.
#include #include // The produced app package’s content consists of these files, with // corresponding content types and compression options. const int PayloadFilesCount = 4; const LPCWSTR PayloadFilesName[PayloadFilesCount] = < L»AppTile.png», L»Default.html», L»images\smiley.jpg», L»Error.html», >; const LPCWSTR PayloadFilesContentType[PayloadFilesCount] = < L»image/png», L»text/html», L»image/jpeg», L»text/html», >; const APPX_COMPRESSION_OPTION PayloadFilesCompression[PayloadFilesCount] = < APPX_COMPRESSION_OPTION_NONE, APPX_COMPRESSION_OPTION_NORMAL, APPX_COMPRESSION_OPTION_NONE, APPX_COMPRESSION_OPTION_NORMAL, >; // // Creates a readable IStream over the specified file. For simplicity, we assume that the fully // qualified file name is 100 characters or less.
Your code should // handle longer names, and allocate the buffer dynamically. // // Parameters: // path // Path of the folder that contains the file to be opened; must end with a » // fileName // Name, of the file to be opened, not including the path // stream // On success, receives the created instance of IStream // HRESULT GetFileStream( _In_ LPCWSTR path, _In_ LPCWSTR fileName, _Outptr_ IStream** stream) < HRESULT hr = S_OK; const int MaxFileNameLength = 100; WCHAR fullFileName[MaxFileNameLength + 1]; // Create full file name by concatenating path and fileName hr = StringCchCopyW(fullFileName, MaxFileNameLength, path); if (SUCCEEDED(hr)) < hr = StringCchCat(fullFileName, MaxFileNameLength, fileName); >// Create stream for reading the file if (SUCCEEDED(hr)) < hr = SHCreateStreamOnFileEx( fullFileName, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, // default file attributes FALSE, // don’t create new file NULL, // no template stream); >return hr; >
Шаг 3. Добавление манифеста пакета в пакет
Каждый пакет должен иметь манифест пакета. Чтобы добавить манифест пакета в пакет, создайте входной поток для файла, а затем вызовите метод IAppxPackageWriter::Close , чтобы записать манифест в конце пакета и закрыть выходной поток для модуля записи пакетов.
В этом коде используется GetFileStream вспомогащая функция, показанная на предыдущем шаге, для создания потока для манифеста пакета.
// We read the app package’s manifest from this file const LPCWSTR ManifestFileName = L»AppxManifest.xml»; IStream* manifestStream = NULL; hr = GetFileStream(DataPath, ManifestFileName, if (SUCCEEDED(hr)) < hr = packageWriter->Close(manifestStream); > if (manifestStream != NULL) < manifestStream->Release(); manifestStream = NULL; >
Шаг 4. Очистка модуля записи пакетов
Перед возвращением wmain из функции вызовите метод Release для очистки модуля записи пакетов и вызовите функцию CoUninitialize .
if (packageWriter != NULL) < packageWriter->Release(); packageWriter = NULL; > CoUninitialize();
Связанные темы
Примеры
Справочные материалы
Источник: learn.microsoft.com
Как создать пакет программ
В этой статье мы рассмотрим как создать deb пакет для своей программы без использования каких-либо сторонних инструментов. Мы не будем рассматривать подпись пакетов для репозиториев, потому что для каждого вида репозиториев команды будут отличаться.
Самый популярный способ распространения программ в Linux – это репозитории программного обеспечения. В репозиториях программы находятся в специальном формате. В Debian и основанных на нём дистрибутивах используется формат пакетов deb. В этих пакетах находится архив всех файлов программы, инструкции по их установке в системе для пакетного менеджера, а также другая служебная информация.
Создание deb пакетов
Шаг 1. Подготовка
Давайте создадим для этого примера небольшую программу на Си. Она будет называться hellolosst и будет выводить на экран строку Hello from losst.ru в терминал при запуске. Сначала создайте папку hellolosst и перейдите в неё:
mkdir hellolosst
cd hellolosst
Затем поместите в неё файл с исходным кодом:
#include
int main() printf(“Hello from losst.run”);
>
Для компиляции программы выполните такую команду:
gcc hellolosst.c -o hellolosst
Затем вы можете её выполнить:
Таким образом, теперь у нас есть программа, которую надо упаковать в deb пакет.
2. Создание манифеста
В каждом deb пакете содержаться не только файлы самой программы, но и файл манифеста, в котором описан пакет, его зависимости и параметры. Этот файл имеет название control и должен находится в папке DEBIAN. Для сборки пакета будем использовать папку package, чтобы файлы программы не путались с исходными файлами и те не попали в пакет. Создайте эти папку:
mkdir -p package/DEBIAN
Прежде чем вы сможете создать этот файл надо узнать несколько вещей. Первым делом надо посмотреть размер файлов программы, поскольку в данном случае файл один, достаточно посмотреть его размер:
du -k ./hellolosst
Если файлов несколько, то можно удалить исходники и посмотреть общий размер папки с файлами программы. Дальше надо понять от каких пакетов будет зависеть ваша программа. Для этого воспользуйтесь командой objdump:
objdump -p ./hellolosst | grep NEEDED
В данном случае программе необходима только libc. Чтобы посмотреть в каком пакете она находится выполните:
Пакет называется libc6. Затем создайте файл манифеста со следующим содержимым:
Package: hellolosst
Version: 1.0
Section: unknown
Priority: optional
Depends: libc6
Architecture: amd64
Essential: no
Installed-Size: 20
Maintainer: losst.ru
Description: Print hello from losst line
Это минимальный набор параметров в файле манифеста. Вот их значение:
- Package – имя пакета;
- Version – версия программы в пакете, будет использована при обновлении пакета;
- Section – категория пакета, позволяет определить зачем он нужен;
- Priority – важность пакета, для новых пакетов, которые ни с чем не конфликтуют обычно прописывают optional, кроме того доступны значения required, important или standard;
- Depends – от каких пакетов зависит ваш пакет, он не может быть установлен, пока не установлены эти пакеты;
- Recommends – необязательные пакеты, но тем не менее они обычно устанавливаются по умолчанию в apt;
- Conflicts – пакет не будет установлен, пока в системе присутствуют перечисленные здесь пакеты;
- Architecture – архитектура системы, в которой можно установить этот пакет, доступные значения: i386, amd64, all, последнее означает, что архитектура не имеет значения;
- Installed-Size – общий размер программы после установки;
- Maintainer – указывает кто собрал этот пакет и кто отвечает за его поддержку;
- Description – краткое описание пакета.
3. Расположение файлов
Манифест готов. Теперь в папке пакета надо создать структуру папок, аналог того, что есть в корневой файловой системе. В данном случае надо создать папку usr/bin и поместить туда исполняемый файл:
mkdir -p package/usr/bin
mv ./hellolosst package/usr/bin
4. Скрипты установки
Несмотря на то, что система установки пакетов очень мощная и позволяет делать многое, некоторые вещи всё же сделать нельзя. Для решения этой проблемы была предусмотрена возможность выполнять скрипты перед установкой пакета и после. Аналогично это работает для удаления пакета – перед и после. Эти скрипты называются preinst, postinst, prerm и postrm. Каждый файл просто содержит набор скриптов, которые надо выполнить. Например:
#!/bin/bash
echo “Hello from losst installed”
Разработчики Debian не рекомендуют использовать эти скрипты без крайней надобности, поскольку они дают вам полный контроль над системой пользователя и вы можете случайно что-то повредить. Обычно эти скрипты используются для того чтобы задавать пользователям вопросы и на основе этого генерировать конфигурационные файлы.
5. Сборка и проверка пакета
Осталось собрать настроенный пакет. Для этого используйте такую команду:
dpkg-deb –build ./package
Теперь вы знаете как как собрать deb пакет. После завершения сборки можете установить его с помощью apt:
sudo apt install ~/hellolosst.deb
После этого исполняемый файл программы появится в /usr/bin, а сообщение из postinst будет выведено после установки.
Выводы
В этой небольшой статье мы рассмотрели как выполняется создание deb пакета с помощью инструмента dpkg-deb. Как видите, всё очень просто. Вам достаточно написать манифест и расположить файлы там, где они должны быть. Мы рассмотрели здесь только самые основы. На самом деле создание пакетов намного сложнее.
Существует целый набор утилит debhelpers, которые используются на различных этапах сборки и установки deb пакетов, подробнее обо всём этом вы можете прочитать в официальной документации.
Источник: unlix.ru