This is the Policy Manual for the RISC OS Packaging Project. It defines the standards which packages are normally expected to meet if they are to be accepted as part of the project. These include:
Rules can be broken where there is good reason to do so, however a consensus must be reached beforehand if other parts of the project are affected.
These rules do not apply to packages distributed independently of the project.
The aims of the project are:
Extended Backus-Naur Form (EBNF) is used to specify the syntax of data structures. A formal description may be found in ISO/IEC 14977. Briefly:
','
) indicates concatenation;'|'
) indicates a choice of alternatives;'*'
) indicates an item repeated a specific
number of times;'['
and ']'
) enclose an
optional sequence.'{'
and '}'
) enclose a sequence
repeated zero or more times.'('
and ')'
) group items together.
';'
) indicates the end of a production.The meta-identifer ws
indicates whitespace:
ws = ws-character, {ws-character}; ws-character = space-character | newline-character;
A binary package consists of a zip file containing some or all of the following files and directories:
RiscPkg |
Required | A directory which contains information about the package. |
RiscPkg.Control |
Required | The package control file, containing information about the package and its relationship to other packages. |
RiscPkg.Copyright |
Required | A text file which states where the package was obtained from, who owns the copyright, and how it is licenced. |
RiscPkg.CrossPaths |
Optional | A file containing a list of translation rules which identify files to be made available to the cross compiler and specify where they are to be installed. |
RiscPkg.Triggers |
Optional | A directory containing files to be run during the install, remove or upgrade of a package. | Apps |
Optional | The root of the hierarchy within which applications are stored.
A package in a given section normally uses a subdirectory of
Apps named after that section. |
Manuals |
Optional | The root of the heirarchy within which manuals and other documentation are stored when no other location (such as an application directory) is more appropriate. |
Resources |
Optional | A directory which corresponds to the active Resources
directory. |
Sprites |
Optional | A directory which contains sprite declarations. This has been deprecated from version 0.4.0. |
SysVars |
Optional | A directory which contains system variable definitions. This has been deprecated from version 0.4.0. |
System |
Optional | A directory which corresponds to the active !System
directory. |
ToBeLoaded |
Optional | A directory which corresponds to a location on the Boot$ToBeLoaded path
(or Boot$Default$ToBeLoaded path on RISC OS 6). |
ToBeTasks |
Optional | A directory which corresponds to a location on the Boot$ToBeTasks path
(or Boot$Default$ToBeTasks path on RISC OS 6) |
Boot |
Optional | A directory which corresponds to the !Boot directory.
It is recommended that this directory is used for OS updates only. |
Bootloader |
Optional | A directory which corresponds to the SD card system image for the
Raspberry Pi (!Boot.Loader ). This is for system updates
provided by RISC OS Open only. |
Diversions |
Optional | A directory that corresponds to the Diversons directory.
This is used for Diversions installed with the RISC OS HardDisc image.
Apps.Games should be used in preference where possible. |
Documents |
Optional | A directory that corresponds to the Documents directory.
This has been added for documents installed with the RISC OS HardDisc image.
It is suggested that this is used for non-technical documentation and examples
files and Manuals is used for more technical documentation.
|
Printing |
Optional | A directory which corresponds to the Printing directory.
This is usually used for installation of components for the RISC OS
printing system. |
Utilities |
Optional | A directory which corresponds to the Utilities directory.
This is used for utilities installed with the RISC OS HardDisc image.
Apps.Utilities should be used in preference where possible. |
!Boot |
Optional | An alias for the Boot path above. |
!System |
Optional | An alias for the System path above. |
Each file has an associated logical path (its location within the package file) and a physical path (its location when installed). Only the logical path is specified within the package file. The package manager (on behalf of the user) is responsible for translating logical paths into physical paths, and it has considerable freedom as to how it does this. The only rule is that the translation must be reasonable. For example:
System$Path
.!Run
file to be separated from
the application directory to which it belongs.Packages are expected to cope with reasonable translations, and should not make unnecessary assumptions about where their files have been placed.
(For simple desktop applications, the usual practice of defining a system
variable of the form App$Dir
then accessing files with respect
to that variable is sufficient to meet this requirement.)
A source package consists of a zip file which includes the following files:
RiscPkg |
Required | A directory which contains information about the package. |
RiscPkg.Control |
Required | The package control file, containing basic information about the package and its relationship to other packages. |
RiscPkg.Copyright |
Required | A text file which details where the package was obtained from, who owns the copyright, and how it is licenced. |
RiscPkg.Rules |
Required | The top-level makefile for building the binary package(s). |
Although the RiscPkg.Rules
file is stated to be required,
it is currently permissible to omit this file if the source package exists
only to comply with licensing requirements and is not intended to be
automatically buildable. However inclusion of a Rules
file
is recommended, even if its only purpose is to take a set of pre-compiled
binaries and place them in a package file.
A control record is a structure used to record information about a package for use by the package manager. There are two types of control record (source and binary) and two types of file in which they can appear (package control files and package index files):
File | Content |
---|---|
Binary control file | One binary control record |
Source control file | One source control record; one binary control record for each resulting binary package |
Binary index file | One binary control record for each binary package |
Source index file | One source control record for each source package |
Package index files list all of the packages that make up a particular distribution, and are the only information available to the package manager (or the user) when deciding which packages to download. Package control files are located within the packages to which they refer, so are only available once those packages have been downloaded. Unlike index file records they are guaranteed to exist whether or not the package is part of a distribution and whether or not it has been superceded by a new version.
Each control record consists of a sequence of control fields:
control-record = control-field, {control-field};
and each field consists of a name and a value, optionally followed by a number of continuation lines:
control-field = control-field-name, ':', space-character, control-field-value, newline, {continuation-line};
For example:
Package: RiscPkg Priority: Required Section: Admin Version: 0.2.0
The fields that are allowed or required in a given control record depend on whether it is a source or binary control record, and whether it is located in a control file or an index file:
Name | Source | Binary | Index only | Description |
---|---|---|---|---|
Source | Required | Optional | No | The name of the source package |
Package | — | Required | No | The name of the binary package |
Section | Required | Required | No | A label for classifying packages by purpose |
Priority | Required | Required | No | A label for classifying packages by importance |
Licence | Required | Required | No | The type of licence carried by the package |
Maintainer | Required | Required | No | The name and e-mail address of the maintainer |
Autobuild | Optional | — | No | The platform or platforms on which this package can be built automatically |
Standards-Version | Required | Required | No | The version of this policy manual to which the package conforms |
Version | Required | Required | No | The version number |
Size | Optional | Optional | Yes | The size of the package file |
MD5Sum | Optional | Optional | Yes | The MD5sum of the package file |
URL | Optional | Optional | Yes | A URL from which the package may be downloaded |
Build-Depends | Optional | — | No | Packages which must be present for this one to be built |
Depends | — | Optional | No | Packages which must be present for this one to be installed |
Recommends | — | Optional | No | Packages which would normally be wanted when this one is installed |
Suggests | — | Optional | No | Packages which might be wanted because this one is installed |
Conflicts | — | Optional | No | Packages which should not be installed when this one is installed |
Description | Required | Required | No | A brief description and a long description of this package |
Homepage | Optional | Optional | No | A URL to a webpage were more information on this package |
Components | — | Optional | No | A list of logical paths to components that may want to be moved or added to the boot options |
Environment | — | Required | No | The RISC OS environment this package will run on |
OSDepends | — | Optional | No | The RISC OS modules this package requires |
InstallPriority | — | Optional | No | The install priority for an environment specific version of the package |
Field names are not case-sensitive, however they should normally be capitalised as in the table above. They must begin at the start of a line and be followed by a colon and a space.
The end of a control record is indicated either by a blank line or by the end of the file.
Values which span several lines are written using continuation lines. These begin with a space (which is automatically removed by the parser). If a blank line is required as part of the value, it is written as a space followed by a period (also removed by the parser):
continuation-line = space, (control-field-value | '.'), newline;
(The space serves to distinguish a continuation line from the start of a new field. The dot serves to distinguish an otherwise empty continuation line from the end of the control record.)
For example:
Package: RiscPkg Priority: Required Section: Admin Version: 0.2.0 Description: A package manager for RISC OS The three main functions of RiscPkg are: - to download and install new software packages on request; - to update installed software packages when new versions are release; and - to remove software packages when they are no longer needed. . If one package requires another in order to run, a request to install the first will also install the second. If a package has been installed automatically but is no longer needed, it is removed.
This indicates the purpose of the package. It contains one of the following section names:
Section | Content |
---|---|
Administration | System administration tools |
Archive | Programs for archiving or compressing data |
Audio | Programs which operate on sound recordings or music scores |
Chat | Programs for chat or instant messaging (including protocols such as IRC and ICQ) |
Communication | Communication programs (excluding those which relate to networks) |
Database | Databases (both general-purpose and application-specific) |
Demo | Demonstration programs |
Desktop | Programs which relate to the mechanics of the desktop |
Development | Software development tools (including compilers and interpreters but excluding libraries) |
Device | Device drivers and control software |
Disc | Programs which operate on discs or filing systems |
Document | Programs for creating, editing and processing documents (including wordprocessors and desktop publishing programs) |
File | Programs which operate on individual files or groups of files |
Education | Educational programs |
Emulation | Emulators for other machines or operating systems |
Font | Fonts and programs which operate on fonts |
Games | Computer games |
Graphics | Programs which operate on still images (vector or bitmap) |
Library | Libraries (for any programming language) |
Programs which process electronic mail or news messages | |
Mathematics | Mathematical programs (excluding educational ones) |
Miscellaneous | Packages which do not readily fit into any other section |
Network | Programs for managing or using computer networks (including both Internet and non-Internet protocols) |
Presentation | Programs for editing and viewing presentations |
Printing | Packages which are part of or relate to the printing system |
Spreadsheet | Programs which operate on spreadsheets |
System | Packages which are part of or relate to the core operating system |
Text | Programs which operate on text files (including plain text and generic structured formats such as CSV and XML) |
Video | Programs which operate on moving images (vector or bitmap, with or without sound) |
Web | Programs which operate on HTML and related data types (including XHTML but excluding generic XML) |
Where reference is made to programs this should be taken to include files of any type which would be used in conjunction with such programs. A more specific section (such as Mail) should normally take precedence over a less specific one (such as Communication).
It is likely that additional sections will be defined in the future. The 'Misc' section is available for packages which would otherwise be difficult to classify. A package may move from one section to another whenever its version number changes.
This indicates how likely it is that a typical user will want the package if they have not explicitly asked for it. It contains one of the following priority levels:
Priority | Meaning |
---|---|
Required | Packages which are needed for the system (including the package manager) to function correctly. (Example: RiscPkg.) |
Important | Packages which a user could reasonably expect to be present on any RISC OS system. (Example: SysLog.) |
Standard | Default packages for a typical user. These should provide a reasonably small but not too limited RISC OS system. Users will normally need to add to this selection to meet their specific requirements, but should find that many of the smaller and more generic applications they want are already present. (Example: Nettle.) |
Optional | Default packages for a user who wants to install almost everything, without regard for disc space or installation time. (Example: GCC.) |
Extra | Packages which have a very narrow audience, or which conflict with other packages of higher priority. (Example: LibPkg.) |
Packages are assumed to be optional unless there is a specific reason why they should have a higher or lower priority. A consensus should be reached before choosing a priority higher than optional unless there are clear technical reasons why that priority is necessary or appropriate.
A package declared as a dependency must be of equal or higher priority to the package declaring the dependency.
This provides information about how the package is licenced. It consists of a comma-separated list of licence tags.
licence = licence-tag, {',', licence-tag};
Tag | Definition |
---|---|
Free | Packages that meet the Open Source Definition, as defined by the Open Source Institute |
Non-free | Packages that do not meet the Open Source Definition |
Additional licence tags may be defined in the future. Unrecognised tags should be ignored. The tag list must be complete with respect to the declared standards-version; however, the fact that a tag is absent should not be taken to imply that the converse is true.
If a package has several components with different licences, the most restrictive combination of terms is applicable. If a package offers a choice of licence, the least restrictive option applies. If there is significant doubt as to which tags apply, the more restrictive interpretation of the licence must be followed.
Since only two tags are available at present and they are exact opposites, it follows that packages working to this version of policy must specify exactly one licence tag.
This identifies the package maintainer responsible for the package at the time it was issued.
maintainer = real-name, '<', email-address, '>';
This is a comma-separated list of platforms which are, or should be, able to autobuild this package:
autobuild-list = autobuilt-platform, { [ws], ',', [ws], autobuild-platform }; autobuild-platform = 'RISCOS' | 'POSIX';
The characteristics of these platforms are described below as part of the build environment.
The list of platforms is nominally considered to be in order of preference, however this order may and probably will be overridden by the autobuilder software to take account of efficiency and availability. If there is a clear technical reason (other than speed of compilation) why the package should be built on one platform rather than another then you should omit the platforms you wish to avoid.
If the autobuild field is omitted then this currently indicates that the package is not suitable for autobuilding on any platform.
This identifies the most recent version of the policy manual to which the package is thought to comply. There are four numeric components to this version, representing (from left to right):
Because the fourth component does not indicate substantive change, it is sufficient to specify the first three components in the standards-version field.
For example, if the latest version of the policy manual is '0.1.2.3' and a package complies with that version, the standards-version field of the package should be set to '0.1.2'.
Intentional non-compliance may be disregarded provided it does not affect how the package manager should process the package.
This contains the package version. It must increase (with respect to the sort order defined below) whenever the content of a package is upgraded, otherwise that upgrade will not be offered to the user.
Versions are discussed in detail in a separate section below.
This contains the size of the package file, expressed as a decimal number of bytes.
size = digit, {digit};
This contains the MD5 message digest of the package file, expressed as a hexadecimal number.
md5sum = 32 * hex-digit;
This contains an absolute or relative URL from which this package can downloaded. If the URL is relative then it is resolved with respect to the package index file in which it was specified.
This contains a comma-separated list of other packages which must be installed for this one to function:
depends-list = [ dependency, { [ws], ',', [ws], dependency } ];
Each dependency consists of a package name followed by an optional version predicate:
dependency = package-name, [ws, version-predicate];
The version predicate, if present, specifies which versions of the package are capable of specifying the dependency:
version-predicate = '(', [ws], version-relation, [ws], version, [ws], ')'; version-relation = '=' | '<<' | '>>' | '<=' | '>=';
For example:
Depends: LibPkg, RTK (>=0.5.0), ZLib
would cause installation of any version of LibPkg, version 0.5.0 or later of the RTK, and any version of ZLib.
Note the double '<' or '>' for strictly less-than or greater-than (which are required for historical reasons).
Small reductions in functionality are not significant: the dependency must be strong enough that the package is of little use without it. For example:
However:
This contains a comma-separated list of packages which are usually installed alongside this one but are not strictly essential:
recommends-list = [ dependency, { [ws], ',', [ws], dependency } ];
For example:
This contains a comma-separated list of packages which the user should consider installing alongside this one but could very reasonably decide not to:
suggests-list = [ dependency, { [ws], ',', [ws], dependency } ];
For example:
This contains a comma-separated list of packages which cannot be installed at the same time as this one:
conflicts-list = [ dependency, { [ws], ',', [ws], dependency } ];
In most cases this will be because the packages install a file in the same place. For example:
However:
Do not declare a conflict without first investigating whether it can be avoided.
This field contains a brief description and a long description of the contents of the package.
The first line of the description is the short description and should be relatively short so that it can be used as a summary line in package lists.
For example:
Description: A package manager for RISC OS The three main functions of RiscPkg are: - to download and install new software packages on request; - to update installed software packages when new versions are release; and - to remove software packages when they are no longer needed. . If one package requires another in order to run, a request to install the first will also install the second. If a package has been installed automatically but is no longer needed, it is removed.
This field contains a URL to a web page where more information about the package can be seen.
The URL must start with the protocol "http" or "https".
For example:
Homepage: http://awebpage.com/agreatapp
This contains a comma-separated list of the components that have extra configuration options:
components-list = [ component-details, { [ws], ',', [ws], component-details } ]
The component-details consists of the the component logical file/folder name and its options:
component-details = file-name, [ws], component_options ; component-options = '(', { [ws], component_option {[ws] ' ' component-option }, [ws], ')' component-option = 'Movable' , 'LookAt', 'Run', 'AddToApps';
The options are all defaults that the user may override when they install the package.
For example:
Components: Apps.Development.!PackIt (Movable LookAt)
Packages with the Standards-Version set to 0.4.0 or later will assume that if the Components field is NOT set there are no movable components in the Package
It is expected the use of the Components field replaces the SysVars and Sprites package control folders. If the package requires system variables and sprites to be loaded you would normally specify the LookAt option so the application is booted when the desktop is started. It is suggested that if the component isn't providing command line utilities or support for a file type that SysVars and Sprites are just removed and the LookAt option is not set.
This contains a comma-separated list of the environment codes that specify the features required by for this package to run on a RISC OS/hardware combination:
environment-list = [ environment-code, { [ws], ',', [ws], environment-code } ]
The environment-code is from the following table:
Code | Description |
---|---|
any | Should run on any system. e.g. BASIC programs that don't use assembler or OS specific features, documents. |
arm1 | 26/32 bit neutral code. Assembler (or C/C++ or other compiled languages) applications that will run on anything from the Risc PC with RISC OS 4 to the latest machines capable of running RISC OS. The code will adjust itself to work on either a machine with a 26 bit or 32 bit address bus. |
arm26 | 26 bit code. Assembler or compiled code that uses instructions only available on 26 bit machines. |
arm32 | 32 bit code. Assembler or compiled code that uses instructions only available on 32 bit machines. |
vfp2 | Application that require the Vector floating point unit |
swp3 | Application that require the ARM SWP/SWPB instruction to be available |
Notes:
The same package can be released with different environment codes to provide optimized versions for different environments.
Packaging front ends are expected to filter the packages shown to present the best for the environment it is run upon and omit packages that will not run upon the current environment.
The OSDepends field (below) is used in conjunction with this field to add further specialisation of the RISC OS version used.
Unless using machine specific features, it is best to try to create programs for the "arm" or "all" environments to allow the maximum number of people to use the package.
This contains a comma-separated list of the modules that this should be loaded at RISC OS startup that are needed for this package.
This should only be for modules that are loaded by RISC OS at startup. If it is a third party module, the module should be packaged and a normal dependency used to ensure the module is installed and available
osmodule-list = [ osmodule, { [ws], ',', [ws], osmodule } ]
The osmodule is the name of the module. This is the name shown when using the *modules commands.
This contains a number from 0 upwards that specifies which package should be chosen if the same package exists for multiple environments/OSDepends combinations. If omitted or 0 the default priority for the environment modified by the number of OSDepends modules is used.
The default install priority order from highest to lowest is: vfp, swp, arm, arm26, any. If any OSDepends modules are specified they are a higher priority than any environment settings.
Every package shall contain a text file named Copyright
in its RiscPkg
directory. No specific structure is required,
but it must contain the following information:
(Note that without a distribution licence it is highly unlikely that a package can be distributed.)
A package can optionally contain runnable files in the Triggers
directory in its RiscPkg
directory that will be run as part of the
commit (installation, removal or upgrade) of a package.
Triggers should be used only when necessary and should be avoided in most cases as:
The following names are used by code in the Triggers directory.
File | Description |
---|---|
PreInstall | Run before a package is installed. |
PreRemove | Run before a package is removed. |
PostInstall | Run After a package has been installed. |
PostRemove | Run After a package has been removed. |
Other code can be added to the Triggers directory and this will be available when the triggers are run. This allows for triggers to use shared code etc.
The code can be any executable code and is run in a background TaskWindow with a WimpSlot of 256K. If logging is turned on, any output from the trigger is added to the Log.
A triggers operation should not rely on any other trigger having been run and it should allow for cases where it may be called multiple times.
Information is passed to and from a Trigger using system variables prefixed
PkgTrigger$
.
At the minimum a trigger must set PkgTrigger$ReturnCode
to 0
if a trigger succeeds or to 1 if it fails.
On failure PkgTrigger$ReturnText
can be set to give the error
message, which may then be logged/reported by the package manager.
The full set of variables are:
Variable | Description |
---|---|
PkgTrigger$Action |
The current action, see below: |
PkgTrigger$Abort |
0 or 1. If set to 1 this trigger is being run to unwind a previous trigger failure. |
PkgTrigger$OldVersion |
The version of the package being removed or "" if it's an install. |
PkgTrigger$NewVersion |
The version of the package being installed or "" if it's being removed. |
PkgTrigger$Dir |
The directory the trigger is being run from. Use this as a prefix if running other code in the Triggers directory. |
PkgTrigger$ReturnCode |
The return code from the trigger, should be set to 0 for success or 1 for failure. |
PkgTrigger$ReturnText |
Set to a brief error message it the trigger fails. |
PkgTrigger$Path<n> |
<n> is a number from 1 upwards. These variables contain the path to the components in the package. |
PkgTrigger$S_* |
Variables prefixed PkgTrigger$S_ are shared variables that exist
for the lifetime of the current package commit and are deleted after the commit
has finished. They are used so state can be shared between triggers. It is
advisable to use the package name in the variable name to avoid clashes with
triggers from other packages. |
The PkgTrigger$Action can be:
Action | Description |
---|---|
install | The package is being installed. |
remove | The package is being removed. |
upgrade | The package is being upgraded. |
abort-remove | The trigger is being run as a remove failed. |
abort-install | The trigger is being run as an install failed. |
abort-upgrade | The trigger is being run as an upgrade failed. |
The triggers are called in the following order for an install.
The triggers are called in the following order for a remove.
The triggers are called in the following order for an upgrade
If new-PreInstall fails
If old-PostRemove fails and is not part of an abort the upgrade completes, but a warning is shown.
If new-PostInstall fails and is not part of an abort the upgrade completes, but a warning is shown.
Every source package should contain a makefile called
RiscPkg.Rules
containing instructions for building the
corresponding binary package(s). These should be placed in the
RiscPkg
directory and have names of the form:
binary-leafname = binary-package-name, '_', version-number;
for example LibPkg-Dev_0/2/1
(on a RISC OS machine)
or LibPkg-Dev_0.2.1
(on a POSIX machine).
All binary packages are to be built when the makefile is invoked with no target or with the target 'all'. (Typically this would be achieved by making 'all' the default target.)
The Rules
file should assume that the current working
directory is at the root of an unpacked copy of the source package.
Typically the command that invokes it will be of the form:
make -C <source-package-root> -f RiscPkg/Rules
It may also assume that it has ownership of all files and directories at or below this root, and that any file permissions are no more restrictive than the following:
Filesystem | File permissions | Directory permission |
---|---|---|
AFS | rlidwk | rlidwk |
RISC OS | WR/ | WR/ |
POSIX | 044 | 055 |
It is recommended that the Rules file seek to avoid altering any file that is part of the supplied source package, in order to avoid creating differences which might be inadvertently checked back in to the revision control system; however it is recognised that this may not always be practicable when packaging software that was created by a third party.
The Rules file must not attempt to read or modify any file or directory outside the root of the supplied source package, unless it is either (a) a defined part of the build environment or (b) a file made available by a build-time dependency, in which case it may read from the file but not alter it.
The package file format is primarily designed for installing software on RISC OS machines, however in some cases there is also a need to make it available to a cross-compiler running on a POSIX-based operating system. This is done by including a CrossPaths file in the RiscPkg directory of the relevant binary package.
Each line within the file consists of two pathnames separated by whitespace. The first is a logical pathname which identifies a file or set of files in the binary package which are to be copied. The second pathname specifies where those files are to be placed. It too is a logical pathname, but using a different set of conventions that are better suited to the way files are organised on a POSIX system. The following paths are defined:
include |
A location that the cross-compiler will search for header files. |
lib |
A location that the cross-compiler will search for libraries. |
Wildcard variables may be used to copy many files with a single rule. These consist of a percentage sign followed by a decimal digit, and match any sequence of zero or more characters within a single pathname component (but not sequences which span multiple components). The variable should appear in both the source or the destination path. Wildcards can be used to translate between RISC OS and POSIX-style naming conventions, for example:
Apps/Library/!LibPkg/libpkg/h/%1 include/%1.h Apps/Library/!LibPkg/a/%1 lib/%1.a
You should include a CrossPaths file within any binary package that contains files which could potentially be needed by the cross-compiler, whether or not that package is itself capable of being built using the cross-compiler.
Versions have three components:
version = [epoch, ':'], upstream-version, ['-', package-version]; epoch = {digit}; upstream-version = {letter | digit | '+' | '-' | '.' | ':' | '~'}; package-version = {letter | digit | '+' | '.' | ':' | '~'};
Only the upstream version is required. This should match the version of the upstream project if there is one. (Upstream is the source from which the software was obtained for packaging.) For example, if you are packaging the version of Nettle released as '0.2040r' by the Nettle Developers then the upstream version would be '0.2040r'.
If there is more than one level of upstream development, you should typically choose the furthest upstream version consistent with the name of the package. For example, if you are packaging version 2.95.4 release 3 of the RISC OS GCCSDK and the package is named GCC, the upstream version would be 2.95.4 and the release number would become part of the package version. However, if the package has instead been named GCCSDK then the upstream version would be 2.95.4r3.
Changes can be made to avoid illegal characters or ensure that the sort order is correct. Some common cases are described below.
The package version allowes for the possibility that a given upstream version will be packaged (or ported) more than once. Typically it should start at zero each time the upstream version changes and increment each time there is no change. A more complex scheme can be used if it is considered useful.
The epoch allows for major changes (or mistakes) in the numbering scheme which would otherwise disrupt the sort order. It should notionally begin at zero, then increment each time the upstream version needs to move backwards. While the epoch is equal to zero it should be omitted entirely.
Changes to the epoch should be rare and unplanned events. If the upstream version scheme makes epoch changes inevitable then it must be modified to prevent this happening.
The epoch is the most significant component, followed by the upstream version then the package version.
Components are compared by dividing them into an alternating sequence of numeric and non-numeric sections. The first section is defined to be non-numeric (so will be empty if the component begins with a digit).
Non-numeric sections are compared lexicographically using ASCII values, modified so that letters sort earlier than non-letters, and so that the tilde character sorts earlier than anything else (including the empty string). Numeric sections are compared numerically. If a numeric section is empty then it is taken to be equal to zero.
Sections are compared from left to right until a difference is found or until both components are exhausted.
(This sort order is intended to be the same as that specified in version 3.8.0 of the Debian Policy Manual. If any difference is found between dpkg, RiscPkg or the two policy manuals it should be reported as a bug.)
If the upstream version incorporates a date then the year must precede the month and the month must precede the day. Formats with a suitable sort order include '1999.9.27', '1999.09.27' and '19990927'.
If the upstream version contains a suffix such as '-pre2', '-test5' or '-rc12' then this may be moved out of the upstream version and appended to the package version. It will then have no effect on the sort order (because the remainder of the package version will always take precedence) while remaining visible to the end user.
If the suffix remains attached to the upstream version then it is not possible to remove the suffix when a final release is available without disrupting the sort order. This can lead the user to believe that the package is less mature than is actually the case.
Each files in a binary package must have a RISC OS extra information field.
This specifies the file type, timestamp and file attributes. It has a zip file tag of 0x4341. Most zip file compressors written for or ported to RISC OS provide this field automatically. Those intended for other operating systems more likely do not.
File attributes should be set to LR/r
for static files
and either WR/wr
or (preferably) WR/r
for
variable files. Packages should not assume that the attributes are set
to these values when the files are installed.
The purpose of this rule is not to force any particular attribute policy on the installed files, but rather to ensure that the package manager is aware of what permissions are needed for the system to function correctly. If the user wants all files to be writable then it is a straightforward matter for the package manager to force the attributes to
WR/wr
during installation, whereas it would not be able to do the opposite.It has not been decided how the package manager will distinguish between files which should disappear when a package is removed and files which should remain until it is purged, however it is possible that file attributes will be used for this purpose.
The use of System variables has been deprecated with Standards-Version 0.4.0 and above. It is recommended that the LookAt option in the Control files Components field is used to Boot an application to set any variables required.
A package may claim ownership of a system variable by including a
file named after the variable in its SysVars
subdirectory.
An escape mechanism is provided to allow for characters which have
special meanings in RISC OS pathnames. To use it, replace the
character with an equals-sign followed by a two-digit hexadecimal
character code.
The following filetypes are allowed:
Filetype | Content |
---|---|
Text | A parsed string with which to initialise the system variable. |
Data | An unparsed string with which to initialise the system variable. |
All other filetypes are reserved for future use. If a string is parsed
then this is done by OS_GSTrans
or an equivalent, with the
addition of support for logical pathname references (as described below).
Note that this mechanism does not replace the need to set system variables in !Boot
and !Run
files.
Run$Path
Packages should not change Run$Path
simply because
they provide one or more command line programs. Aliases of the form
Alias$command
should be used instead.
The
Run$Path
would soon become very long if every command line program were to extend it. This would make the system less efficient and could eventually break it.
!Boot
fileThe !Boot
file must be idempotent (meaning that the result
after executing it twice is the same as the result after executing it once.)
The actions performed by a !Boot
file should be limited
to the following:
System variables with previously set values should not be altered.
Ideally the
!Boot
file would not replace existing sprites either, but it is not obvious how this could be easily achieved.
!Run
fileIf the application needs a system variable to be set to a particular
value then the !Run
file should forcibly set that
variable to the appropriate value.
For example, most applications use a variable of the form
App$Dir
to access support files within their application directories. Ideally applications should not clash — but if they do then the correct behavior is to use the value appropriate to the application that is currently running. The variable is not intended to be user-configurable, so this action is unlikely to override a value set by the user.
If the application needs a system variable to be set to a meaningful
value, but there is more than one value to which it could usefully be set,
then the !Run
should provide a reasonable default but
should not overwrite an existing value.
This allows configuration to be performed by setting system variables at boot time, as opposed to editing the
!Run
file. The latter method is undesirable (a) because the!Run
may be shared between several users or machines, (b) because the application directory cannot be made read-only, and (c) because the system variable cannot be shared between applications.
The use of the Sprite declarations has been deprecated with Standards-Version 0.4.0 and above. It is recommended that the LookAt option in the Control files Components field is used to Boot an application to load any sprite that are required.
The package manager has the ability to load sprites into the Wimp sprite
pool at boot time. For this to happen the sprite must be declared. A
package can do this by placing a file named after the sprite in its
Sprites
directory.
At present the file must be a text file, in which case it contains the
pathname of the sprite file that contains the sprite. The pathname is parsed
using OS_GSTrans
or an equivalent, with the addition of
support for logical pathname references (as described below).
Only one sprite may be specified per declaration, however any number of declarations may refer to a single sprite file.
The sprite file identified by the pathname should be one that is
suitable for use as an argument to the IconSprites
command.
If higher-resolution versions of this file are present then they will be
recognised automatically by the package manager, provided that the
conventional suffixes are used. For example, if a package provides
sprite files called !Sprites
, !Sprites22
and
!Sprites11
then declarations should refer to the first of
these only, but one of the others will be used if it is a better match to
the screen mode.
The preferred method for distributing command line programs is to
encapsulate each one within a separate application directory, then
set an alias of the form Alias$command
to make the program
available from the command line.
The alternative of placing all command line programs in a central location would work acceptably for stand-alone executables, but provides nowhere for supporting documentation and other files to be located. Use of an application directory was thought to be more in keeping with the RISC OS tradition of keeping associated files together where possible.
Where there would be no advantage in a command having its own graphical front end, it is permissible for it to share an application directory with other programs.
At its simplest, the application directory would contain
!Boot
and !Run
files to set system variables, a
!Sprites
file to provide an icon, the executable itself, and
documentation within or referenced by a !Help
file. Other
files may be added as required.
Provision of files for use by the FrontEnd module is encouraged. Provided they are reasonably small (as is likely to be the case) they can be bundled into the same package as the executable. More elaborate graphical front ends should in most cases be packaged separately.
When specifying the content of a system variable or the location of a
sprite file it may be necessary to translate a logical pathname to a physical
pathname. This is done using an extension of the syntax implemented by
OS_GSTrans
:
logical-pathname-reference = '<', package-name, '$', '@', logical-pathname, '>';
For example, the logical path Apps.Admin.!RiscPkg
within
the package RiscPkg
would be expressed as:
<RiscPkg$@Apps.Admin.!RiscPkg>
Only pathnames can be processed in this way. If a path is required then the trailing period must be placed outside the logical path reference:
<RiscPkg$@Apps.Admin.!RiscPkg>.
A module package is a package that just contains a single RISC OS module that will be installed into the !System modules directory.
It can contain a single module in the appropriate subdirectory of !System and optionally some documentation to be installed in the root Manuals directory.
The package name should be the full name of the module (the module title) and the version must match the version number of the module followed by a dash and the package number (starting with 1).
e.g. For a module in file MyMod with a title MyModule and version 1.11, the package name should be MyModule and the version should be 1.11-1.
If the versioning rules are followed the packaging system will detect if a newer existing version of the module already exists on the machine and use that instead of the package when the module package is installed.
The build environment is the set of tools, libraries and other resources that are external but available to a source package while it is being built. There are two parts to the build environment:
The latter category is provided so that it is not necessary for large numbers of source packages to declare their need for basic facilities such as Make or GCC. Binary packages which provide such resources are described as 'build-essential&rsqup;.
Two different build platforms are defined, RISC OS and POSIX, and there are differences between them. Ideally source packages should be written so that they can be compiled on either, however it is recognised that this is impractical in many cases.
The following packages (or their equivalents) are build-essential when using RISC OS as the build platform:
Name | Version | Description |
---|---|---|
DiffUtils | 2.7 | A set of tools for comparing files |
DRLink | 0.44 | AOF linker |
FixDeps | 1.0.2 | A filter for processing makefile dependencies |
FileUtils | 4.1 | GNU file management utilities |
G++ | 3.4 | The GNU Compiler Collection (C++ compiler) |
GCC | 3.4 | The GNU Compiler Collection (C compiler) |
Ld-GCCSDK | 0.44 | A GNU-compatible front-end for Link or DRLink |
LibFile | 1.01 | ALF creation and maintenance tool |
Make | 3.80 | The GNU Project implementation of Make |
Patch | 2.5.4 | A tool for applying diff files |
Perl | 5.8.8 | The Perl programming language interpreter |
RiscPkg-GenControl | 0.0.0 | Binary control file generator for RiscPkg packages |
Sed | 4.0.9 | The GNU stream editor |
UnixLib-Dev | 4.6 | A C run-time library for RISC OS |
Unzip | 5.52 | A decompressor/dearchiver for zipfiles |
Zip | 2.3 | A compressor/archiver for creating and modifying zipfiles |
UUDecode | 4.2.1 | UU and base-64 file decoder |
UUEncode | 4.2.1 | UU and base-64 file encoder |
When using a POSIX-based system as the build platform, equivalent functionality should be provided, typically by installing GCCSDK, with the exception of FixDeps. (The functionality of FixDeps can be achieved using Sed on a POSIX-based system.)
The versions specified are the minimum allowed. Higher versions may be used provided that they are fully backwards-compatible. The method of installation for this software is unspecified: it is not necessary to use RiscPkg (although it would be sensible to do so where the build platform is RISC OS and the necessary packages are available.)
Source packages should not attempt to test whether they are being built on RISC OS or POSIX; instead, they should determine whether the build platform provides the specific feature that is required.
It is not necessary to write fully portable makefiles, as you can assume that Make will be compatible with the GNU Project version.
The following environment variables may/shall be set by the autobuilder before invoking the Rules file of a source package:
RISCPKG_BUILD_GNU_CPU_FAMILY | Required | The name used by the GNU toolchain to identify the target CPU family (currently always 'arm'). |
RISCPKG_BUILD_GNU_CPU_TYPE | Required | The name used by the GNU toolchain to identify the specific target CPU (for example 'strongarm' or 'xscale'), or undefined to indicate that the compiler defaults should be used. |
CPPFLAGS | Optional | Flags to be passed to the C preprocessor. |
CFLAGS | Optional | Flags to be passed to the C compiler. These will include instances of 'mtune' and 'mcpu' if appropriate. |
CXXFLAGS | Optional | Flags to be passed to the C++ compiler. These will include instances of 'mtune' and 'mcpu' if appropriate. |
LDFLAGS | Optional | Flags to be passed to the linker. |
If you encounter a bug in a package on which you depend, either at run-time or build-time, then you should either wait for the bug to be fixed or put in place a workaround that allows the package to be built with or without a fix. Do not install a workaround which is likely to break when the bug is corrected, as this will unnecessarily complicate the process of fixing it.
Significant aspects of this policy manual are based on the Debian Policy Manual, written by Ian Jackson and Christian Schwarz.
This manual is part of the RISC OS Packaging Project.
Copyright © 2004-2016 Graham Shaw.
Update from version 0.4.0 onwards © 2014-2020 Alan Buckley.
Distribution and use are subject to the GNU General Public License, as published by the Free Software Foundation.