Packaging Software For Nekoware
This is a draft. Do not follow it for advice
Package Format - tardist
IRIX packages are called tardists and, as the name implies, are essentially tar(1)'ed sets of distribution files. These files describe the location and permissions of all files related to a particular piece of software. These tardists can then be distributed and installed on similarly-configured SGI machines.
Tools Required
Compilers
For IRIX, the system compiler is known in 6.5 and 6.2 as MIPSPro, and earlier versions as IRIS Development Option. For SGI software, there are two viable options:
MIPSPro (c99/cc/CC): Caveats are that thread local storage is not supported, C11 and C++11 and up features are mostly absent, IRIX's CC (c++) compiler has some important limitations and that cross-compilation is not possible. GCC and MIPSPro are C-ABI compatible, but not C++. MIPSPro is fast at compilation, uses less memory, and can potentially improve performance
GCC: Caveats are that applications that use native C++ libs (libfam, libviewkit, libinst) etc. cannot be built under GCC. They won't link correctly. Link-time optimization and thread local storage do not work correctly on IRIX, SGUG RSE disables the latter and the former will break binaries. GCC has trouble linking under RSE to pthread and GL libs, and pthread libraries otherwise. GNU binutils has limitations, and most GCC will only build 32-bit apps correctly.
Platform
In order to build software for Nekoware, it's recommended to run IRIX 6.5.21 or newer, have at least 512M RAM, and an R10000 at 175MHz or an R5200 at 300MHz or greater. Nekoware does not support cross compilation, but these machines are fast enough to not require it.
Software
MIPSPro requires a license. Flexlm licenses exist for it, but it can also be patched to remove the check. GNU make 3.81 or later is also recommended, as IRIX pmake, smake and make are all unsuitable for modern software.
Build Environment
Be sure to set some global variables for development on IRIX. The following is a set of sensible starting point. setenv(1) is used on tcsh, export for KSH and GNU Bash:
setenv CC c99 setenv CXX CC setenv CFLAGS '-O2 -mips4 -TARG:proc=r10000' setenv CXXFLAGS '-O2 -mips4 -TARG:proc=r10000' setenv CPPFLAGS '-I/usr/nekoware/include -I/usr/include' setenv LDFLAGS '-L/usr/nekoware/lib32 -L/usr/lib32 -Wl,-rpath -Wl,/usr/nekoware/lib32' setenv PKG_CONFIG '/usr/nekoware/bin/pkgconf' setenv PKG_CONFIG_PATH '/usr/nekoware/lib32/pkgconfig' setenv ACLOCAL_PATH '/usr/nekoware/share/aclocal'
export CC=c99
export CXX=CC
export CFLAGS='-O2 -mips4 -TARG:proc=r10000'
export CXXFLAGS='-O2 -mips4 -TARG:proc=r10000'
export CPPFLAGS='-I/usr/nekoware/include -I/usr/include'
export LDFLAGS='-L/usr/nekoware/lib32 -L/usr/lib32 -Wl,-rpath -Wl,/usr/nekoware/lib32'
export PKG_CONFIG='/usr/nekoware/bin/pkgconf'
export PKG_CONFIG_PATH='/usr/nekoware/lib32/pkgconfig'
export ACLOCAL_PATH='/usr/nekoware/share/aclocal'
All Nekoware is installed relative to /usr/nekoware and should be built and linked against the libraries there.
Furthermore, there are some MIPSpro options that should be set:
Defining CC
and CXX
specifies the MIPSpro compiler suite. The CFLAGS
option indicates building for MIPS IV, that being any MIPS processor R5000 or newer (see above).
Also present are additional optimizations being done for the R10000 platform (more specifically the SGI Origin 200 IP27), which is a common processor among the SGI O2, SGI Octane, and SGI Origin platforms. This build will work on R5000, but will see additional optimization on R10000 or better. If the software is optimization-friendly, e.g. mplayer or blender - it is possible to provide different builds, optimized for specific processors and have inst or swmgr automatically select the best build during installation.
Alternatively, the -TARG
option could be disgarded entirely to build without any platform-specific optimizations whatsoever. Many Nekoware packages use only -03 -mips4
.
Note: A great deal of open source software expects the compiler suite to halt processing if an "#error" preprocessor directive is encountered. GCC does this, while MIPSpro does not by default. To get this behavior with MIPSpro you can add "-diag_error 1035" to the CFLAGS definition above.
Creating a Sandbox
Typically, a location under the home directory would be used for holding source tarballs, build directories and other working files. Under this directory, creating two copies of the build directory will aid the patch creation process later on. Suppose one were building fooware, version 1.2.3, within this working directory:
(prompt) gunzip -c fooware-1.2.3.tar.gz | tar xf - (prompt) cp -r fooware-1.2.3 fooware-1.2.3-PATCHED
There are now two identical versions of the source directory. By maintaining the original source and working within the "-PATCHED" directory, creating a patch for the package will be much more simple.
Building the Software
Typically, after a sandbox has been created, the software should be configured from within the "-PATCHED" directory (following the directions above). Remember, all Nekoware packages are installed relative to /usr/nekoware, so the --prefix
option should be passed to configure. libdir must be done as well, as /lib is for o32 software and /lib64 for 64-bit
% ./configure --prefix=/usr/nekoware --libdir=/usr/lib32
Be sure to specify any other configure arguments necessary to build the software. It may be necessary to write down any dependencies configure checks to create accurate rules later.
After the software has been successfully configured, compile the source as usual. As an example, something like this might be used to compile the software on a dual-processor machine:
% gmake -j3
If the software successfully compiled, it may be possible to simply run the software from within the working directory, without installing anything. If so, try that now and verify that all desired functionality is present. If not, the software should now be installed using something similar to the following:
% sudo -s % gmake install % exit
After installation, test the software as above to verify the successful build.
Installing the Software
To package, after confirming build and install correctly, reconfigure the software to install to a staging directory:
./configure --prefix=/usr/neko_staging --libdir=/usr/neko_staging/lib32
This will allow tracing by either swpkg(1) or genidb(1) to be useful.
Package Preparation
Directory Structure
Nekoware packages use a consistent directory structure for patches, sources, release notes and distribution files. Create this structure under the /tmp/build directory (created above), now:
% mkdir /usr/neko_staging/patches % mkdir /usr/neko_staging/src % mkdir /usr/neko_staging/relnotes % mkdir /usr/neko_staging/dist
Copy the original source distribution and the patch file to their respective directory:
% cp neko_fooware-1.2.3_irix.patch /usr/neko_staging/patches % cp fooware-1.2.3.tar.gz /usr/neko_staging/src
Release Notes
This section is under construction
Creating a Package
Now that the temporary directory contains the binary software, the source code, the patch and a release notes file, create a distribution directory and run Software Packager:
% mkdir /usr/neko_dist && cd /usr/neko_dist % swpkg
The Software Packager interface is designed to be intuitive. The other option will discussed soon.
Creating a Product Hierarchy using swpkg
On the first worksheet, a tree is displayed showing a default arrangement of subsystems within a package. This may, or may not, suit the software's layout, but it is provided as a starting point for creating a new package.
The first step is to give the package a name on the root node. Something like neko_fooware is recommended. Add a description to this node on the right using other packages in the Software Manager as a guide. Be sure to save any changes or they will be lost.
Create the other nodes according to the typical Nekoware hierarchy, as follows:
neko_fooware.eoe (binaries and files for execution only) neko_fooware.include (headers) neko_fooware.lib (shared libraries) neko_fooware.man.manpages (manual pages) neko_fooware.opt.src (the original source tarball, this is optional) neko_fooware.opt.patches (patches against the original source) neko_fooware.opt.relnotes (release notes for this package) neko_fooware.opt.dist (distribution files, generated by swpkg)
Not all of the tree may be required by the software. Use common sense and other Nekoware package as a guide.
Versioning
Every package will have two version numbers that should never be confused: the package version and the software version.
The package version is assigned to all children of the root node on the first worksheet of the Software Packager. This number is incremented for each build of this package independently of the software version contained within the package.
For Nekoware, start a package version at 100. This is because historical nekoware may conflict, which can break things.
Remember: a package's version is independent of the version of the software it contains.
Also, all package version numbers must be equal within a package. If, for example, the execution-only subsystem has changed in a new package, all other subsystem's must have the version numbers incremented, as well. This holds true even if no other subsystems have changed between package versions.
Dependencies
This is, perhaps, the most important portion of the packaging process and is the reason for recording the software's dependencies during the build stage above. Find the package version of each dependency using the versions(1) command. For example:
(prompt) versions -n neko_foo (prompt) versions -n neko_bar (prompt) versions -n neko_baz
Each versions(1) command will output several lines, one for each subsystem in the package. Write down the version numbers for each subsystem the software depends on. Be sure to be specific: which subsystem does the software depend on? Just the shared libraries, or the execution environment? Both?
Now, in Software Packager, specify the dependencies for each subsystem in the Rules section. The rules will look somewhat like the following:
replaces self prereq ( neko_fooware.lib 100 maxint neko_foo.lib 100 maxint neko_bar.eoe 100 maxint neko_baz.include 100 maxint )
Final Steps
There is also an "install by default" checkbox that should be checked for any subsystems that require it. Typically, the sw.eoe, sw.lib, sw.hdr and man.manpages will have this option checked.
Before continuing, be sure to save the .spec and .idb files that Software Packager creates to /usr/neko_staging/dist. This will make them available to the next step.
Headless Alternative to swpkg, genidb
Running an SGI headless? No problem! Raion and EasyMode developed genidb(1). It skips many of these steps.
Referencing the above section, start with a spec file. Here's one for fooware, using all of the above steps:
product neko_fooware id "Your description goes here" image eoe id "fooware binaries" version 100 order 9999 subsys base default id "fooware binaries" prereq ( neko_fooware.lib 100 maxint neko_foo.lib 100 maxint neko_bar.eoe 100 maxint neko_baz.include 100 maxint ) replaces self exp neko_fooware.eoe.base endsubsys endimage image lib id "fooware libs" version 100 order 9999 subsys base default id "fooware libs" prereq ( neko_fooware.lib 100 maxint neko_foo.lib 100 maxint neko_bar.eoe 100 maxint neko_baz.include 100 maxint ) replaces self exp neko_fooware.lib.base endsubsys endimage image include id "fooware headers" version 100 order 9999 subsys base default id "fooware headers" replaces self exp neko_fooware.includes.base endsubsys endimage image man id "fooware manpages" version 100 order 9999 subsys manpages default id "fooware manpages" replaces self exp neko_fooware.man.manpages endsubsys endimage image opt id "optional" version 1 order 9999 subsys patch id "patch files" replaces self exp neko_fooware.opt.patch endsubsys subsys relnotes id "release notes" replaces self exp neko_fooware.opt.relnotes endsubsys subsys dist id "distribution files" replaces self exp neko_fooware.opt.dist endsubsys endimage endproduct
If this looks complicated, just go section by section. If problems still exist, ask on the IRIXNet forums.
Once that's established, copy it to /usr/neko_staging/dist, add all other files including patches, relnotes etc.
Then:
genidb -p /usr/neko_staging -s /usr/neko_staging/dist/neko_fooware.spec -v
The output should say:
(-s) Input Spec: /usr/neko_staging/dist/neko_fooware.spec (-p) Path: /usr/neko_staging Working through specified path: /usr/neko_staging IDB output file: /usr/neko_staging/dist/neko_fooware.spec Parsed Spec File Scanning files in: /usr/neko_staging Completed with 25 entries and 0 rejections.
Or something to this effect. It'll tag files as best it can. Manually review the file, as sometimes subsystems get messed around with. Skip the next section, Tagging.
Building the package
Next, the idb must be sorted per the gendist manual:
sort +4u -6 < neko_fooware.idb > /usr/nekoware/dist/neko_fooware.idb
This will copy it to /usr/nekoware/dist. cp the spec file, patches, relnotes and src if present.
Next, fix the paths in idb: perl -pi -e 's/_staging/ware/g' neko_fooware.idb
Running Gendist
Finally, try gendist:
% cd /usr/neko_dist % gendist -sbase / -spec /usr/nekoware/dist/neko_fooware.spec -idb /usr/nekoware/dist/neko_fooware.idb -distdir .
It'll give any errors such as empty subsystems and such.
Skip to Quickstarting for relevant info.
Tagging
Every file that the software creates and installs must be tagged with a particular subsystem within the package. Above, we created a clean application tree in /tmp/build for this very purpose. Had we not, each file that the software installed would need to be found in /usr/nekoware - a very tedious process!
Import the entire /tmp/build directory and tag each file. For example, files installed in lib/ would be tagged with sw.lib, those in bin/ and share/ should be in sw.eoe and include/ is tagged with sw.hdr.
All directory entries should be removed from the distribution entirely. Leaving them is considered sloppy and clutters the package.
Set all files as owned by the root user and sys group, save the .spec and .idb files once more and exit Software Packager.
Fixing Paths
The current package now contains all files installed by the software with the correct permissions and tagged with the correct subsystem. However, due to using the sandbox, /tmp/build, all of the paths are incorrect. Thankfully, correcting them is an easy proposition:
(prompt) cat /tmp/build/usr/nekoware/dist/neko_fooware.idb | \ sed 's/\/tmp\/build//g' > tmp.idb (prompt) mv tmp.idb /tmp/build/usr/nekoware/dist/neko_fooware.idb
Alternatively, the .idb file can be opened using a text editor and the necessary replacements done using the editor's find-and-replace functionality.
Re-launch the Software Packager and open the .spec and .idb files. Verify that the paths are correct.
Quickstarting
Note that the myth that any files should be marked with norqs is false. gendist automatically marks all ELF files with needrqs, unless the file has been tagged with norqs. Any other files, such as text files, graphics etc. will not trigger an rqsall run after installation, nor will they even be read by rqs.
During most package installations using inst(1M) or swmgr(1M), certain files need to be "Re-quickstarted" using rqsall(1). When creating a new package, certain files may be marked as not needing this process using the norqs option.
Toolchest Entries
Testing and Building
Save the .spec and .idb files once more and move to the next worksheet. This worksheet provides the final steps in Software Packager. Click the Test button to test the package build process. It is likely that the process will complain about files missing from /usr/nekoware. Move to a shell and copy these files from /tmp/build into their respective directories in /usr/nekoware and run the test again.
It's worth it even if built with genidb to check, as genidb doesn't support post install commands or other features.
Once the test routine passes without complaint, click the Build button and exit Software Packager. The distribution files for the package should now be in /usr/neko_dist . Change to that directory and archive these files:
% cd /usr/neko_dist % tar -cf neko_fooware-1.2.3.tardist *
The next, and final, step is crucial. Change to the working directory, "-PATCHED" above, and uninstall the software:
% su % gmake uninstall % rm /usr/nekoware/dist/neko_fooware.* % rm /usr/nekoware/src/fooware-1.2.3.tar.gz % rm /usr/nekoware/relnotes/neko_fooware.txt % rm /usr/nekoware/patches/neko_fooware-1.2.3_irix.patch
Now, install the package as though it were a normal Nekoware tardist:
% inst -f /usr/dist/neko_fooware-1.2.3.tardist
Verify that the software installs correctly and runs as before, with no errors. If it installs and runs correctly, contact Raion on the forums for instructions.
Postprocessing
Certain installed files may require some kind of post-processing to integrate or register them with e.g. a service or database that is part of another package. The steps necessary will either be documented in the installation instructions or silently performed as part of make install. In the latter case, one will have to carefully inspect the output and determine if any special action needs to be taken. Examples of files that require post-processing are Icons or texinfo pages. While the tools to install icons are likely already installed on the system, the install-info tool would warrant an additional prerequisite in the spec file for the subsystem containing the file. When you have determined the commands required, add an appropriate exitop to the idb file. For a texinfo file, the exitop may look as follows:
f 0644 root sys usr/nekoware/info/foo.info usr/nekoware/info/foo.info neko_foo.man.info exitop('if test -x $rbase/usr/nekoware/bin/install-info; then chroot $rbase /sbin/sh -c "/usr/nekoware/bin/install-info --info-dir=/usr/nekoware/info /usr/nekoware/info/foo.info;" ; fi')
For Perl modules, perllocal.pod should not be installed, but amended as follows:
f 0555 root sys usr/nekoware/lib/pidgin/perl/auto/Pidgin/Pidgin.so install/usr/nekoware/lib/pidgin/perl/auto/Pidgin/Pidgin.so neko_pidgin.sw.lib exitop('$rbase/usr/nekoware/bin/perl -MExtUtils::Command::MM -e "perllocal_install" -- "Module" "Pidgin" "installed into" "/usr/nekoware/lib/perl5" LINKTYPE "dynamic" VERSION "0.01" EXE_FILES "" >> $rbase/usr/src/pidgin/install/usr/nekoware/lib/perl5/irix-n32/perllocal.pod')
Standardization of nekoware
The package release notes should be installed by default. Also please put man pages in /usr/nekoware/share/man rather than /usr/nekoware/man, etc. It may be necessary to have to override some default locations (e.g. "--mandir=$PREFIX/share/man" instead of "--mandir=$PREFIX/man").
Quality Standards
Updated later