h1. How to make packages for RISC OS RISC OS on the Raspberry Pi has been the first release with a _package manager_ available to upgrade the system and install new programs. This guide describes how to make new packages and submit them to the package repository. All this is very new at the moment, both the RISC OS software, the documentation and the server infrastructure, so please bear with it as things settle down. h2. Packaging programs - PackMan, !Store, RiscPkg There are two programs for installing new software on RISC OS Pi, !Store and PackMan. These are two complementary systems, which operate in different ways. !Store is primarily an index of available software, and a way to buy commercial software. It stores and downloads software, but leaves it to the user to install and upgrade programs. PackMan is a package manager, in that it both has an index and download function, but also installs and upgrades. In RISC OS Pi, PackMan is the primary interface for updating the OS distribution after it's been released, including new ROMs and other system components. PackMan wasn't written from scratch, it uses the underlying package format and code from a previous packaging system called RiscPkg. RiscPkg laid much of the groundwork for the packaging system as it now stands, but has seen little development in recent years. Some users also criticised it for lacking in user-friendliness, hence PackMan was written. Some of the terminology continues to refer to RiscPkg however. In theory RiscPkg and PackMan will operate on the same database - in other words you can use them interchangeably - but this hasn't been tested recently. h2. Using PackMan For more details on using PackMan to install, move, upgrade, remove, etc packages, see the [[PackMan User's Guide]]. h2. What is a package? A packaging system that automatically installs programs needs them to be structured so that it knows where to put all the files. For example on RISC OS, files need to be installed in !System, !Boot.Resources, and other places. PackMan will handle this, but you need to tell it what you want. In addition, it needs to have information about the program itself - the name, the version, a description, dependencies (what other packages are needed for this one to operate), and so on. As it happens, PackMan packages are Zip files which are structured in a particular way to aid auto-installation. This means you can view PackMan as a clever unzip tool that keeps track of everything it unzips, so that it can rollback when things change (for example, a program is removed). PackMan maintains a database of the files and packages it knows about. It's also possible to manually install programs from PackMan packages (they're just Zip files after all) but, since this is not recorded by PackMan in its database, such manual installs won't be updated unless you do it yourself. h2. What does a package consist of? There's two main components of a package: the program/data files themselves and the packaging information. Earlier versions also included the system variables and the sprites. These are now deprecated. PackMan from 0.8 onwards can use the RISC OS Boot mechanism to perform the equivalent functionality. h2. How do I make a package? First, think about how to structure your package. One consideration of packaging is that your files will be pushed to the user's machine. The user can use PackMan to move applications around, but it's not appropriate to have a haphazard file layout in your package because you'll impose it on all users. So, ideally, design your program so that it's stored in an application, rather than a directory full of files. For example, put your documentation and example documents in a directory and have that open when the user clicks Help from the Filer menu on your app. Also, think about how you might split up your program into multiple packages. For example, users might not want to install all the documentation, or the tutorials, on a machine with a small amount of storage. You might want to make packages like MyApp, MyApp-Tutorials, MyApp-Examples, and so on, instead of one huge package. Or you might use a module that is useful for other programs - make it a separate package and they can all share it instead of installing their own (potentially out of date) versions. When a package is upgraded, the full package will get downloaded. If you break things up, users won't have to re-download the whole lot for a small change in the program code. h2. OK, so now what do I do? Let's assume you have a nice simple app !MyApp, that has files outside it. If you split your program up, you could have several !MyApp shells, each containing the parts for that package (for example tutorials might only contain !MyApp.Docs.Tutorials) The quickest way to make a package is with PackIt, a tool which can be installed with PackMan (or "install manually":https://sites.google.com/site/alansriscosstuff/risc-os-packaging ) Drag !MyApp to PackIt, and fill in the boxes. PackMan will warn you about which things remain to be fixed. Then click menu to save out the package file. (In the case PackMan gives spurious warnings - eg about an empty Copyright window that isn't - you can still save out the package anyway, or load an existing package to modify it) h2. What do all the options mean? PackIt has help which explains the options. If you really need to read the gory details, see the "RiscPkg policy manual":http://www.riscos.info/~abuckley/policy.html There's also a "Drobe article":https://web.archive.org/web/20120718194156/www.drobe.co.uk/riscos/artifact1279.html on the subject (aimed at packaging by hand rather than a tool like PackIt). h3. Version numbering Any time PackMan finds a package with a version number higher than the one already on your system, it will attempt to upgrade it. An upgrade may not be because the program itself changed - something may have changed in the other files or the way the program is packaged. To mark this as an upgrade, package version numbers have two or more components. For example, version 3.4.1tiny-9 has a suffix -9 which indicates that this is the ninth package of program version 3.4.1tiny. *Important.* Any time you update a package, you must increase the package version number. If you don't, users who try and install the old version will get an error message due to a mismatch between old and new. h3. Common errors * Having a package name with characters other than ASCII letters, numbers and plus/minus. Packages are stored on both RISC OS and Unix - if the filenames aren't usable on both systems (with the usual dot/slash swapping) then they might not be found. Top bit set characters in particular will cause problems as the servers use UTF-8. * Putting a Licence of Free when your software isn't open source (RiscPkg's policy says that Free means it abides by a licence approved by the Open Source Initiative, and anything else is Non-Free) * Not stating in the Copyright section any conditions on copying, modification and use. If your program uses a standard licence like GPL, it's sufficient to say that and include copyright messages for the authors and other boilerplate - don't put the entire GPL in here (it's in the Common-Licences package). Every licence must allow people to distribute the package - if it doesn't, nobody can host it! * Not making your software [[ARMv7 compatibility primer|ARMv7 compatible]] (necessary for BeagleBoard, Pandaboard, and Raspberry Pi 2 and later). Raspberry Pi 1 ships in ARMv5 compatibility mode which will run programs that won't run on ARMv7. To test it on a Raspberry Pi 1, go into Configure -> CPU settings and choose ARMv7 Strict mode. h2. More complicated packaging You may have to create a package yourself, or modify the output of PackIt in some way. See below and the above links for more detail on how to do this. h3. How to package modules Modules for !System go in a directory in top level of the Zip called (annoyingly) System, in the same structure as !System (eg System.310.Modules.Network...) h3. How to package !Boot components !Boot components are divided by their function. For example, files to go in !Boot.Resources live in a directory 'Resources' in the zip. Similarly for RO500Hook, Library and Utils (which goes into !Boot.Utils). PackMan does not support installing things into Choices. This is deliberate, because user settings live there - PackMan leaves Choices completely alone when upgrading software - if it didn't, it would overwrite your choices with the defaults of the new version. In addition, some versions of RISC OS support multi-user mode, where each user can have their own Choices. This means that you may have to alter programs that expect users to copy things in Choices at installation time (such as folders of settings like !ZapUser and !StrgEDcfg). The best way to do this is to copy them into <Choices$Write> the first time the app is run, and also to handle any necessary upgrading by detecting an old version is in use. h3. How to package other components PackMan also provides Manuals, Utilities and Printing which are, by default, installed into those top level directories. If you need advice on where other things should be installed , do ask for help (see below). h2. Uploading Currently, RISC OS Open have a fairly basic means of integrating your packages into the distributions. To supply your packages: # Upload them on a website and note the URL for each one. Let's say you make http://www.example.com/fred/myapp-1.0.1-1.zip and http://www.example.com/fred/myapp101-tutorial.zip # Create a pointer file, which is the URLs without the domain part (in other words, in Unix filename format). For example, the above would be a text file containing: <pre>/fred/myapp-1.0.1-1.zip /fred/myapp101-tutorial.zip</pre> also upload this to the website # Email <code>packages [at] riscosopen.org</code> with the URL of the pointer file. Packages will be checked and, once any issues with the packages are fixed, they will be downloaded on a nightly basis to the ROOL server and added to the repository. If you upgrade your packages, just update the pointer file to point to the new versions. The old versions will be automatically archived for safekeeping - you don't need to do anything. When you update a package, make sure you increase the revision number (the last digit in the package version number - eg the '3' in 0.1.2-3) so that it's clear that it has been changed. ROOL takes care of providing a stable server from which to serve the packages to users, so it doesn't matter if something later happens to your web space (except updates will no longer happen). h2. Removing your package Should you wish to remove your package from the ROOL server, please contact us at <code>packages [at] riscosopen.org</code>. See also our "privacy policy":/content/documents/privacy for more information. h2. Questions? If you need help or someone to look over your packages, feel free to email <code>packages [at] riscosopen.org</code> or post on the ROOL forum.