In an ideal world, software developers should merely prepare their software to make it easier for packagers to whip up a package based on a template. As a packager I know the pain of having to discover the magical way a piece of code is intended to be built, tracking down its dependencies, and stringing together the means of packaging the finished product based on how the developer assembled it.

Some of the problems you'll face when packaging random code:

* non-standard version numbers
* non-standard file paths
* non-standard configure/make/install routines (or none at all)
* custom or non-standard build/install tools
* lack of build/configure/install documentation
* lack of dependency documentation (including what versions of what dependencies might conflict)
* code that isn't portable past the desktop the developer wrote it on
* lack of best practices in setting up multi-user permissions
* lack of pre/post install scripts
* lack of simple init scripts
* lack of minimal configuration files
* lack of pidfile, log rotation, crontab, environment, and other necessary ops functions
* patching code just to get them to build and install on your distro
* bundled, highly patched, third-party software (!!!)

Learning to make packages is easy, but what's even easier is leaving your source in a state that's convenient for packagers of all distros to put it together with little or no effort. Here's some suggestions on how to do this:

1. Make sure your code is portable. Please, try not to hardcode things; use a 'configure'-type process to allow someone to override things like file paths, usernames, and other variable data. Test it on multiple architectures or distributions to see what kind of dependencies you might need to document.

2. PLEASE use a standard configure/make/make install method for your language, and don't write one yourself or depend on some backwards antiquated build tool that nobody uses. Interpreted languages often have their own standard, and compiled languages often use autoconf/automake. Learn them and use them, or at the very least, make an incredibly basic Makefile. And please document the expected permissions and users (chowns/chgrps/chmods).

3. Make sure that you can run one command for each of the configure/make/make install steps. Make sure it can be passed options or environment variables to change the root directory to install into. Make sure your install procedure puts them all in Filesystem Hierarchy Standard paths. Make sure it works as a non-root user; the packager will add the permissions and ownership as metadata to the package.

4. Provide working samples of all the things your app will need. Crontabs, log rotation, pid file tracking for daemons, configuration files, documentation, init scripts, preinstall/postinstall/uninstall scripts.

5. For the love of god, use standard version numbers. Either X.XXXX, X.XX.XX, or X.X.X.X. Pick one and stick with it. Otherwise different distros might actually use different version schemes for their packages which confuses everyone. Please don't include any non-numeric characters (fuck you, openssl! hex doesn't belong in versions!!!)

6. Fully document your ChangeLogs. A packager needs to know that your new release now requires a newer dependency or breaks ABI compatibility, because now they have to modify the metadata of the package to specify what deps will or won't work. Remember that users often install and uninstall different versions of different software.