Packaging: Difference between revisions

From iPhone Development Wiki
(infinite upgrade troubleshooting)
Line 61: Line 61:


=== dpkg-deb ===
=== dpkg-deb ===
=== Infinite upgrade ===
Does Cydia seem to think a package on your repository has an available upgrade no matter what you do? Check the control file for that package - you might have an error in it, such as a duplicated line.

Revision as of 21:53, 8 January 2015

Packaging is the step prior to sharing or releasing a tweak/application/tool/library/theme. Here you put all your project files into a single nicely wrapped file that others can install on their devices.

Cydia is based on Debian APT (Advanced Packaging Tool), so a lot of general documentation about packaging for APT also applies to packaging for Cydia.

Tools

To do: add existing tools, on which platforms they are available, how to use them.

DEBIAN folder

Control file

To do: add layout of fields, what do they mean, how they are used. Refer to saurik's post and links at the bottom.

If you need to list dependencies or conflicting packages, Debian's packaging manual may be useful (because Cydia packaging is based on Debian packaging): Syntax of relationship fields, Dependencies, Conflicts -- or if you're submitting this package to a default repository, you can just ask your repository maintainer for help with this.

Other files

You can add preinst, postinst, extrainst_, prerm, and postrm files to run scripts at various points of the package installation and uninstallation lifecycle. It's important to be conservative with this code - as Best Practices explains, "Do not use postinst/preinst/extrainst_ for file management purposes! Do not store in the package files or directories that your software could create. Do not enforce permissions that your package should contain. dpkg uses an expressive packaging format that has support for permissions, ownership, and links. Use that support!"

If your package scripts have problems, especially upon uninstallation, this can be very frustrating for your user because that can be very hard to fix for them. You don't want to cause the dreaded "subprocess pre-removal script returned error" and "Sub-process /usr/bin/dpkg returned an error code" error messages. A related unfortunate reality is that if your package has complex scripts, that can increase the chances that if a pirate repository poorly repackages your tweak, somebody doing "try before they buy" can run into those error messages and get frustrated.

Documentation about these scripts in the Debian packaging manual: basics and more info.

extrainst_

I get a lot of requests for things like "I want to run stuff after the install, but only on install, not on upgrade". APT/dpkg is miserable at this. Its sad, but true. It has a file called postinst, but postinst is really designed for reconfiguring a package, not for installing it: its called /long after/ the package is installed (like, APT will go on and install more things and then queue up the postinst files to the very end) and it doesn't /really/ know anything about the package.

Example: in a postinst you know that the previous configuration on disk was from version 1.0, but not that 1.0 itself was actually on disk. And if you are a new install it still tells you that /you're/ already the configuration there (which is really just a stupid semantic).

/So/, after dealing with an issue in a package with _BigBoss_, I have decided to do something about this: I have added to dpkg a new script called extrainst_. This script takes one of two arguments: install or upgrade (in which case you also get the version you are upgrading from), and is designed to completely ignore configuration files (so if you were previously in a configuration file only state that isn't considered "installed"). I believe that this new script now provides a very simple conceptualization for how you do "extra stuff" during an install.

In fact, if you are previously coming from Installer, this script will likely feel like "ahhhh".

To use this new script (which yes, really ends in an underscore) your package should Pre-Depends: dpkg (>= 1.13.25-5). This will make it so that that version of dpkg is actually available during the install and is used to run the scripts. (Yes, this will work even during the install using the old version of dpkg to upgrade dpkg and then switching to the new version of dpkg to install your script ;P).

If this script fails then the install is considered to not have worked and the installation procedure will get rolled back (files will get removed, replaced back to the backup copies if it was an upgrade, and a million random scripts will get called with irritatingly complicated to remember arguments).

(Note that this version of dpkg isn't up right now, but will be up within an hour or two: i.e., long before any of you is likely to bother to try to use it ;P).

An example extrainst_:

#!/bin/bash

if [[ $1 == install || $1 == upgrade ]]; then
    do_something awesome
fi

if [[ $1 == upgrade && $2 == 1.0-4 ]]; then
   fix_bug_in old version
fi

-J

To see the whole discussion about this, see this thread.

Telling Cydia to respring/reboot etc. after install

To do: Consider this paste as one example. Explain how it fits into Debian packaging (how it interacts with apt/aptitude/dpkg/Cydia).

Troubleshooting

dpkg-deb

Infinite upgrade

Does Cydia seem to think a package on your repository has an available upgrade no matter what you do? Check the control file for that package - you might have an error in it, such as a duplicated line.