* '''autotools.class''': Provides an additional unified logic framework for a package that use Autotools, the GNU Build System. For most applications, no further action or customization should be required other than adding this file as an include on the package's Makefile file, such as in the case seen above.

+

* '''autotools.class''': Provides an additional unified logic framework for a package that use Autotools, the GNU Build System. For most existing autotools based applications, no further action or customization should be required other than adding this file as an include on the package's Makefile file, such as in the case seen above. See later section if you want to create an autotools based application or library from scratch.

For applications that make no use of autotools but rather employ different build methods or systems, other unified logic framework files are available to be included in the same way as the autotools.class file seen above, such as cmake.class or qt.class. For these particular cases read their respective sections.

For applications that make no use of autotools but rather employ different build methods or systems, other unified logic framework files are available to be included in the same way as the autotools.class file seen above, such as cmake.class or qt.class. For these particular cases read their respective sections.

Linux Application Development

This section targets software developers with a little background on Linux software development, presenting some basic concepts about Linux applications that may be unfamiliar to developers with experience in real time operating systems (RTOS).

Linux application development is more like standard PC application development and less like RTOS focused development. The main differences is the clear separation between the applications and the operating system and also that applications are stored on a file system.

This section doesn't replace a good book on Linux/Unix software development, but introduces the minimal concepts that will be useful when porting applications.

Kernel and User Space

Linux is a multi-tasking operating system with protection between executing processes.Therefore applications run in their own address-space which is provided by the kernel using the hardware memory management unit (MMU).

Since applications are separate from the kernel, they live on some file system, therefore Linux needs a least one file system holding the initial applications: the root file system.

The File System

Linux file system is based on Unix file system concepts, and therefore it is composed of a tree of files that are located on some physical storage. The physical storage should provide the root of the tree (the root file system) and other devices can be “mounted” at directories in the file system tree.

Following the Unix mindset, most of the computer universe is represented like a file: files are data containers for more than binary executable files or raw data stored on memory devices, files are also used to represent device drivers, interprocess pipes, or system status.

Unix file system layout is also important, as there are standard locations for configuration files, shared libraries, binaries, shared data, etc.

Pseudo file systems

Linux has several pseudo file systems that when mounted don't reflect actual stored files on some memory device, but file handlers that can provide information about the system, a process, a driver, etc. This pseudo file systems generate the file entries and contents dynamically, based on the system status.

The two more common pseudo-file systems are procfs, and sysfs. More information on these can be found on the next section.

Linux File System Layout

Understanding the Linux file system layout is important for the porting process. The following table explains what's the purpose of the most common locations and should provide a guideline on where to store the contents of your application.

Location

Propose

/bin

Intended for executable binaries required for the basic system.

/sbin

Intended for executable binaries required for the basic system that should be available only to the super (root) user.

/lib

Shared libraries for the basic system.

/etc

Text configuration files of the basic system.

/tmp

Temporary files: on most embedded systems this directory contents are lost between power cycles.

This is the typical mount point of Linux's pseudo file system procfs, which creates a set of files that contain different aspects of the running system, processes, drivers, etc.

/sys

This is the typical mount point of Linux's pseudo file system sysfs, which provides information on, and control of, devices drivers and kernel objects.

/opt

Intended for applications that don't form part of the standard system provided by the vendor. These are usually third-party applications. Most of the applications at this location don't conform to the bin/lib separation of the Unix file systems.

/usr/bin

Intended for executable binaries that are not required for the basic system.

/usr/sbin

Intended for executable binaries that are not required for the basic system that should be available only to the super user.

/usr/lib

Shared libraries not required for the basic system.

Embedded Linux File System

The standard Linux file system is designed for use by more than one person at a time. This is rarely the case on an embedded device, so the difference between /bin, /sbin, /usr/bin, /usr/sbin, /opt may seem less useful than for standard desktop computing purposes.

However one of the important uses of this separation is that it simplifies the final layout of the file systems used by the embedded target. RidgeRun applies the following rules to decide where to locate the applications:

/bin, /sbin: minimal binaries to boot the system

/usr/bin, /usr/sbin: standard Linux applications that are not required to boot the system

/opt: customer applications

This layout allows for different mount points to be used for the /usr and /opt directories which in turn allows:

Creating smaller minimal root file system to speed up booting (depends on the file system technology used), or using a read only file system.

Simplifying software upgrades

Security analysis is simplified if suspect activities are limited to a small part of the file system.

Embedded target file system

RidgeRun SDK creates the target file system on the Linux host machine, and processes it to create the proper target file system image to be downloaded (if required) to the embedded system. The file system of the target system is found under the base (referred to as $DEVDIR) of your SDK: $(DEVDIR)/fs/fs.

This directory only exists after the SDK has been built for the first time, and files can be copied to this location to include them in the target file system image.

Since the file system of the target should have a minimal footprint, the SDK only puts the strictly necessary parts of the applications into this directory, leaving out some run-time unnecessary parts of many programs like include files, manual and info pages, unused localizations, etc. However some of these files (like the includes) may be required during the compilation process for other programs. For this propose the SDK provides the directory $DEVDIR/fs/fsdev, which is the typical installation point of most applications (including all the unnecessary run-time files), and later the application scripts copy the minimal parts from $(DEVDIR)/fs/fsdev to $(DEVDIR)/fs/fs . More information on this procedure will be explained later on this document.

SDK build system

Building software for embedded systems is a complex task as it typically involves cross-compiling. Cross compiling presents new challenges to already established procedures for building software. The RidgeRun SDK uses a build system that simplifies the complexities of cross compiling.

The SDK build system was designed by embedded Linux programmers for embedded Linux programmers, therefore it not only simplifies the process of building embedded Linux applications, but the process of integrating, using or developing open source tools or packages with the SDK.

Introduction to RidgeRun SDK build system

Embedded Linux software development differs in various ways from the two environments it mixes: “embedded” and “Linux”.

Embedded Linux differs from most embedded environments using an RTOS in that Linux uses a file system outside the kernel, and advanced software tools like dynamic loaded libraries, multiple applications, dynamic modules, powerful networking tools and high modularity are supported.

An often overlook but crucial difference between Linux and other RTOS systems has to do with the dynamics of building and integrating open source software. Open source software is build by different communities around the world, and a typical embedded Linux system will include pieces from hundreds of developers and several different open source projects. This factor impacts various processes: system integration, application building, bug reporting, etc.RidgeRun support services minimizes this complexity by providing a single point to get access to embedded Linux support experts, but also by accounting this factor on the design of the build system.

Embedded Linux also differs from standard Linux distributions in its requirements for custom tailored kernel, drivers, and file system. Embedded limitations on footprint, power consumption and processing power create a big gap between embedded and desktop Linux systems.

All the previously mentioned details need to be taken into account by the development procedures for building and packaging the software for embedded Linux. We found three different approaches from SDK providers to build the system (with RidgeRun using the last option):

Binary software distributions: some embedded Linux providers ship the file system applications pre-compiled for the target hardware. This approach provides the advantage that the overhead and work to recompile the basic system is avoided, however also presents several disadvantages:

Minimal footprint is not achieved as the system is often compiled with broader-audience by including generic features.

The packages may have been compiled with or without features required by the customer, therefore requiring the re-compilation of certain packages.

Incompatibility of binary code with other software provided by third parties (For example if the object files uses different ABIs).

In some cases getting the proper code that matches the binary files may be challenging for debugging or tracing proposes.

The binary-oriented design usually lacks proper support to simplify building code from source.

Source software distributions by emulation: some embedded Linux providers use a source building based system that is compiled by running a virtual machine emulating the target hardware and using the compiler natively on the emulated target. This approach has valuable advantages:

Avoids the complexities of cross compiling: open source tools like autotools are in better position to properly evaluate the environment, and several other tricks required for cross compiling are not required.

Allows building optimized code for the target hardware.

Allows creating optimized footprint and features on the compiled software.

Permits testing on the emulated environment.

The disadvantages of this system are:

Overhead on setup, maintenance and build time due the simulated environment. On big systems the compilation delays my be noticeable.

Development files that are not required will be included on the target file system.

Building and maintaining an accurate emulation environment is complex and time consuming.

Source software distributions by cross compilation: consists on building the applications from source for the target hardware from the host target. The advantages are:

Allows building optimized code for the target hardware.

Allows creating optimized footprint and features on the compiled software.

Compilation and build time are typically fast as the host machine is usually more powerful than the target.

The disadvantages of this system are:

Requires special procedures and manual tweaking when cross-compiling complex applications; for example open source software using autotools requires special steps, since many run time detections can't be performed while cross compiling.

Dependency handling between open source packages require special tools.

RidgeRun SDK build system is a source distribution built using cross compilation, and has minimized the complexities of it by defining a centralized system to simplify tool usage, the setting of compilation flags, dependency handling and minimizing host tools requirements.

SDK build tools

The SDK build system is based on a set of technologies commonly found on standard Linux developer machines:

A extended Linux kernel “kconfig” style system, along with custom logic in makefiles, is used to integrate the bootloader, kernel, file sytem and toolchain build and configuration system.

The SDK detects and installs host tools required to build the bootloader, kernel, and Linux libraries and applications.

The set of tools were selected are generally available on most systems, and can be extended to integrate with more sophisticated IDEs like Eclipse, or can be used standalone.

The SDK requires a Linux host machine for development, RidgeRun recommends Ubuntu. Please consult the SDK User Guide or RidgeRun support for the latest information on supported distributions.

Anatomy of a build system

An embedded Linux build system can be analyzed by how well it supports the requirements and the components used to meet those requirements. The RidgeRun SDK build system is composed by:

Centralized configuration system: a single system where the user can control the features and components of the software to be build.

Centralized build system: a single system that is responsible for building the software according to the configuration files generated by the configuration tool.

Application build tools: a set of tools and guidelines that provided support for target applications build process (as described in this document), such:

Application locations

Standard targets for the Makefiles

How to define dependencies, or provide dependency information

How to provide global definitions for other the applications

How to discover global definitions from other applications

How to define host applications requirements

SDK Build system basics

The SDK build system needs to be understood to easily integrate new applications and port existing applications.

Configuration system

The SDK uses a dynamic configuration utility, called kconfig, which is shared by other important projects of the open source community, for example the Linux Kernel and the busybox set of tools.

The kconfig system used by RidgeRun differs from standard versions:

Customized for SDK usage (file names and menus).

The search path for the configuration files has base directories, supporting then integration of the kernel and busybox configurations in a single configuration tool.

Supports extra logic in the SDK makefiles to permit dynamic additions to the menu based on external conditions. For example, when a new application is added to the system it is include in the menus without any programming effort.

The build system provides a way to add menus to the configuration system and associate that value to a variable that can later be accessed by the Makefiles to effect decisions or translate it as a compile definition. For example the definition:

config FS_APPS_MYAPP
bool “myapp”

will create a definition:

CONFIG_FS_APPS_MYAPP=y

if selected as true on the configuration system. Note that the suffix “CONFIG_” was added to the variable name. Those definitions can be used by the Makefiles by including the file $DEVDIR/bsp/mach/Make.conf

For more information on the syntax of the configuration files used by the kconfig system and the different options please consult $DEVDIR/bsp/bspc/kconfig-language.txt.

Build stages

The SDK build system builds difference components and this order may be important when building software that relays on other definitions or libraries. The SDK build order is:

kernel: compiled and kernel images are generated.

fs: built and file system images are generated.

bootloader: built and the bootloader images are generated. In addition repacking of the fs and kernel images into the native format of the bootloader (for example .rr images for rrload or .uImage for u-boot) is performed.

The applications from the file system are separated in different directories, and are build in the following order:

fs/apps: consists mostly of architecture independent programs.

fs/arch: contains programs that are common between all the systems within this hardware family. For example, this directory contains all the generic code for DaVinci processors in DM6446 SDK.

fs/mach: contains the specific code for the target hardware (the “machine” specific code).

fs/proprietary_src: is an optional build stage, if some third party proprietary binary code is included with the SDK, then this code is built at this point.

fs/myapps: is the stage where the customer applications stored in the $DEVDIR/myapps directory are built.

The order in which the directories are built inside the specific fs stages defaults to alphabetically sorted directory names. If some application requires a dependent code to be build first, the order can be changed by using the metainfo system explained later on this document.

Makefile integration with the configuration system

The different makefiles of the system can be integrated with the configuration system by including a couple of files providing:

Definitions matching the selected configuration of the SDK.

Toolchain definitions and flags.

Information regarding other applications or libraries of the system that your application may want to use.

All three are described in detail throughout the rest of this document.

Integrating applications in the SDK

Customers are encouraged to create their applications in the $DEVDIR/myapps directory. Use of the other file system build points is not recommended. For example if you want to create a newapp application, you should proceed to create a directory $DEVDIR/myapps/newapp/.

Your application needs some elements in order for the application to be compiled by the SDK:

Config file: this an file integrating your application with the SDK configuratio system.

Makefile file: this is a set of rules to build/install your application.

metainfo file: this is an optional file that may be used to report dependencies of your application on the target machine (some library you require to be installed) or the host machine (if you need certain tool on the host to compile the application).

In this section we will guide you through the process of creating these files for the newapp application. It is recommended that you read the SDK User Guide before reading this section, and also have used and familiarized yourself with the SDK.

Application installation process overview

In order to understand the application installation process that occurs before one is finally compiled and stored in the target file system, it's good to have a grasp on some of the directories found within the "fs" directory on the development directory (devdir) that's being worked on.

Application installation process overview.

fs/

fs-dev/: This is the local directory where the raw output of all applications to be installed into the target ends up after going through the installation process described in the "apps" directory for a particular application. This includes documentation, libraries, binaries, and everything produced by the installation process.

apps/: This is the local directory where the fetching, compilation, configuration and other processes for all applications intended to be cross-compiled for the target are described. The raw output of these processes is stored at the fs-dev directory (1).

host-apps/: This is the local directory where the fetching, compilation, configuration and other processes for all applications intended for the host system are described. This might be necessary in case an application intended to be cross-compiled for the target system requires the host system to have a particular library or package. The raw output of these processes is stored in the bsp/local directory, which is referenced through the rrsdk.class include file, which will be referenced later (3).

fs/: The target's file system. Through the makefile syntax, which will be expanded upon later, whatever should be ultimately stored in the target's filesystem from the output stored in the fs-dev directory is specified and sent to the appropriate directory here once installation has been completed (2).

bsp/

local/: This directory contains the raw output of the installation processes for applications specified through the fs/host-apps directory. As mentioned before, these are packages that for some reason require to be present in the host system.

Integration with the configuration system (Or: The "config" file)

To integrate your application with the configuration system you have to create a file named Config in the application directory. This file contains logic to select if your application should be built within the SDK. A simple example file is:

In addition, you can use the Config file to force the selection of other configuration options on the SDK (kernel features, libraries, etc). To do this all you need to do is to get the string of the definition you want to enable and add a select statement for it (shown later).

For example, if your application requires zlib (an open source application for compression) then you may use the following code to force incluing of zlib if your application is selected:

The name of the zlib configuration variable may be queried using the “help” of the feature in the configuration menu system. For example the help of “File System Configuration -> Select target's file system software -> SDK Applications -> zlib 1.2.3” says CONFIG_FS_APPS_ZLIB (just strip the prefix CONFIG_).

For further information about the syntax of this file check $DEVDIR/bsp/bspc/kconfig-language.txt. You can look at other Config files in the SDK to find one that is similar to your needs and use it as your starting point.

Once the Config file is created, you can run the “make config” target on your system to enable the the new application to be built and installed in the target file system. A screen will appear as follow:

Creating your application Makefile

The RidgeRun SDK provides an unified method for handling the creation of the "Makefile" file that must be present in an application's directory in order to be built. This unified method works for a majority of cases and will simplify the process of creating the installation description files needed for its completion, avoiding, for example, having to manually specify the targets required to build, clean and configure packages. However, be aware that some applications might not be entirely compatible with it in which case it also supports customizing the internals of this automated system. It's recommended you read the following sections in order to determine whether any customization apart from the default file layout might be required.

Unified Makefile file layout

As an example, the following is the Makefile file for the expat-2.0.1 package that can be found at the "fs/apps/expat-2.0.1" on a standard DM368's development directory. Although the Makefile file layout isn't particularly static, as looking through other application's Makefile files will make evident, it does introduce the basic conventions and rules it employs, and any further in-depth documentation on its specifics can be explored by checking the RidgeRun SDK's internal API Documentation.

As it can be seen from the above file, although some customizations are necessary for the package, most actual logic is defined within the "rrsdk.class" and "autotools.class" files, both found over at the "bsp/classes/" directory within the devdir. Following is a short description of both, although it's recommended to check the RidgeRun SDK's internal API Documentation for an in-depth explanation.

autotools.class: Provides an additional unified logic framework for a package that use Autotools, the GNU Build System. For most existing autotools based applications, no further action or customization should be required other than adding this file as an include on the package's Makefile file, such as in the case seen above. See later section if you want to create an autotools based application or library from scratch.

For applications that make no use of autotools but rather employ different build methods or systems, other unified logic framework files are available to be included in the same way as the autotools.class file seen above, such as cmake.class or qt.class. For these particular cases read their respective sections.

rrsdk.class

This helper class provides the unified logic framework for a package's installation procedure by the SDK, such as is the case for libraries, binaries and additional initial scripts. For most applications, no further action or customization should be required other than adding this file as an include on the package's Makefile file, such as in the case seen above.

Expanding upon these class files, if modifications to this logic are required (in the case that the logic the .class files employ do not fit a particular package's requirements) an "equivalent" .def file that provides definitions required to be fulfilled by the logic can be included in its place and the logic may be manually specified immediately after, on the same Makefile file. Minor modifications such as the post-installation fix seen in the example above can also be added in a similar manner.

Depending on the class files included, additional optional or obligatory variables can or must be specified, such as is the case in the example above, which employs generic and basic options enabled through the rrsdk.class:

LIBRARIES= /usr/lib/libexpat.so.1.5.2

This defines that particular file's final destination (if any) on the target filesystem. As it possibly can be also inferred, these mostly either set application-specific settings depending on the fetching and build methods, or generic settings that refer to the final layout of the build process output on the target's filesystem. In some exceptional cases, some of which will be reviewed in sections below, additional variables might be required. An in-depth look into all of these variables and their function can be consulted the RidgeRun SDK's internal API Documentation.

It's desirable, in addition to the above, to include this file, as well as any other enabled class file (such as autotools.class, as seen in the example) after everything else in the Makefile file, due to the lazy evaluation nature of Makefile definitions which allow for variable expansion only when these are actually needed and not merely when they're referred to.

In addition to the above considerations, it's of importance to notice the package description section of the Makefile file, which is as follows:

This section, desirably located as a sort of header for the Makefile file, corresponds to functionality provided by the rrsdk.class helper file through the fetcher.class file it in turn implements and provides support for handling the fetching and checking of the source for a package that is to be installed and might not be present on the system. Variables that must be set here are pretty straightforward, however, again, largely depend on a particular case's requirements. The default fetching method is http, however support for ftp, git and svn is available through the PKG_TYPE and PKG_REVISION variables (the second in the case of git or svn). In case the source code is stored locally the fetching process can also be bypassed, by using the FETCHER_NO_DOWNLOAD variable. For more information on these particular variables, check the RidgeRun SDK's internal API Documentation.

Makefile targets

The top makefile of any application needs to define a standard set of targets to respond to. In an application Makefile all the following targets must be defined (note that these are defined automatically when including the appropriate .class file such as autotools.class as in the example above, and are noted here only as a reference):

build: builds the software.

install: installs the software.

clean: cleans the built software.

The following correspond to optional targets, that might be required depending on the application.

sim: if this application supports being built for simulated execution on the host target. Simulated execution is a complex way of saying 'not cross compiled'. For example, if your application is graphical and depends on QT, a simulated build would allow the application to run on the desktop PC using the desktop PC's QT library.

preconfig: this target is called before invoking the configuration system and allows the application to dynamically generate their Config files to be used in the system menu. Is unlikely that any application use this option, so you may leave it empty.

The extras-overlay directory

The previously mentioned mechanism allows for specifying what files should be located and where within the target's file system, from those that were generated by the output of the installation processes that was described through the Makefile file, as described above. However, in some cases it might be necessary for additional files that aren't produced through the installation process to be placed somewhere on the target's filesystem, such as additional configuration files.

For this reason, the same unified system described above introduces the extras-overlay directory functionality; in the case that an application requires any extra content to be added to the target's filesystem, it will, after installation, automatically detect the existence of an "extras-overlay" directory placed in the application's directory (the same directory where the Makefile, metainfo and config files are located) and copy anything stored there into the target's filesystem root (located in the fs/fs/ directory on the devdir, as described previously). So, for example, if a configuration file has to be placed on the target's /etc/app/ directory, place the configuration file in the /devdir/fs/fs/my-apps/app/extras-overlay/etc/app/ directory.

Handling dependencies: using metainfo

Most open source application developers create their software in a modular design so it can be reused by other people or projects. This is the reason you can find an endless list of required components to build your applications or components that you need to port to the SDK in order to make the port you are most interested in to work.This job requires the SDK build system be capable of handling dependencies between the different components at compile time, providing the following services to the components:

Capability to report where header files are installed so other components can use them.

Capability to report where shared libraries are installed (if they exists) so other components can link against them.

Capability to report which other components it depends on, so the other components can be built before this component.

Capability to report required host tools to build, so the SDK may validate the tool is available or report an early error on the missing piece.

The SDK build system provides the above functionality with an optional metainfo file in the application directory. Before the development of the metainfo system, many separated techniques were used to accomplish the same goals, they will be documented along the new procedure, but are considered deprecated.

Exploring the metainfo file

Let's suppose we are adding an application named newapp-1.0 to the SDK. We will assume that newapp-1.0 requires of the library libapp-1.0 to be build, and requires the open source program flex to be executed on the host during the compilation.

This applications will appear in its own directory, under $DEVDIR/myapps/, with the following structure:

$DEVDIR/fs/myapps/

libapp-1.0

Config

Makefile

metainfo

source code...

newapp-1.0

Config

Makefile

metainfo

source code...

Previous sections dealt with the Config and Makefile files; in this section the metainfo file will be explored.

Our first step will be to modify the Config file of newapp-1.0 to add a line after the definition of the menu for newapp:

config USER_APPS_NEWAPP
select USER_APPS_LIBAPP

in order to notify the SDK configuration system that in case newapp-1.0 is selected, then libapp-1.0 should be enabled too. We will notify that libapp-1.0 needs to be built before newapp-1.0 later on the metainfo file.

Now we will define the metainfo file for libapp-1.0 (and we will elaborate on it during the next sections):

In the above lines, the NAME identifier is used to prefix the definitions that will be available in the $DEVDIR/fs/Apps.defs repository file.

Each one of the identifiers prefixed with DEFS_ represents a path to a specific component of the application, and they will appear in the $DEVDIR/fs/Apps.defs repository file when they need to be used by other applications. The DEFS_ prefix will be substituted with the content of the NAME identifier. In this way, each definition will be associated in a unique way with their correspondent application package. It is important that each application holds a unique NAME identifier.

Also, note that the DEFS_ strings includes the $(FSDEVROOT) substring, meaning that the headers and libraries are to be found on the /usr path of the file system for development.

Accordingly, the metainfo script will generate the definitions and the final output will appear in the $DEVDIR/fs/Apps.defs repository file looking like the following code block:

Now the Makefile of newapp-1.0 can include $(DEVDIR)/fs/Apps.defs and use the definitions to notify the compiler and linker about the proper location of headers and libraries of libapp-1.0.

Note: the previous SDK build system used an Apps.defs file for each application that included the required definitions just like the previous code block. The usage of those individual Apps.defs files are now deprecated. If the metainfo system founds both an Apps.defs and metainfo files in an application directory, the contents of the Apps.defs file will be used and those from the metainfo file will be discarded.

Detailing software dependencies

When a target application requires the availability of another specific target application or library, the dependency must be included in the TARGET_REQUIRED line. In our example, we found this line of the metainfo file of newapp-1.0:

TARGET_REQUIRED="libapp-1.0"

The identifier representing each application is just the name of the required application's directory as found in the upper level directory of the application metainfo file requesting it. This identifier may be a white space separated list of directories.

The SDK build system will build those applications before the application that requires them, in order to comply with the requirement, in turn, if any required library or application holds other dependencies, they will be built before it and so on recursively.

Note: the previous SDK build systems, there was a file named dependencies that included each directory name in its own line. If a dependencies file exists, it will take precedence over the metainfo file.

Detailing Software dependencies on host hardware =

In the metainfo file, the line with the identifier HOST_REQUIRED provides a white space separated list of the host system packages that should be installed. In our example newapp-1.0 requires flex to properly build.

HOST_REQUIRED="flex"

This will instruct the SDK build system to verify if the host Linux distribution has installed the proper software package that provides the requested tool. Since the SDK is designed to run on different Linux distributions, there is a dictionary to translate between the program name and the package that should be queried for the particular distribution.

If you are using the SDK in a supported distribution and machine you can skip this step and just manually go ahead and verify the package is installed on your machine. However if you intend to re-distribute, or re-install the SDK on different machines, you are better adding the host tool check.

There are various text database files, which are checked in an order so that if a package is listed among a higher-priority list, it will be used rather than one that may be listed within a low-priority one. This is made in order to check if the SDK has a local copy of the package instead of using a generic one provided by the distribution that the host system is using. The order of this search is as follows:

Local SDK database

Distribution-specific database

Non-specific distribution common database

The text database files for each distribution are located in $DEVDIR/bsp/oscheck/, and have been named with the format of distribution-version_architecturebits, such as ubuntu-6.06_32.

In those files there are defined a list of pairs, in the format <alias>:<package_name>. Example:

automake:automake1.9
flex:flex
glade2:libglade2-dev

That is, each line contains an alias or symbolic identifier, a colon, and the name of the package in the host system distribution according to the package management tool used. The SDK has building support for querying the distribution package management tool.

Other helper functions of the metainfo file

The metainfo files can be used to support other more obscure operations.

Build detection: the SDK only tries to build applications that are enabled on the configuration system. To determine which applications are enabled, the SDK build system looks for the first config entry on the Config file of the application directory. However if an application has more than one config entry on that file, the heuristic may fail to determinate correctly if the application must be build or not. To solve this problem you can add the following line to the metainfo file:

CONFIG=USER_APPS_MYAPP.

Where the “USER_APPS_MYAPP” definition corresponds to the config flag that should be used to detect if the application is enabled or not.

Porting autotools based applications

One of the main reasons for using embedded Linux is the vast amount of open source libraries and programs available. RidgeRun has simplified the process of porting open source applications into the SDK.

Most open source applications available use what is known as the GNU build system, also called autotools. For more information on autotools, the following introductory documentation is recommended: http://www.lrde.epita.fr/~adl/dl/autotools.pdf .

Autotools generates scripts that in turn detect if the needed components are available in the build environment. For the SDK, that includes both the host components (toolchain, make, autoconf, shell scripts) and the target components (any library required to be available in the embedded target).

Most open source applications follow a basic three step build process based on autotools using
the following order:
1. configure: Checks for required host and target components and the build system capabilities.
2. make: Builds the applications.
3. make install: Install the application in the target path.

Before getting into details of porting autotools based applications, please be sure that you have read and understood the section Integrating applications in the SDK.

Wrapper Makefile

Elaborating further on how to port applications by using the unified Makefile file layout described previously in this article (make sure to read it before continuing), the example presented in that section constitutes an example of how it should be done for an application that uses the GNU Build System. This makefile will compile and install the application under $(FSDEVROOT) which usually is set to $(DEVDIR)/fs/fsdev. The purpose of this directory is to fully install the autotools based application there using the application install target and later to copy the minimal required files to the target file system on $(FSROOT). This is performed in this way since often the install target will add several MB of files that are not required for run-time execution (headers, localizations, manuals, etc), making the target file system bigger, as describe in a section above.

As seen and explained above, the autotools.class file provides various parameters that may be set according to a specific application's needs:

AUTOTOOLS_PARAMS: is a variable that can be set to any list of parameters you may want to pass to the invocation of the configure script.

AUTOTOOLS_SRC_DIR: is the relative path from the makefile location to the directory containing the autotools based application source code. If this variable is not set by default “src” is used.This means that you should put the source code of the application under a directory named src. For example, if you are porting an application like bash, you will put the wrapper makefile at $DEVDIR/myapps/bash/Makefile, and the source code of bash at $DEVDIR/myapps/bash/src.

Exceptions

It should be noted that not all autotools based applications will compile without problems by using the autotools.class file, and there are certain cases that are know to be specially problematic, specially because of the prefix variable:

Applications that use plugins (like DirectFB, gstreamer, tslib, etc): this type of applications often embeds the directory path to look for the plugins in the binaries, and the cross-compilation process will end wiring the path based on the host machine, not the target file system. This is because these plugins often require the --prefix variable to be set to the host's /usr/ directory. Solving this problem depends on the specific application. Three kinds of files may be affected by this issue: .la files, package configuration (.pc) files and those that end with other suffixes.

Handling .la and .pc files: These are handled easily enough by using the DESTDIR variable in conjunction with the AUTOTOOLS_CORRECT_LA and AUTOTOOLS_CORRECT_PKGCONFIG variables, all of them supported by the autotools.class file, with which the affected files can be listed and which the automated process will use to correct the file's location so that no issue occurs. An example in which this occurs is shown below:

Handling files with variable suffixes: This represents a slightly more difficult issue, however it's still solvable through setting a post-installation fix in the Makefile file that applies a similar fix as the other cases but through pattern matching using regular expressions to describe the target files. As an example, ncurses-5.7 implements this method:

As it can be appreciated, a sed script is set up to replace the wrongly wired addresses with the correct prefix for the ncurses5-config file. The syntax used here is "install::" and is documented through the makefile documents in the following way:

Double-colon rules are explicit rules written with ‘::’ instead of ‘:’ after the target names. They are handled differently from ordinary rules when the same target appears in more than one rule. Pattern rules with double-colons have an entirely different meaning (see Match-Anything Rules).

When a target appears in multiple rules, all the rules must be the same type: all ordinary, or all double-colon. If they are double-colon, each of them is independent of the others. Each double-colon rule's recipe is executed if the target is older than any prerequisites of that rule. If there are no prerequisites for that rule, its recipe is always executed (even if the target already exists). This can result in executing none, any, or all of the double-colon rules.

Double-colon rules with the same target are in fact completely separate from one another. Each double-colon rule is processed individually, just as rules with different targets are processed.

Porting cmake based applications

CMake is a unified, cross-platform, open-source build system that enables developers to build, test and package software by specifying build parameters in simple, portable text files. It works in a compiler-independent manner and the build process works in conjunction with native build environments

In the specific case of porting applications that support cmake instead of autotools, the method is quite straightforward and similar to all previous examples. The cmake.class file is included instead of the autotools.class files as it's done in the previous examples, and in a similar fashion to previous examples, various parameters can be set, such as CMAKE_PARAMS in the following example (which corresponds to the OpenCV-2.1.0 package).

As a warning, the cmake subsystem makes the assumption that the script is compliant with cmake standard variables such as CMAKE_SRC_DIR and uses them accordingly. If for some reason the script subverts conventions such as this, the automated class system may not work at all. For details on which variables are used during compilation, check the API reference guide.

Porting Qt based applications

Qt is a cross-platform application framework that is widely used for developing application software with a graphical user interface (GUI) (in which cases Qt is referred to as a widget toolkit), and also used for developing non-GUI programs such as command-line tools and consoles for servers.

Porting a Qt application, much like porting one that uses CMake, isn't far off what's been shown so far. An example is shown below ("hello-qt", taken from the myapps directory):

#$L$
# Copyright (C) 2011 Ridgerun (http://www.ridgerun.com).
#$L$
# We don't have to fetch the source code, is local
FETCHER_NO_DOWNLOAD=yes
BINARIES=/usr/bin/qthello
include ../../bsp/classes/rrsdk.class
include $(CLASSES)/qt.class

It should be noted that no packages are to be downloaded in this case, therefor the FETCHER_NO_DOWNLOAD is set to "yes", and the usual PKG_URL and other variables don't require to be set.

As a warning, the qt automated subsystem, as with cmake, makes the assumption that the script is compliant with qt standard variables such as QT_SRC_DIR and uses them accordingly. If for some reason the script subverts conventions such as this, the automated class system may not work at all. For details on which variables are used during compilation, check the API reference guide.

Qt applications and touch screens

Several environment variables are used by tslib the touch screen library. The touch screen needs to be calibrated before it is usable. The following is a script fragment that will give you an idea of how to setup your environment before invoking your Qt application.