NI Linux Real-Time and opkg: Distributing Packages¶
Introduction¶
Oftentimes it can be desirable to extend the functionality provided by the Linux kernel and have access to other custom packages. This document will discuss how to create, package, and test loadable packages with NI Linux Real-Time.
A Note on Support¶
This document is meant as a walkthrough of general Linux concepts within NI Linux Real-Time. As these concepts are general to any Linux system and the open source software used, NI Support will not provide assistance through Technical Support channels should problems be encountered. NI does not provide official support for modifying the kernel such as through the addition of loadable kernel modules. For more information on how NI provides support for NI Linux Real-Time, refer to the NI Linux Real-Time FAQ. If problems are encountered, posting to the NI Linux Real-Time Community or other Linux discussion boards is the recommended way to get further guidance.
Requirements¶
The following software and hardware are required to follow this tutorial:
NI Linux Real-Time System with one of the following access to the online NI Repositories
Source for a Linux Package
NI recommends using the “Hello, World!” source
available here
for this tutorial, however one can use your own source or even pre-built shared libraries.
Opkg¶
Opkg is a light-weight package manager which uses the *.ipk format to install and manage packages on a filesystem. While slightly different, *.ipks are very similar to *.deb packages and are based on that standard. Due to the lightweight nature of opkg and its basis on a standard Linux package type, NI chose to use opkg as the package manager for NI Linux Real-Time.
This tutorial will cover the steps needed to use the opkg and opkg-build commands to create a package for distribution. *.ipks can be created on any system with opkg-build installed. For simplicity, this tutorial uses a Linux Real-Time system. For more information on opkg, refer to the official documentation.
Configuring the System¶
Before starting, the required software and toolchains must be installed to the NI Linux Real-Time system used. This can be accomplished through console access to the device via a serial port, SSH, or direct access via a keyboard and monitor. For the screenshots in this tutorial, SSH is used via PuTTY.
Open a console to the NI Linux Real-Time system and log in as or switch to the admin user.
Run the opkg update command to refresh the list of available packages. .. code:: bash
opkg update
Install the opkg-utils package to install the required tools for creating *.ipks. .. code:: bash
opkg install opkg-utils
Confirm that the installation completed successfully.
Source Files¶
To demonstrate building and testing a package, this tutorial will use a simple “Hello, World!” example. While this same process will apply to any package, NI recommends walking through the process for this simple module before moving to more complex designs.
The source for this “Hello, World!” package
will consist of three main
files:
helloworld.c – The C source code
CONTROL - The control file for the package
debain-binary - The debian-binary file
helloworld.c¶
This is C source code for a simple “Hello, World!” program.
#include <stdio.h>
int main()
{
printf("Hello, World!!! \\n");
return 0;
}
If you want to compile the source on the target, you could do so using the gcc toolchain:
gcc –o hello helloworld.c
Note: if you are following this tutorial and compiling on target, make sure to install the compile tools which will allow you to use gcc.
opkg install gcc binutils gcc-symlinks
At this point, you now have an executable called hello.
Creating the Package File¶
With the source in hand, the next step is to package it into an *.ipk for redistribution. As mentioned previously, *.ipks are very similar to *.deb packages and are based on that standard. For more information on creating *.ipks and the options for doing so, NI recommends referring to the official documentation for opkg and opkg-build.
Directory Structure¶
To create an *.ipk file, everything must be in the proper directory structure. For this tutorial the following directory structure will be used.
hellopkg
|-- CONTROL
| `-- control
|-- debian-binary
`-- usr
|-- bin
| `-- hello
`-- lib
This mirrors the final structure contained in the built package, which is simply a special compressed form of that directory structure. As covered in the official opkg documentation, an *.ipk requires a few things with the other items being optional:
A CONTROL directory with a control file. .. note:: Keep in mind that Linux is case sensitive.
The data files to be installed in their proper directory structure.
The optional components required for a package are:
A postinst script, to register the kernel module with DKMS following the installation.
A prerm script, to remove and unregister the kernel module from DKMS prior to removal.
For more information on *.ipks and these files, refer to the official documentation and man pages for opkg. To proceed with this tutorial, recreate the file structure shown above on the NI Linux Real-Time system with the files provided for this tutorial.
Control File¶
The control file describes the package’s dependencies, maintainer, name, version, and other information required by opkg to ensure proper installation. Much of this information will also be returned if the opkg info command is run on a built or installed package.
Package: hellopkg
Version: 1.0.0
Architecture: x64
Maintainer: "somebody" <somebody@somewhere.com>
Description: hello world
Source: helloworld.c
Priority: optional
Section: libs
The debian-binary File¶
This file should be a text file containing only the following line, as described by the *.ipk standard.
2.0
Scripts¶
As mentioned previously, there are two optional scripts when creating *.ipk files for installing packages. These scripts handle the registration, installation, and removal of files during installation and removal of the package.
Note
In order to build a package, all scripts must have executable privileges. To ensure that this is the case, run chmod a+x <script> before attempting to build a package.
preinst¶
The preinst script will be run before the installation of the package files.
postinst¶
The postinst script will be run upon finishing the installation of the package files.
premrm¶
The prerm script will be run by opkg before any files are removed during package removal.
postrm¶
The postrm script will be run by opkg after files are removed during package removal.
Building the Package¶
Once the directory structure is in place, all that’s necessary is to build them into an *.ipk package.
Change directories to the directory containing the top-level directory for the package. In this case, the directory containing the hellopkg/ directory.
Run the opkg-build command on the package directory.
Confirm that the *.ipk file is now present.
Building the Feed¶
If you wish to turn the directory into a feed, you can perform the following step to generate Packages and Packages.gz files.
Run opkg-make-index –p Packages Packages
From there, you can put these files onto a HTTP/S web server to access the feed remotely.
At this point, NI recommends testing the package on a different system from the one it was originally built on or testing by formatting the system used to create the *.ipk and installing from scratch. You can simply transfer the ipk to the target, and then install it using opkg.
A Note for More General Use Cases¶
The tutorial above just walked through the steps for building an ipk that includes a Hello World executable. If you want to apply this to an ipk that will include various shared libraries, you can still follow the steps above, and use the tree structure. For example:
examplepkg
|-- CONTROL
| `-- control
`-- usr
|-- bin
| `-- exampleexe
`-- lib
`-- example.so
Once you have the tree structure in place, you can follow the rest of the steps in the tutorial. For installing from the OS package manager, it is best practice to install shared libraries to /usr/ directories. It is best practice to use /usr/local/ for things not managed by opkg