How to use !nstall to distribute RISC OS software
=================================================

Introduction
____________

!nstall is a program making it easy for users to install software on RISC
OS computers. Installing software is more complicated than it used to be,
because modern programs commonly need to be supplied with system resources
to ensure they work across as many systems as possible, especially since the
release of RISC OS 5.

Conditions
----------

!nstall is released under a BSD style licence. Read the file LICENCE for full
details.

This version and documentation (c) Tony Houghton 2003.
Email: <riscos@realh.co.uk>
Check <http://www.realh.co.uk> for updates etc.

Handling installations too big for one disc
-------------------------------------------

!nstall allows products to be split across multiple discs - provided each
component archive (see below) is small enough to fit on one - but also
allows a multidisc distribution to be merged into one, simply by dragging
the contents of each disc into one location. This could be handy for some
emulators which may not have real-time floppy disc access. To make this
possible it is necessary that each disc in a set must have exactly the same
title, and !nstall be placed in the same relative location - usually the
disc's root directory. !nstall automatically mounts and dismounts discs as
necessary to avoid the system becoming confused by duplicate titles.

32-/26-bit neutrality
---------------------

!nstall's !RunImage and the tar and bunzip2 utilities it uses are compiled
in 32-bit APCS mode but linked with Justin Fletcher's StubsG. This means
they can run on 26-bit or 32-bit versions of RISC OS without it being
necessary to install the 32-bit SharedCLibrary on 26-bit versions.

Archives
________

!nstall delivers software in compressed archives, unpacking them as they're
installed. The format of the archives is Unix tar (with RISC OS filetype
extensions) compressed with bzip2, achieving some of the best possible
compression ratios while being easily read on many platforms.

Reading
-------

To read an archive in RISC OS first decompress it with bunzip2, supplied in
!nstall.Scripts. It is easier if you copy bunzip2 (and tar) to your
Library, rename the archive with a /bz2 extension, and set the working
directory to the one containing the archive. For example:

Rename System System/bz2
bunzip2 System/bz2

This will create a decompressed tar archive called System. Its contents can
be listed or extracted with the tar program also supplied in
!nstall.Scripts, or you may use SparkFS. To list contents with tar:

tar -tvf System

Omit the v if you just want the filenames without details. To extract the
contents:

tar -xvf System

Omit the v if you don't want the filenames listed.

Creating
--------

To create archives, place the contents in the current directory, and run tar
with the -c option, for example to create an archive called Foo containing
application !App and directory Data:

tar -cvf Foo !App Data

Then you need to compress it. Remember if your filing system has a name
lenght limit to leave room for the /bz2 extension to be added. Either make a
copy of bunzip2 called bzip2 (it checks its own filename when called to
determine its default mode of operation) or force compression mode with the
-z option:

bzip2 -z Foo

This creates a compressed version called Foo/bz2 which you'll probably want
to rename back to Foo before moving it into !nstall's Items subdirectory
ready for distribution.

Multiple disc sets
__________________

The easiest way to create a distribution is to first make one master
!nstall, then split it up if it becomes too big for the intended media. The
first or only disc should contain the files shown on the left, subsequent
discs should contain those shown on the right:

!nstall                            !nstall
 |                                   |
 +- !Help                            |
 +- !Run                             +- !Run
 +- !RunImage                        |
 +- !Sprites                         +- !Sprites
 +- !Sprites22                       +- !Sprites22
 +- CheckRun                         +- CheckRun
 +- Control                          |
 +- Messages                         |
 +- Sprites                          |
 +- Sprites22                        |
 +- Templates                        |
 |                                   |
 +- Items                            +- Items
 |   |                                   |
 |   +- (archives to be installed)       +-- (more archives to be installed)
 |                                   
 +- Scripts                          
     |                              
     +- bunzip2                    
     +- tar                        
     +- (other scripts as necessary)

What each file is for
_____________________

Adapt !Help, !Run, !Sprites[22], CheckRun, Control, Messages and Sprites[22]
as necessary.

!Help
!Run
!RunImage
!Sprites[22]
Messages
Templates
------------

Should all be fairly obvious. Check !Help, Messages and Templates have
appropriate instructions, strings and window titles etc for your
application. !Run can set variables helping to tailor the install for the
target machine, see the discussion below.

Changing the application name
-----------------------------

You can even change the application name from !nstall if you want, but
don't forget to change !Sprites[22] as well. The names of the variables
nstall$Dir and nstall$Parameter* may not be changed.

CheckRun
--------

Checks whether !RunImage is present and runs if it is, otherwise tells the
user to run the first disc. You may want to alter it to change the
message.

Control
-------

The crucial file that tells !nstall what to install and how and where. The
example is heavily commented and will be discussed below. The underlying
format is that used by MessageTrans. The main concept is that there are a
number of target locations which the user may be prompted for, and each
archive is installed in or relative to one of these locations. One location
is the master location used to hold temporary files used in the
installation.

Sprites and Sprites22
---------------------

Should contain icons belonging to the items being installed, so !nstall can
look pretty while installing them before the sprites are made available in
the Wimp sprite pool.

Scripts
-------

Contains the crucial tar and bunzip2 programs as well as any scripts you
provide to help with the installation. This directory is copied to the
master target installation location first to make sure its contents are
still available after disc swaps and so that they will probably load more
quickly. When installation is complete the copy is deleted.

The creation of the Scripts temporary directory may cause problems if the
completed package contains a directory called Scripts. The proper way round
this would be to improve the program so alternative names can be used, but
workarounds are possible with creative juggling of locations (see below for
an explanation of locations).

A worked example
________________

The easiest way to explain it all is with a worked example. I'll use
ArtToSpr, because that needs Artworks resources (!AWViewer) which
illustrates some important features in the installer. Although everything
necessary should fit on one floppy disc, we'll pretend it needs to go on two
discs for the sake of example, and also pretend that installation of
ArtToSpr itself is optional - leaving only the resources needed to run it,
which wouldn't actually make much sense in real life.

Download and archive the resources
----------------------------------

If you want to work through the example download ArtToSpr from
<http://www.realh.co.uk/free.html#arttospr> and follow the link there to
download AWViewer as well. Download both versions, one for RISC OS 3.1 and
one for RISC OS 3.5 and later. You should find an archive called TBox/zip at
<http://www.iyonix.com/32bit/system.shtml>. This archive contains a version
of !System that will work on just about any version of RISC OS. If you
wanted to be clever, you could also download System/zip and choose which to
install on the target system using techniques in the !Run and Control files
similar to the ones described below.

Make an archive of !ArtToSpr called ArtToSpr, using the instructions above.
It's up to you what you do with the ConfigEg and ChangeLog files. Make
archives of both versions of !AWViewer, including only the application in
each, called AWView310 and AWView350 respectively. Keep the !SysMerge file
from TBox/zip, we'll be using a modified copy later. Archive just !System in
an archive called System.

Make two copies of !nstall, one a master copy, and one a subsequent disc
copy, as detailed above. Put the System archive in the Items subdirectory of
the first, with the BootPatch archive, and both AWViews and ArtToSpr in the
second. If you don't wat to go the whole hog and test with floppies, just
make one copy of !nstall and put all the archives in the one Items
subdirectory.

!Run
----

The technical stuff starts before the Control file:- some variables need to
be set in !Run.

Lines 8 and 9 load the CallASWI module for RISC OS versions earlier than 3.7.
It's supplied and loaded from <nstall$Dir> in case !System isn't already
installed, but this is very unlikely.

Lines 13 and 14 set a variable if the system is 32-bit ie RISC OS 5 or later.
This is not used in the example, but may be useful if part of the
installation should only be carried out on one type of "bitness" or the
other. If so you may need a complementary variable, nstall$26bit.

Lines 16 and 17 set nstall$Parameter0 to 310 for RISC OS 3.1 and 350 for
later OS versions. This is used to decide which version of AWViewer to
install. In an ideal world one copy would work on all OS versions, in case
of installing on a file server, and I believe Martin Wuerthner is
considering ways to deal with this.

Since the release of StubsG some people feel it's better to link your code
with it so that it can run on RISC OS 3, 4 or 5 with the native
SharedCLibrary. However, because some people disagree, and for the sake of
completeness, this example shows how to install a !System including a SCL
upgrade. The upgrade requires a patch to be applied to Select versions 4.29
through 4.31, so lines 19-21 in !Run check whether this is needed. Castle
don't seem to provide this patch any more, but you may not want to have to
insist that telling users of your installer upgrade Select, so I've provided
an archive called BootPatch.

It's remotely possible, albeit very unlikely, that the target system will
have no !System installed, so the installer needs to choose between
upgrading an existing !System and installing one for the first time. Lines
23 and 24 of !Run set a variable, referenced in the Control file, to help
make this choice. It's also used for RISC OS 5, which doesn't need a !System
upgrade because it already has the same versions of the modules as supplied
here.

After installing a new SharedCLibrary (part of !System) a reboot is required
to ensure its safe loading. If the SCL is not upgraded the reboot is not
necessary so lines 26 and 27 set a variable for making this choice. Again,
the name of this variable does not matter provided it matches what's
referenced in the Control file. It's a good idea to use the prefix nstall$
for all variables used here.

Scripts
-------

We need three scripts besides tar and bunzip2: one to upgrade !System, based
on Castle's !SysMerge script downloaded earlier; a generic booting script for
booting the other applications as they're installed; and one to apply the
patch to !Boot for Select. A script gets run just after the archive it
applies to has been unpacked, and is given an argument: the directory
containing the unpacked archive.

SysMerge
........

Rename the !SysMerge file that came with TBox/zip to SysMerge (ie delete the
!) and copy it into !nstall.Scripts.

I think the original version of this may be bugged, because it contains the
line:

RMEnsure Installer 0.07 RMLoad <Obey$Dir>.!System.310.Modules.Installer

However, !System contains two versions of the module, one in the 310
directory and one in the 360 directory, so I figure there must be a good
reason why OS 3.6 and newer require a newer version, so the SysMerge script
should take this into account. For this reason I suggest modifying the above
line to:

Set nstall$ModVer 360
RMEnsure UtilityModule 3.60 Set nstall$ModVer 310
RMEnsure Installer 0.07 RMLoad <Obey$Dir>.!System.<nstall$ModVer>.Modules.Installer

Note that it still relies on the !System about to be installed being
temporarily installed in the Scripts directory. The installer can be told to
do this with the Control file, see later.

When the script has completed it should delete the temporary !System, so add
this line to the end of it:

Wipe <Obey$Dir>.!System ~CFR~V

Boot
....

This is a generic script to boot each of the other applications as they're
installed. It needs to know the application name as well as the directory
installed in, so we can force an extra argument to be inserted before the
directory name by putting "Boot Appname" in the Control file instead of just
"Boot". Create an Obey file called !nstall.Scripts.Boot containing this one
line:

/%1.%0.!Boot

Control
-------

The supplied Control file is already set up for this example, so just follow
it through, reading the comments in conjunction with this file.

Locations
.........

Three locations are defined:

0 : Where !System will be installed if it isn't already
1 : Where !AWviewer will be installed
2 : Where !ArtToSpr will be installed

We don't want to use location 0 if !System is already installed, so we get
LocationExcludeIf0 to check System$Dir. If System$Dir is set, ie !System is
already installed, this location is skipped.

AWViewer may already be installed, but even if it is we still want to
install our copy in case it's newer. If our version is older it doesn't
matter, the install process doesn't overwrite newer files with older ones.
LocationPath1 contains a pathname based on one of AWViewer's variables. If
this variable exists the path will be expanded and shown to the user who has
the choice of clicking Next or changing the Path. If the value of
LocationPathN doesn't expand to a valid path, or we haven't used the
LocationPathN key, as is the case for the other locations, the leafname
defined by LocationLeafN is used instead, and the Next button is greyed out
until the user enters a full path by dragging or typing.

Note that it is assumed that each location is a directory (created
automatically) that will contain a number of items eg the user may enter a
location of ADFS::4.$.Package, and the contents of archives App1 and App2
etc will be installed there, creating ADFS::4.$.Package.!App1,
ADFS::4.$.Package.!App2 etc. This isn't always appropriate, mainly when a
location only contains one item, as is the case for each of the items
installed in this example. If the user enters ADFS::4.$.!ArtToSpr as a
location, the default behaviour would be to install the application as
ADFS::4.$.!ArtToSpr.!ArtToSpr. To correct this, we use an ItemLeafN value of
".^" to cancel out the redundant extra .!ArtToSpr.

Items
.....

Item 0 is the !Boot patch for Select, using ItemExcludeIf0 to skip it if !Run
sets the variable indicating it isn't needed. It will be extracted into the
Scripts temporary directory, as instructed by ItemLeaf0, and applied to the
real !Boot with the BootPatch script, according to ItemScript0.

Items 1 and 2 have a peculiarity: they're both based on the archive System,
but having different locations etc. The reason for this is because of the two
different courses of action depending on whether !System is already
installed. Item 1 is for when it isn't installed, item 2 is for when it just
needs upgrading. ItemLeaf1 is set to ".^" as explained in the previous but
one paragraph, and ItemLeaf2 is set to ".Scripts" to install the temporary
copy in the same directory as the SysMerge script.

Item 3 is AWView%0. The %0 will be replaced with the value of
nstall$Parameter0 (see the comment at the top of the file) which we defined
in !Run, ensuring the correct version of !AWViewer is installed.

Item 4 is ArtToSpr itself. If this were all going to be used in the real
world, installation of ArtToSpr itself would not of course be optional, but
to illustrate another featue I've used ItemOptional4 and ItemOptional4Desc to
make it optional. Whenever there are optional items, an extra stage appears
in the installer, allowing users to tick the optional items they want to
install. If there are many of these you may need to resize the window with a
template editor.
