Learn about Linux Portability

Printer-friendly version

Porting to the Linux Standard Base

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.

Prerequisites

To benefit from this tutorial, you should have experience with the C or C++ programming language as well as the typical Linux software development environment and its cadre of tools, including the compiler, linker, system libraries, configuration and build utilities, and packaging tools.

You should also have experience installing software from the command line and have at least a modicum of experience with administering and maintaining a Linux system, such as configuring a file system, starting and stopping network services, and adding system services.

If you're running Debian Linux, you should also have some experience with the APT package manager. To run VMWare Workstation on Debian Linux, you must install the kernel source associated with your kernel version. (You must typically have superuser access to install VMWare Workstation.)

Before you start the tutorial, you must install several software packages on your Linux system. Here's everything you need:

  • The VMWare Workstation product suitable for your Linux distribution

    Note: Alternatively, you can easily install VMWare Workstation on any computer running Microsoft® Windows® XP and run a virtualized Linux instance on the Windows XP platform. Download a trial version of VMWare Workstation at no cost and use it to create one or more virtual machines (VMs). After you've created a VM, you can save it and switch to the free VMWare Player to replay it.

  • The LSB Sample Implementation
  • The LSB Build Environment
  • The LSB application test suites

You may also find it useful to download and read the LSB V3.0.0 specification appropriate for your target hardware platform. Hardware-specific LSB specifications are available for seven popular architectures: the IA32, IA64, PPC32, PPC64, S390, S390X, and AMD64 processors.

If you want to certify your application, download and read the Application Product Standard associated with your target hardware platform.

To run the examples in this tutorial, you must have a computer running either the Linux or Windows XP operating system. VMWare Workstation running on either of those platforms provides a Linux environment for you to do the rest of your work.

If your application depends on software libraries other than those ratified as part of the LSB specification for your processor, you must install those libraries on the virtual system, as well. To avoid confusion, it's ideal to install application-specific libraries separately from the standard libraries.

The need for a standard

According to the Distro Watch Web site, at least 22 significant Linux distributions currently exist. If you include other variations -- some optimized for size (such as Damn Small Linux ), some for convenience (such as Knoppix ), some tailored to a specific audience (such as Fedora Core ), and still others customized for a specific country (such as Red Flag Linux ) -- that rather staggering number of choices easily doubles or triples. Linux is the only modern operating system with such numerous variations.

On one hand, the do-it-yourself culture of Linux encourages diversity and specialization. On the other hand, such proliferation can be overwhelming, especially if you're an independent software vendor (ISV) faced with developing, selling, and supporting a Linux application. If the "UNIX® Wars" of the 1980s splintered ISVs' chances of success, so many Linux versions seem to promise nothing less than wholesale obliteration of the market for rich Linux applications. To wit, imagine the expense of building and supporting a complex application on more than a handful of Linux variants.

LSB terminology

When discussing the LSB, you'll frequently hear (and read) the terms conformance, compliance, and certification:

  • The LSB defines requirements for a run time and an application to be in conformance with the specification.
  • An application or a distribution is in compliance with the LSB if its developer has realized all the suitable LSB requirements and claims that the software conforms.
  • An application or distribution receives certification if it successfully demonstrates compliance through official review.

In this tutorial, you learn how to create compliant applications. You cannot self-certify your application, although you can run many tests that greatly increase the likelihood of certification.

 

Promoting interoperability

In an attempt both to encourage diversification and provide consistency, the Free Standards Group (now The Linux Foundation) created the Linux Standard Base, an "open source project to develop and promote a set of standards [to] increase compatibility among Linux distributions and enable software applications to run on any compliant system" (according to the LSB Web site, http://www.linuxbase.org ).

Specifically, the LSB defines a consistent Linux platform. A Linux distribution is LSB compliant if it implements (at least) the LSB platform. (Nothing precludes a version of Linux from providing additional features.) A Linux application is LSB compliant if it consumes only the services that the LSB platform provides. If the application requires additional libraries, it provides those, either during installation or through static linking. (Of course, the libraries must be self-sufficient and LSB compliant, as well.) The sidebar "LSB terminology" explains what other terminology means.

The figure below shows the many areas for which the LSB defines (or will eventually define) standards. The areas are libraries, the basis of all Linux applications; the execution environment, including mandates for where certain critical system files reside and how the system provides for localization services; system initialization; common commands and utilities to be found across all LSB-compliant systems; and user and group management.

Figure 1. The components of the LSB
Figure 1. The components of the LSB

Application developers are probably most concerned with the blue and orange boxes.

In blue, the LSB stipulates a set of core libraries and additional modules that an LSB-compliant application can use. The core libraries include libc, libm, libpthread, libpam, libcrypt, libz, libncurses, librt, and libgcc_s. Modules include a module for X Window System Version 11 graphics (libX11, libXt, libXext, libSM, libICE, and libGL) and the C++ standard library, libstdc++.

In orange -- and not part of the LSB specification -- is a set of valuable companion tools to validate that applications, packages, (and soon, static libraries) are LSB compliant.

Binary compatibility

The LSB specification is a binary compatibility standard. An application binary (compiled, executable code) that is LSB compliant can run unchanged on any LSB-compliant Linux distribution (built for the same processor architecture as the application).

Binary compatibility is remarkably different from source compatibility. An application that is source compatible requires the software to be recompiled in situ, with the local system's compilers and libraries -- two significant founts of variability and unpredictability. Source compatibility doesn't guarantee that the executable will run, let alone run as expected.

 

The benefits of consistency

Think of the LSB as a kind of binding agreement between a distribution and an application. The distribution "agrees" to provide (at least) the specification's libraries and interfaces, and the application "agrees" to use only those libraries and interfaces, providing any other software that's needed. To ensure that "both parties" adhere to the agreement, the LSB provides tools, guidelines, and validation services to certify Linux distributions and applications as LSB compliant.

Adherence to the LSB inures to the benefit of distribution vendors, ISVs, and users alike.

For the distribution vendor:

  • A distribution vendor can promote compliance with the LSB, assuring customers that LSB compliant applications will run consistently and reliably on its product.
  • After its distribution is certified LSB compliant, a vendor can re-focus its energies on differentiating, novel features.

For the ISV:

  • An application developer can create and certify a single binary and deploy it to any LSB-compliant distribution.
  • An ISV need only test and support the single, certified binary. Additionally, if the binary is sufficiently internationalized, a single version of an application might suffice for all customers, independent of nationality.

For the customer, the user:

  • The user can pick and choose among competing LSB-compliant distributions, either to deploy the most appropriate flavor of Linux or to avoid vendor lock-in.
  • The user has many Linux applications to choose from.

Given all the dynamics listed above, distribution vendors, ISVs, and users reap rewards from each unique investment in Linux. In turn, Linux benefits, as well.

 

The LSB Build Environment and Sample Implementation

The LSB is a "contract" between an application and a distribution to adhere to the LSB specification. Ignoring the complications of making a Linux distribution compliant, how can a Linux application developer -- you -- ensure compliance?

If you're a developer, you likely know your code very well and can work diligently to meet the obligations of LSB compliance. However, it may not always be obvious that your code depends on a non-standard (non-LSB) component, especially as a typical Linux distribution has thousands of components strewn about the system.

For example, perhaps your code depends on a non-compliant string library found only on your favorite distribution. Or perhaps, the string library used was added locally and recently by your system administrator. As an another example, perhaps your code depends on a specific version of a library. Version W of the library is LSB compliant, but version Y -- the version you depend on -- is not part of the LSB specification.

 

Tools to help you migrate

To help find and remove such dependencies -- the crux of making your code LSB compliant -- the LSB provides two significant tools: the Build Environment and the Sample Implementation.

The Build Environment helps you identify source code that depends on non-LSB libraries and application binary interfaces. The Build Environment consists of header files, stub libraries, and a compiler wrapper that simulate a software build environment on a compliant Linux system. You can install the Build Environment on any Linux system -- even one that is not compliant.

The Build Environment is available in two forms: One form is a set of utilities that run within your local operating system. The utilities simulate a build within an LSB environment. The other form is a complete hierarchy of files that substitutes for your environment with chroot. You might use the former as a quick measure of compliance. The latter typically requires you to import your build environment into the new root, but eliminates issues with stray files.

The Sample Implementation helps you validate that your application executes successfully in a compliant run time environment. You can think of the Sample Implementation as a mini-Linux (yes, you can boot from it, if you want to) -- an environment that proxies for an LSB-compliant distribution.

Of course, you could use an LSB-compliant distribution as your test environment, but the Sample Implementation has a few advantages: It only includes what's defined in the LSB, and several versions of the Sample Implementation exist -- one each for version of the LSB specification. Hence, if you want to verify that your application is LSB V2.0 and LSB V3.0 compliant, you can install the respective Sample Implementations on a single test system rather than require two Linux systems. Certainly, the Sample Implementation is the preferred method to validate your application against a newly ratified LSB specification before real-world, compliant systems are available.

An individual Build Environment and Sample Implementation set is provided for each version of the LSB standard. For this tutorial, you'll use LSB V3.0.0 as the target platform. (Version 3.0.0 was the most recent LSB specification at the time this tutorial was written. Versions 2.0.0 and 1.3.0 are previous versions of the LSB. You'll likely find that many popular Linux distributions are certified with either of the earlier instances of the LSB.)

 

The benefits of porting using Virtual Machines

To run the LSB V3.0.0 Sample Implementation, you need an operating system capable of running the Sample Implementation in a chroot environment. The community distribution Fedora Core 4 (FC4) is one flavor of Linux that can run the V3.0.0 Sample Implementation.

But what if you don't have FC4 installed? Or, what if you want to run your application on numerous instances of the LSB or on a handful of Linux distributions? You could assemble a (somewhat large) collection of hardware or multi-boot among all your desired variations, but a far easier and less-expensive solution is to run each Linux distribution in its own VM.

VMWare Workstation is Virtual Machine (VM) software that runs equally well on Linux and Windows. After you install VMWare Workstation, you can create, load, and run any number of Linux variants (and instances of Windows). Switching between operating systems is as simple as switching between tabs or loading a different image. VMWare Workstation even allows you to create groups of VMs, or teams, to run many VMs together as a group (perfect for testing failover configurations without tons of hardware).

For purposes of this tutorial, VMWare Workstation transforms Debian Linux (the host system) into FC4.

Download and install VMWare Workstation

Install VMWare Workstation on Debian Linux, and run FC4 in a VM to run the LSB V3.0.0 Build Environment and Sample Implementation.

Download a VM image

Download an FC4 VM image (a .vmx file and corresponding .vmdk, vmsd, and .nvram files) for VMWare Workstation. You can find an image at the Thought Police web site. As the zip package is an entire operating system, it's quite large: 283 MB.

Use the following code to extract the .zip package to yield a usable virtual image:

$ unzip fedora-fc4-i386.zip 
Archive:  ../fedora-fc4-i386.zip
creating: fedora-fc4-i386/
inflating: fedora-fc4-i386/fedora-fc4-i386.nvram  
inflating: fedora-fc4-i386/fedora-fc4-i386.vmdk  
inflating: fedora-fc4-i386/fedora-fc4-i386.vmx  
inflating: fedora-fc4-i386/fedora-fc4-i386-s001.vmdk  
inflating: fedora-fc4-i386/fedora-fc4-i386-s003.vmdk  
inflating: fedora-fc4-i386/fedora-fc4-i386.vmsd  
inflating: fedora-fc4-i386/fedora-fc4-i386-s002.vmdk  
$ ls
fedora-fc4-i386

Determine your kernel version

Determine the version of the kernel running within your Debian Linux system. Use the uname command.

$ uname -a
Linux 2.4.27-2-686 #1 Wed Aug 17 10:34:09 UTC 2005 i686 GNU/Linux

Here, the example system is running kernel 2.4.27-2-686.

Install and run the VMWare Workstation

Install and run VMWare Workstation on your Debian Linux system. You must download the kernel source and kernel headers that correspond exactly to your running kernel. As a convenience, use the apt-get command to download and install the source and headers on your system:

1 $ sudo apt-get install kernel-source-2.4.27
2 $ sudo apt-get install kernel-headers-2.4.27-2-686
3 $ cd /usr/src
4 $ sudo bzip2 -d kernel-source-2.4.27.tar.bz2
5 $ sudo tar xvf kernel-source-2.4.27.tar
6 $ cd kernel-source-2.4.27
7 $ sudo mv include include.orig
8 $ sudo ln -s /usr/src/kernel-headers-2.4.27-2-686 /usr/src/linux/include

Commands 1-5 download, install, and extract the packages for the kernel source and the kernel headers. Commands 6-8 ensure that the kernel headers found on your system match your kernel version. You're now ready to download, (build a small portion), and install the VMWare Player.

Download, build, and install VMWare Player

Download and extract the VMWare Workstation software. You can download a tarball package suitable for use on Debian Linux from VMWare Workstation . (You must complete a short registration form to download the software.) The version of VMWare Workstation used in this tutorial was VMware-workstation-5.5.1-19175.tar.gz.

$ cd /tmp
$ tar zvxf VMware-workstation-5.5.1-19175.tar.gz.
vmware-distrib/
vmware-distrib/lib/
vmware-distrib/lib/modules/
vmware-distrib/lib/modules/source/
vmware-distrib/lib/modules/source/vmmon.tar
vmware-distrib/lib/modules/source/vmnet.tar
vmware-distrib/lib/modules/source/vmppuser.tar
..

You should now have a directory named /tmp/vmware-distrib that looks like this:


$ ls vmware-distrib
FILES  bin  doc  etc  installer  lib  man  vmware-install.pl

Install VMWare Workstation, change your working directory to /tmp/vmware-distrib, and then run the installer: vmware-install.pl.

 

$ cd /tmp/vmware-distrib
$ sudo perl vmware-install.pl

At each prompt the installer presents, accept all the default answers, and then accept the End User License Agreement. Be sure to answer "yes" to the questions about networking to create Network Address Translation (NAT) and host-only networks.

Part of the installation builds two kernel modules for your system: vmmon and vmnet. You should see something like the following in your console:


Trying to find a suitable vmmon module for your running kernel.

None of the pre-built vmmon modules for VMware Player is suitable for your 
running kernel. Do you want this program to try to build the vmmon module for 
your system (you need to have a C compiler installed on your system)? [no] yes

Using compiler "/usr/bin/gcc". Use environment variable CC to override.

What is the location of the directory of C header files that match your running 
kernel? [/lib/modules/2.4.27-2-686/build/include] <Return>

Extracting the sources of the vmmon module.

Building the vmmon module.

Using standalone build system.
make: Entering directory `/tmp/vmware-config0/vmmon-only'
make[1]: Entering directory `/tmp/vmware-config0/vmmon-only'
make[2]: Entering directory `/tmp/vmware-config0/vmmon-only/driver-2.4.27-2-686'
make[2]: Leaving directory `/tmp/vmware-config0/vmmon-only/driver-2.4.27-2-686'
make[2]: Entering directory `/tmp/vmware-config0/vmmon-only/driver-2.4.27-2-686'
make[2]: Leaving directory `/tmp/vmware-config0/vmmon-only/driver-2.4.27-2-686'
make[1]: Leaving directory `/tmp/vmware-config0/vmmon-only'
make: Leaving directory `/tmp/vmware-config0/vmmon-only'
The module loads perfectly in the running kernel.
..
Extracting the sources of the vmnet module.

Building the vmnet module.

Using standalone build system.
make: Entering directory `/tmp/vmware-config0/vmnet-only'
make: Leaving directory `/tmp/vmware-config0/vmnet-only'
The module loads perfectly in the running kernel.

Starting VMware services:
   Virtual machine monitor                                             done
   Virtual ethernet                                                    done
   Bridged networking on /dev/vmnet0                                   done
   Host-only networking on /dev/vmnet1 (background)                    done
   Host-only networking on /dev/vmnet8 (background)                    done
   NAT service on /dev/vmnet8                                          done

The configuration of VMware Workstation 5.5.1 build-19175 for Linux for this 
running kernel completed successfully.

Run VMWare Workstation

After the build and installation are complete, you can run VMWare Workstation by typing /usr/bin/vmware. The command should open a window similar to Figure 2. You can use VMWare Workstation to run multiple operating system instances side by side. Each instance runs in its own VM.

Figure 2. VMWare Workstation

Now, create a suitable VM for FC4, including NAT to allow the VM to access all network resources in the real world. To do so, complete these steps:

  1. Click Open Existing Virtual Machine or Team.
  2. In the Open Existing Virtual Machine or Team window (shown in Figure 3), navigate to the VMWare image for FC4 that you extracted earlier. Select the fedora-fc4-i386.vmx file.
    Figure 3. Choosing a VM
  3. In the Commands area (shown in Figure 4), click Edit virtual machine settings to reveal the settings window.
    Figure 4. A VM control panel
  4. Click Ethernet 1 (shown in Figure 5), and then change the settings (if necessary) to use NAT.
    Figure 5. Editing the VM settings
  5. Click OK to save your settings and return to the VM control panel.
  6. Click Power on this virtual machine to start the virtual Linux instance.
  7. Click Keep in the first window, and OK in the remaining warning windows.

When the Linux kernel boots, you should see a startup screen that resembles Figure 6. (During the boot process, you should also notice that the IP address of the system is set automatically.)

Figure 6. FC4 running in a virtualized environment
Figure 6. FC4 running in a virtualized environment

To login as root, type root with the password thoughtpolice. (The creator of each image sets the password; see the documentation or Web page of each image for login information.)

The VMWare application traps all mouse and keyboard input unless you press Ctrl+Alt. To set the focus back to the virtualized environment, press Ctrl+G.

Congratulations! You now have FC4 running in its own VM! You can save the image (to play again in VMWare Player), suspend the machine, clone the machine, and more. Within FC4, you can download Red Hat Package Managers (RPMs) and install whatever software you need.

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:

  1. 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.

  2. Build your code, and run the LSB appchk tool to scan your binary for symbols that are not expressly provided in the LSB specification.

    You can also use the beta version of the new LSB archk tool to scan your static archives for suitability for use in an LSB-compliant application.

  3. If appchk 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.

  4. 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.)

  5. If your code builds successfully within the LSB Build Environment, run the code in the LSB Sample Implementation.
  6. If your target Linux system is LSB compliant, run your code on that system.
  7. 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 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, convert the RPMs to DEB format, which is suitable for Debian's dpkg package manager:


1 $ sudo apt-get install wget

2 $ wget http://ftp.freestandards.org/pub/lsb/\
test_suites/released-3.0.0/binary/application/\
lsb-appchk-3.0.3-1.i486.rpm

3 $ wget http://ftp.freestandards.org/pub/lsb/\
test_suites/released-3.0.0/binary/application/\
lsb-pkgchk-3.0.3-1.i486.rpm

4 $ wget http://ftp.freestandards.org/pub/lsb/\
lsbdev/released-3.0.0/binary/ia32/\
lsb-build-base-3.0.3-1.i486.rpm

5 $ wget http://ftp.freestandards.org/pub/lsb/\
lsbdev/released-3.0.0/binary/ia32/\
lsb-build-c++-3.0.3-1.i486.rpm

6 $ wget http://ftp.freestandards.org/pub/lsb/\
lsbdev/released-3.0.0/binary/ia32/\
lsb-build-cc-3.0.3-1.i486.rpm

7 $ sudo apt-get install alien
8 $ alien *.rpm
9 $ ls -t -1
lsb-pkgchk_3.0.3-2_i386.deb
lsb-build-cc_3.0.3-2_i386.deb
lsb-build-c++_3.0.3-2_i386.deb
lsb-build-base_3.0.3-2_i386.deb
lsb-appchk_3.0.3-2_i386.deb
lsb-pkgchk-3.0.3-1.i486.rpm
lsb-appchk-3.0.3-1.i486.rpm
lsb-build-c++-3.0.3-1.i486.rpm
lsb-build-cc-3.0.3-1.i486.rpm
lsb-build-base-3.0.3-1.i486.rpm
10 $ sudo dpkg --install *.deb
11 $ ls /opt/lsb
bin  doc  man
12 $ ls /opt/lsb/bin
lsbappchk  lsbc++  lsbcc  lsbpkgchk

Command 1 installs wget if it isn't already available on the system. Commands 2-6 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-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 CNU 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 7 installs alien, a utility that can convert RPMs to Debian DEB packages (among other features). Command 8 runs alien; command 9 shows the results; and command 10 installs all the software into the /opt/lsb/ directory, as shown in commands 11 and 12.

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 <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 echo.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
Checking binary echoargs
Incorrect program interpreter: /lib/ld-linux.so.2
Header[ 1] PT_INTERP       Failed
Found wrong interpreter in .interp section: /lib/ld-linux.so.2 instead of: /lib/ld-lsb.so.3

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
Checking binary lsb-echoargs

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
-bash: no such file or directory: ./lsb-echoargs

Unfortunately, the example system, Debian Sarge, is not LSB V3.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.


Listing 2. A snippet of a PCRE application



#include <pcre.h>
..

int main()
{
  pcre *re;
  const char *error;
  int erroffset;

  ...
  
  re = pcre_compile("^[A-Z]", 0, &error, &erroffset, NULL);

  ...
}

Assuming that LD_LIBRARY_PATH includes /usr/local/lib, you can build the code with the command cc -o pcre pcre.c -l pcre.. Checking the code with lsb-appchk produces an additional error message:

$ cc -o pcre pcre.c -l pcre
$ /opt/lsb/bin/lsbappchk pcre
Incorrect program interpreter: /lib/ld-linux.so.2
Header[ 1] PT_INTERP       Failed
Found wrong interpreter in .interp section: /lib/ld-linux.so.2 instead of: /lib/ld-lsb.so.3
DT_NEEDED: libpcre.so.0 is used, but not part of the LSB
Symbol pcre_compile used, but not part of LSB_Core 

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.

Interestingly, the same command using lsbcc does not generate errors:

$ /opt/lsb/binlsbcc -o pcre pcre.c -l pcre
$ /opt/lsb/bin/lsbappchk pcre
Checking binary a.out
$ nm a.out | grep pcre
0809b680 R _pcre_OP_lengths
0809b900 R _pcre_default_tables
0809b6d4 R _pcre_utf8_table1
0809b6ec R _pcre_utf8_table1_size
0809b6f0 R _pcre_utf8_table2
0809b708 R _pcre_utf8_table3
0809b720 R _pcre_utf8_table4
0809b760 R _pcre_utt
0809b888 R _pcre_utt_size
080b385c B pcre_callout
0804b0a0 T pcre_compile
0804b0e0 T pcre_compile2
080b18e4 D pcre_free
080b18e0 D pcre_malloc
080b18ec D pcre_stack_free
080b18e8 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 is superior. The next section demonstrates how to install and use the LSB Build Environment.

 

Installing the LSB Build Environment and Sample Implementation

Note: The rest of this tutorial uses the virtual FC4 instance running in VMWare Workstation. If you previously suspended the FC4 VM or quit VMWare Workstation, resume the FC4 VM or re-launch VMWare Workstation and start the FC4 instance. When the instance is running, log in as root.

The LSB chroot Build Environment lets you build your application in a box, or a specific, well-controlled, isolated environment. You download the chroot Build Environment, install it, and then expand the Build Environment with whatever utilities, libraries, and sources you need to build your application. Once configured, you use the chroot command to change the effective root filesystem to the Build Environment, which ensures that no files except those found in the Build Environment root are visible.

 

Download and install the chroot Build Environment

You can download the version 3.0.0 Build Environment from the LSB download page . The chroot Build Environment is distributed as two RPMs.

At the root prompt, create a temporary directory. Use cd to go to that directory, and then run the following commands (wget is already available in the FC4 VM that you installed; long lines have been continued over multiple lines using the backslash to meet production requirements):

$ wget http://ftp.freestandards.org/pub/lsb\
/lsbdev/released-3.0.0/binary/ia32/\
lsb-buildenv-3.0.2-1.i486.rpm

$ rpm -i lsb-buildenv-3.0.2-1.i486.rpm

Installing the RPM yields a new directory, /opt/lsb-buildenv-ia32/. Its contents should look familiar:

bin  boot  dev  etc  home  lib  media  mnt  
opt  proc  root  sbin  srv  tmp  usr  var

To use the directory as an isolated environment, run chroot /opt/lsb-buildenv-ia32 /bin/bash. You should be prompted with a new shell prompt, bash-3.00#. If you navigate around the file system, the only files visible are those in /opt/lsb-buildenv-ia32/, now the effective /, or top-level directory.

For now, press Ctrl+D to exit the chroot and return to the FC4 VM. Now, you'll install the LSB Sample Implementation, and then finish the tutorial by building and running code in the Build Environment and Sample Implementation, respectively.

Download and install the chroot LSB Sample Implementation

The Sample Implementation is distributed as a base tarball and an (optional) add-on tarball that has several test tools. (You can also download the Sample Implementation as a user-mode Linux binary, if you prefer that format.)

To begin the installation of the Sample Implementation, choose a location for the Sample Implementation within FC4. The /opt folder is a common choice. Next, create a temporary directory, and download and unpack the tarballs:

 1 $ mkdir /tmp/tgz; cd /tmp/tgz

 2 $ wget http://ftp.freestandards.org/pub/lsb/\
impl/released-3.0.0/binary/ia32/lsbsi-boot-ia32-3.0.1.tar.gz

 3 $ wget http://ftp.freestandards.org/pub/lsb/\
impl/released-3.0.0/binary/ia32/lsbsi-core-ia32-3.0.1.tar.gz

 4 $ wget http://ftp.freestandards.org/pub/lsb/\
impl/released-3.0.0/binary/ia32/lsbsi-graphics-ia32-3.0.1.tar.gz

 5 $ wget http://ftp.freestandards.org/pub/lsb/\
impl/released-3.0.0/binary/ia32/lsbsi-test-ia32-3.0.1.tar.gz

 6 $ cd /opt
 7 $ tar xzvf /tmp/tgz/lsbsi-core-ia32-3.0.1.tar.gz

 8 $ cd /opt/lsbsi-core-ia32
 9 $ tar xzvf /tmp/tgz/lsbsi-lsbsi-graphics-ia32-3.0.1.tar.gz
10 $ tar xzvf /tmp/tgz/lsbsi-boot-ia32-3.0.1.tar.gz
11 $ tar xzvf /tmp/tgz/lsbsi-test-ia32-3.0.1.tar.gz

Command 1 creates a directory for the interim files. Commands 2-5 download the pieces of the LSB Sample Implementation:

  • Lsbsi-boot is a bootable system, including a kernel and other pieces of software to allow you to boot the Sample Implementation in stand-alone mode (if you want to).
  • Lsbsi-core is a basic run time that contains only those features spelled out in the LSB specification. You can use lsbsi-core to chroot and enter a virtual, LSB-compliant environment.
  • Lsbsi-graphics provides libraries to create graphical applications inside the Sample Implementation. As shown in [section2.html#fig1 Figure 1] at the start of this article, these libraries include functions for X and OpenGL drawing, among others.
  • Lsbsi-test adds additional software to make the Sample Implementation a suitable testing environment.

Commands 6-11 extract the tarballs into /opt, creating the directory /opt/lsbsi-ia32. Do not skip command 8; lsbsi-lsbsi-graphics-ia32-3.0.1.tar.gz, lsbsi-boot-ia32-3.0.1.tar.gz, and lsbsi-test-ia32-3.0.1.tar.gz must be extracted into /opt/lsbsi-core-ia32.

Like the Build Environment above, after you extract all the Sample Implementation, you can use chroot to get to it. Run the command chroot /opt/lsbsi-core-ia32 /bin/bash. To exit the chroot environment, press Ctrl+D at the new shell prompt.

 

Building and executing code in the Build Environment and the Sample Implementation

Build the simple code of Listing 1 within the Build Environment and run it within the Sample Implementation.

Copy files into the Build Environment

Within your FC4 VM, you now have three environments: the FC4 environment, the Build Environment, and the Sample Implementation. For convenience and clarity, create three working directories and set three environment variables to make copying files between them a snap:

$ FC4=/tmp/work
$ BE=/opt/lsb-buildenv-ia32/tmp/work
$ SI=/opt/lsb-core-ia32/tmp/work
$ mkdir $FC4 $BE $SI

The $FC4 directory is the working directory for downloading source code and keeping interim files as needed. For example, you can download the LSB-compliant binary created with the LSB Build Environment utilities to $FC4, and then copy them to the $SI directory to determine whether they run in LSB V3.0.0. (Everything should work perfectly.) the $BE directory is the directory for source code that you want to build with the chroot Build Environment. The $BE directory is available as /tmp/work after you run chroot /opt/lsbsi-buildenv-ia32 /bin/bash. Similarly, the $SI directory is the drop for binaries built in the Build Environment that you want to run in the Sample Implementation. The $SI directory is available as /tmp/work after you run chroot /opt/lsbsi-core-ia32 /bin/bash.

So, to build Listing 1 in the chroot Build Environment and test it in the chroot Sample Implementation, you download the code to the FC4 environment, and then run the following sequence (the prefixes in the command-line prompt were added for clarity):

(fc4) $ cd $FC4
(fc4) $ wget ftp://.../echoargs.c 
(fc4) $ cp echoargs.c $BE
(fc4) $ chroot /opt/lsbsi-buildenv-ia32 /bin/bash
(be)  $ cd /tmp/work 
(be)  $ cc -o echoargs echoargs.c
(be)  $ ./echoargs hello there
hello there
(be)  $ Control-D
(fc4) $ cp $BE/echoargs $SI
(fc4) $ chroot /opt/lsbsi-core-ia32 /bin/bash
(si)  $ cd /tmp/work
(si)  $ ./echoargs hello there
hello there
(si)  $ Control-D
(fc4) $ echo $FC4
/tmp/work

By the way, because FC4 is LSB V3.0.0-compliant, the binary you created in the Build Environment runs fine in FC4:

(fc4) $ cp $BE/echoargs $FC4
(fc4) $ cd $FC4
(fc4) $ ./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 V3.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.

The LSB provides backward compatibility at both the source and binary level beginning with LSB 3.0. In other words, applications that target version X.Y of the LSB (where X.Y >= 3.0) will run on distributions certified to or compliant with LSB version X.Y and newer. For example, applications that target LSB 3.0 will run not only on LSB 3.0 certified/compliant distributions but also LSB 3.1, LSB 3.2, LSB 4.0 etc. certified/compliant distributions.

To achieve backward compatibility, each subsequent version is purely additive--in other words, interfaces are only added, not removed (our interface deprecation policy does provide us with a mechanism for removing interfaces, but only after the interfaces have been marked "deprecated" for at least three major versions, or roughly six years).

This policy allows application vendors to certify to the version of the LSB that provides the interfaces they need and not require them to recertify to newer versions unless the newer versions provide functionality the applications require.

Please note that the application compatibility policy has changed with LSB 3.0: previously, in LSB 1.x and 2.x, binary compatibility was only provided within a major version--now application compatibility is provided between major versions.

 

Copyright © 2008 Linux Foundation. All rights reserved.
LSB is a trademark of the Linux Foundation. Linux is a registered trademark of Linus Torvalds