Note: This article is out of date in some places, but is kept for posterity.
Because Linux is an open operating system, you can configure and assemble it to suit specialized purposes. However, while variety and choice are beneficial for users, heterogeneity can vex software developers who must build and support packages on a multitude of similar but subtly different platforms. Fortunately, if an application conforms to the Linux Standard Base (LSB) and a flavor of Linux is LSB compliant, the application is guaranteed to run. Discover the LSB, and learn how to port your code to the standard.
This tutorial describes the Linux Standard Base (LSB), a specification and collection of tools and test suites that help Linux software developers increase compatibility among Linux software distributions. Applications and distributions can be certified compliant with the specification, providing assurances to users that certified software is compatible. This tutorial describes the LSB and explains how to vet your application code to conform with it.
sudo apt-get install kvm
in a terminal window. Or, you can use the Synaptics package manager if you prefer using a graphical interface.
As packaged in the Debian and Ubuntu distributions, in order to use kvm without being root, your user id must be in the “kvm” group. You can edit the /etc/group
via a text editor as the superuser, or if you are running Ubuntu, you can use the menu selection System→Administration→Users and Groups from the system's menubar, and then on the click on the “Unlock” button, enter your password, then click on “Manage Groups”. This will cause a “Group Settings” window to appear. Find “kvm” in the selection window, and then click on “Properties”, and then add a check-mark next to your user id in the “Group Members” list, and then click the “OK” button. After you make a change to the group membership of the “kvm” group, you will need to logout and then login again so the change can take effect.
====Running KVM====
To start the KVM virtual machine you simply untar the lsb-siX-vm tarball and run the following command in a terminal window:
kvm lsb-siX-vm-4.0.1-2.i686-1.1.2.vmdk
The KVM application traps all mouse and keyboard input unless you press Ctrl+Alt. To set the focus back to the virtualized environment, just click in the KVM window. There are additional arguments mentioned in the README that comes with the lsb-siX appliance that allow networking and port redirection to move files in and out of the virtual machine.
Congratulations! You now have openSUSE 11.1 running in its own VM!
=====Porting Your Code to the LSB=====
With setup behind you, you can begin the process of porting your code to the LSB.
====The General Approach to Porting====
Porting an application to the LSB requires the following steps:
- Copy your code to the new build system.The new build system might be an LSB-compliant Linux distribution running on separate hardware or, in this case, a VM.
- Build your code, and run the Linux Application Checker (“AppCheck”) tool to scan your binary for symbols that are not expressly provided in the LSB specification.You can also this tool to scan your static archives for suitability for use in an LSB-compliant application.
- If AppCheck finds invalid symbols, change your code or the assembly of your code to bring it into compliance.For instance, if you're using a library that isn't part of the LSB specification, link to it statically so that the code is self-contained in your binary. (Again, this assumes that the code in the library itself is otherwise LSB compliant.) Assuming that you've addressed all the issues, you can proceed to the next step.
- Use the LSB Build Environment to build the code in a clean, compliant environment.If your code uses libraries that are not provided for under the LSB, you must modify your build process to either install or link statically to those libraries. (Remember that all libraries must be LSB compliant, as well.)
- If your code builds successfully within the LSB Build Environment, run the code in the LSB Sample Implementation.
- If your target Linux system is LSB compliant, run your code on that system.\\ - Package your application.LSB-conforming systems promise to be able to install an LSB-compliant RPM. However, you need not limit yourself to that format, with the caveat that the packaging technology you choose must work on an LSB-compliant system. For example, a compliant shell script with a tarball is an acceptable format. Your own installer is acceptable, too, as long as the installer itself is LSB compliant.
Now, let's build a simple application to elaborate on the process.
=====Installing and Running the LSB Build Environment Utilities=====
Before using the chroot
version of the LSB Build Environment, try the Build Environment utilities, which you can quickly and easily install on virtually any Linux system. You can use the Build Environment utilities lsbappchk and lsbpkgchk to quickly determine why your application and RPM package (the standard LSB format), respectively, aren't compliant with the LSB.
====Download and Install the Build Environment Utilities====
The Build Environment utilities are available as two RPMs, one for lsbappchk and another for lsbpkgchk. Because the test system is Debian Linux, you can either convert the RPMs to DEB format using alien, or download the native .deb packages suitable for Debian's dpkg package manager. For a more complex application, with a GUI, you may want to also download lsb-build-desktop, lsb-build-qt3 and/or lsb-build-qt4.
1 $ sudo apt-get install wget 2 $ wget http://ftp.linuxfoundation.org/pub/lsb/test_suites/released-all/binary/application/lsb-appchk-4.0.0-2.i486.rpm 3 $ wget http://ftp.linuxfoundation.org/pub/lsb/test_suites/released-all/binary/application/lsb-pkgchk-4.0.1-2.i486.rpm 4 $ wget http://ftp.linuxfoundation.org/pub/lsb/base/released-all/binary/lsb-setup-4.0.0-2.noarch.rpm 5 $ wget http://ftp.linuxfoundation.org/pub/lsb/lsbdev/released-all/binary/ia32/lsb-build-base-4.0.0-4.i486.rpm 6 $ wget http://ftp.linuxfoundation.org/pub/lsb/lsbdev/released-all/binary/ia32/lsb-build-c++-4.0.0-2.i486.rpm 7 $ wget http://ftp.linuxfoundation.org/pub/lsb/lsbdev/released-all/binary/ia32/lsb-build-cc-4.0.0-4.i486.rpm 8 $ sudo apt-get install alien 9 $ alien -k *.rpm 10 $ ls -t -1 *.deb lsb-setup_4.0.0-2_all.deb lsb-pkgchk_4.0.1-2_i386.deb lsb-build-cc_4.0.0-4_i386.deb lsb-build-c++_4.0.0-2_i386.deb lsb-build-base_4.0.0-4_i386.deb lsb-appchk_4.0.0-2_i386.deb 11 $ sudo dpkg --install *.deb 12 $ ls /opt/lsb bin doc man 13 $ ls /opt/lsb/bin lsbappchk lsbc++ lsbcc lsbpkgchk
The native .deb packages are at:
http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/pkgs-common/lsb-appchk_4.0.0-2_i386.deb http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/pkgs-common/lsb-pkgchk_4.0.1-2_i386.deb http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/pkgs-common/lsb-setup_4.0.0-2_all.deb http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/pkgs-common/lsb-build-base_4.0.0-4_i386.deb http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/pkgs-common/lsb-build-c++_4.0.0-2_i386.deb http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/pkgs-common/lsb-build-cc_4.0.0-4_i386.deb
Command 1 installs wget
if it isn't already available on the system. Commands 2-7 download the latest versions of the LSB utilities:
* lsb-appchk verifies that a supplied binary only uses the dynamically linked symbols defined in the LSB.
* lsb-pkgchk verifies that an application package–a bundle used to install the software on an LSB-compliant system–is valid. The lsb-pkgchk tool is intended for RPMs only. However, the LSB does not mandate the use of RPMs to install software.
* lsb-setup simply provides the /opt/lsb/* directory structure used by a number of lsb packages
* lsb-build-base provides stub libraries and header files. While the stub libraries don't implement the functions defined in the LSB, they do mimic the actual dynamic libraries found on an LSB system. Hence, you can use lsb-build-base to build a compliant application.
* lsb-build-c** adds ''C++'' support to the build environment.
* **lsb-build-cc** contains lsbcc, a wrapper around the GNU Compiler Collection (GCC) compiler that yields LSB-conforming applications. If your application uses a GNU-style configure script, you can easily modify your script to use lsbcc instead of the default system (typically GCC) CC compiler. In some cases, you can directly replace GCC with lsbcc (for example, in a makefile).
Command 8 installs alien, a utility that can convert RPMs to Debian DEB packages (among other features). Command 9 runs alien; command 10 shows the results; and command 11 installs all the software into the /opt/lsb/ directory, as shown in commands 12 and 13. If you use the native .deb packages, steps 8 and 9 would be skipped.
If your system supports a package manager such as apt, yum, or zypper, you can also add LSB package repositories and install the SDK and application tests using those tools. The LSB repositories are at:
* [[http://ftp.linuxfoundation.org/pub/lsb/repositories/debian/
[lsb-4] name=LSB 4 baseurl=http://ftp.linuxfoundation.org/pub/lsb/repositories/yum/lsb-4.0/repo-ia32 enabled=1
For zypper, again you create an LSB repo file like /etc/zypp/repos.d/lsb-ia32.repo
:
name=lsb-ia32 enabled=1 autorefresh=0 baseurl=http://ftp.linuxfoundation.org/pub/lsb/repositories/yum/lsb-4.0/repo-ia32 type=rpm-md keeppackages=0
Then the package installation would look something like:
apt-get install lsb-appchk lsb-pkgchk lsb-build-cc lsb-build-c++
or
yum install lsb-appchk lsb-pkgchk lsb-build-cc lsb-build-c++
or
zypper in lsb-appchk lsb-pkgchk lsb-build-cc lsb-build-c++
You'll note we omitted lsb-setup and lsb-build-base. This is because the package manager now resolves the dependencies and pulls these packages in with the others.
Building and verifying an RPM is beyond the scope of the tutorial. Instead, let's focus on building a small C
application with lsbcc and scanning the resulting binary for invalid symbols with lsb-appchk.
====An Example Program====
Listing 1 shows a small program that echoes its command-line arguments (error-checking code has been omitted intentionally).
Listing 1. A Simple C Program
#include <stdio.h> #include <stdlib.h> #include <unistd.h> main(argc, argv) int argc; char *argv[]; { int i = 0; for (i = 1; i < argc; i++) { fputs(argv[i], stdout); putchar(' '); } putchar('\n'); exit(0); }
Copy and paste the code into a file named echoargs.c, and then build it with the compiler installed on your Debian system:
$ cc -o echoargs echoargs.c $ ./echoargs hello there, world! hello there, world!
The code works as intended, but is it LSB conforming? To make the determination, run the lsbappchk
command:
$ /opt/lsb/bin/lsbappchk echoargs LSB version is not specified, using 4.0 by default. BIN: echoargs LSB Application Checker Report ============================== Binary echoargs: FAIL Incorrect program interpreter: /lib/ld-linux.so.2 URL: http://developer.linux-foundation.org/lsbchk?suite=appchk&arch=IA32&testcase=echoargs&tpnum=16&result=FAIL&purpose=Check%20program%20interpreter Section .interp not checked Section .note.ABI-tag not checked section .gnu.hash is not in the LSB FAIL section .gnu.hash is not in the LSB
Echoargs is clearly not an LSB-conforming application.
====Use the LSB Compiler to Make the Application Conform====
Now, rebuild the same code using the LSB compiler–lsbcc–and run lsbappchk
on the binary it produces:
$ /opt/lsb/bin/lsbcc -o lsb-echoargs echoargs.c $ /opt/lsb/bin/lsbappchk lsb-echoargs LSB version is not specified, using 4.0 by default. BIN: lsb-echoargs LSB Application Checker Report ============================== ...
(there is additional output, but no FAIL messages) Much better! The new binary is conforming. It was built with the LSB stub libraries using the LSB include files (header files) instead of the system header files. But does the application run?
$ ./lsb-echoargs foo bar $ foo bar
While not yet certified, Ubuntu Hardy is indeed lsb conforming. If running the application gave this type of message:
$ ./lsb-echoargs foo bar -bash: no such file or directory: ./lsb-echoargs
It would be an indication that the system is not LSB V4.0 conformant, so the binary cannot be executed. The command ./lsb-echoargs
produces the somewhat odd message, -bash: ./lsb-echoargs: No such file or directory
, which belies the real error–namely, that the system cannot load the binary. (In a moment, you'll use the LSB Sample Implementation to run this binary.)
As another example, consider Listing 2. The code snippet uses the open source Perl Compatible Regular Expressions (PCRE) library to add the power of regular expressions to traditional C
. As useful as PCRE is, it's not part of the LSB specification.
On Ubuntu Hardy, you need to install libpcre3-dev to build this example. On other systems the package name may be different
$ apt-get install libpcre3-dev**\\ **
Listing 2. A Snippet of a PCRE Application
#include <pcre.h> int main() { pcre *re; const char *error; int erroffset; /* more code here */ re = pcre_compile("^[A-Z]", 0, &error, &erroffset, NULL); /* rest of the application */ }
You can build the code with the command cc -o pcre pcre.c -lpcre.
. Checking the code with lsbappchk produces additional error messages:
$ cc -o pcre pcre.c -lpcre $ /opt/lsb/bin/lsbappchk pcre LSB version is not specified, using 4.0 by default. BIN: pcre LSB Application Checker Report ============================== Binary pcre: FAIL Incorrect program interpreter: /lib/ld-linux.so.2 ... FAIL DT_NEEDED: libpcre.so.3 is used, but not part of the LSB ... FAIL Symbol pcre_compile is used, but is not included in LSB 4.0 (Core & C++ & Desktop)
The functions declared by PCRE are not LSB compliant and are flagged. You could avoid this error (assuming that the rest of the PCRE library was LSB compliant) by adding the -static
flag when compiling.
Interestingly, the same command using lsbcc does not generate errors:
$ /opt/lsb/binlsbcc -o lsb-pcre pcre.c -lpcre $ /opt/lsb/bin/lsbappchk lsb-pcre LSB version is not specified, using 4.0 by default. BIN: lsb-pcre LSB Application Checker Report ============================== ...
Again, a lot of output, but no FAIL messages. Let's look at the symbols in lsb-pcre:
$ nm lsb-pcre | grep pcre 08051be0 R _pcre_OP_lengths 08058240 R _pcre_default_tables 0804fd40 T _pcre_is_newline 08050020 T _pcre_ord2utf8 08050090 T _pcre_ucp_findprop 08050130 T _pcre_ucp_othercase 08051c50 R _pcre_utf8_table1 08051c68 R _pcre_utf8_table1_size 08051c6c R _pcre_utf8_table2 08051c84 R _pcre_utf8_table3 08051ca0 R _pcre_utf8_table4 08051f80 R _pcre_utt 08051ce0 R _pcre_utt_names 080521f8 R _pcre_utt_size 080501b0 T _pcre_valid_utf8 0804fec0 T _pcre_was_newline 080597c8 B pcre_callout 0804fd00 T pcre_compile 0804f340 T pcre_compile2 080597b8 D pcre_free 080597b4 D pcre_malloc 080597c0 D pcre_stack_free 080597bc D pcre_stack_malloc
Here, lsbcc statically linked the PCRE code into the executable – one solution to avoid library differences between one Linux platform and another. Lsbcc modifies command-line arguments to the GCC compiler to use LSB header files and libraries and to avoid dynamic links to non-compliant LSB libraries.
If you use GCC and a number of home-grown or popular tools to build your code, lsbcc is probably preferable over the chroot
LSB Build Environment. In contrast, if you use a compiler other than GCC or have dependencies on a specific compiler, compiler options, or library or include file paths, the LSB Build Environment may be superior. The next section demonstrates how to install and use the LSB Sample Implementation to test your application. Both the Build Environment and the Sample Implementation have been redesigned for LSB V4.0. As of this writing the Build Environment is not yet ready for testing. When available, it will be similar to the Sample Implementation, a standalone minimal system. Basically the Sample Implementation with the addition of the SDK.
=====Installing the Sample Implementation=====
Note: The rest of this tutorial uses the virtual lsb-siX-vm instance of openSUSE 11.1 running in VMWare Workstation. If you previously suspended the VM or quit VMWare Workstation, resume the VM or re-launch VMWare Workstation and start the lsb-siX-vm instance. When the instance is running, you should be logged in as tux
automatically.
====Download and Install the chroot LSB Sample Implementation====
This section only applies if you are using a different OS or virtual machine than the lsb-siX-vm. The LSB appliance already has lsbsi-chroot and lsbsi-tools installed. If you are using the lsb-siX-vm, please skip ahead to the section on using the SI.
The Sample Implementation is distributed as the lsbsi-choot rpm package, with a supporting lsbsi-tools package which helps integrate the SI as a “application” on the host system. Because of the complexity of the SI, it tends to lag the full LSB release slightly, and at the time of this writing it is still in beta. For what we're doing in this demo, the beta release should be sufficient.
1 $ wget http://ftp.linux-foundation.org/pub/lsb/impl/beta/binary/ia32/lsbsi-chroot-4.0.1-1.i586.rpm 2 $ wget http://ftp.linux-foundation.org/pub/lsb/impl/beta/binary/ia32/lsbsi-tools-4.0.0-1.i586.rpm 3 $ rpm -ivh lsbsi-chroot-4.0.1-1.i586.rpm lsbsi-tools-4.0.0-1.i586.rpm
Commands 1-2 download the pieces of the LSB Sample Implementation. Command 3 installs them on the system.
* lsbsi-chroot is the core of the Sample Implementation. It installs in opt/lsb/si/chroot.
* lsbsi-tools is a set of scripts and menu entry that facilitate your chroot into the SI system. The scripts provide the proper bind mounts and environment that enable the SI chroot to behave much like a “real” system. An lsbsi group is added to the system at package install. By adding users to this group, non-root users will also be able to use the SI.
After you install the Sample Implementation, you can use chroot
to get to it. You can either run the command /opt/lsb/bin/si-chroot
, the command /opt/lsb/si/tools/si
, the command /opt/lsb/si/tools/si-gui
, or select the menu entry Development|LSB Sample Implementation. To exit the chroot
environment, press Ctrl+D at the new shell prompt.
=====Executing Code in the Sample Implementation=====
Build the simple code of Listing 1 within openSUSE 11.1 and run it within the Sample Implementation.
====Install the SDK====
To make things convenient for development, the lsb-siX-vm openSUSE 11.1 environment provides gcc and LSB SDK. If you are using another system, you would need the install a compiler and the LSB build tools as outlined earlier.
Within your openSUSE 11.1 VM, you now have two environments: the openSUSE environment, with the SDK, and the Sample Implementation. There should be a terminal window open already within the Sample Implementation and if you open another tab or window, you should be the “tux” user in that home directory. For convenience, tux's home directory is bind mounted under /root/myfiles within the SI:
tux user:
$ pwd $ /home/tux $ touch foo
root user in the SI:
$ cd /root/myfiles $ ls -1 Desktop Documents foo
So, to build Listing 1 with the SDK and test it in the chroot
Sample Implementation, you download the code to the openSUSE 11.1 environment, and then build it per the following sequence (the prefixes in the command-line prompt were added for clarity):
(tux) $ wget http://ftp.linuxfoundation.org/pub/lsb/demos/source-code/echoargs.c
(tux) $ /opt/lsb/bin/lsbcc -o echoargs echoargs.c
(si) $ cd /root/myfiles
(si) $ ./echoargs hello there
hello there
By the way, because openSUSE 11.1 is nearly compliant with LSB V4.0.0, the binary you created with lsbcc runs fine in the openSUSE:
(tux) $ ./echoargs this is cool this is cool**\\ **
=====Summary=====
While the example code shown in this tutorial was simple, the same techniques used to build and test a few lines of code apply equally well to a few thousand lines of code. Use the lsb-appchk tool to find questionable symbols. Try building your code with the LSB Build Environment utilities and within the stand-alone LSB Build Environment chroot
environment. If you don't have an LSB V4.0.0-compliant version of Linux, use the LSB Sample Implementation to test the portability of your application. Leverage a tool such as VMWare Workstation to virtually (both metaphorically and practically) multiply your computing resources and run your targeted flavors of Linux.
With a little work, you can shape your application to be LSB compliant, and then apply to have your application certified. Certified distributions and certified applications allow users to invest in Linux comfortably. The LSB provides uniformity, which–perhaps paradoxically–promotes choice.
And after all, choice is what Linux is all about.
=====Attribution=====
This article originally appeared on IBM developerWorks. It has been revised to current technology practices. Thanks to Ted T'So and Jeff Licquia for updating it. The current version has been updated to reflect changes with LSB V4.0.