ChorusOS 5.0 Source Delivery Guide

Build Management

This section demonstrates through examples how modifications to different layers of the source code must be accounted for when building a ChorusOS system.

imake or mkmk?

A fundamental strength of the ChorusOS operating system is its portability across a range of target family hardware architectures. The trade-off made to achieve broad portability manifests itself as build management complexity. ChorusOS system builds require powerful tools to generate the necessary Makefiles to render the process more straightforward. These tools, imake and mkmk:

ChorusOS operating system builds involve make for end-result build tasks, and involve imake and mkmk for generating and managing Makefiles inside components. The following tables indicate which standard system components are managed using which Makefile generation tool.

Table 4-1 Components Managed with imake

Component 

Description 

BSP

Bootstrap code 

DRV

Drivers 

EXAMPLES

Example applications 

Table 4-2 Components Managed with mkmk

Component 

Description 

NUCLEUS

Microkernel and related code 

OS

POSIX, file system and networking layers of the operating system 

The rule of thumb for choosing between imake and mkmk is simple: use imake if you can; use mkmk if you must. User-level application components can be handled using imake. Hardware driver components can be handled using imake. Subsystem components -- such as microkernel components and components that modify the POSIX, file system and networking layers of the operating system itself -- might require you to use mkmk.

imake Files

An Imakefile is a machine-independent description of the make targets you want to build. In the first step of the build process, the imake tool generates a Makefile from each Imakefile, by selecting the configuration files with dependencies appropriate to your target system. This has the advantage that the Imakefile is a machine-independent description of the targets you want to build and is thus portable.

If files are altered they must be rebuilt. For the imake tool within the ChorusOS operating system, only dependencies between source and binary files are taken into account when altered files are rebuilt.

imake Rules

ChorusOS--specific imake rules are provided in the imake subdirectory of the install-dir/tools directory, as shown below.


host% cd install_dir/chorus-family/tools/imake
host% ls
Imake.rules     Imake.tmpl      Imake32.rules   Package.rules   Project.tmpl
host% 

Table 4-3 presents each imake file.

Table 4-3 The imake files provided with the ChorusOS System

File 

Description 

imake/Imake.rules

imake rules

imake/Imake32.rules

Provides compatibility with r3.2 imake rules

imake/Imake.tmpl

Template Makefile, for imake

imake/Package.rules

Packaging rules, for imake

imake/Project.tmpl

Empty Project.tmpl

Components managed with imake export their public information through packaging rules based on those found in these files. Examples demonstrating the use of ChorusOS--specific imake rules can be found in the ChorusOS 5.0 Application Developer's Guide. Commercially available books offer extensive explanations of how to use imake to manage portable software.

The imake command uses Project.tmpl and Imakefiles you include in each directory of your component source to generate Makefiles. During builds managed with imake, only dependencies between source and binary files are taken into account.

Table 4-4 ChorusOS imake Targets

iMake Target 

Description 

all (default target)

Builds everything 

clean

Removes generated files recursively 

depend

Generates dependencies recursively 

Makefile

Regenerates the Makefile in the current directory. 

Makefiles

Regenerates Makefiles recursively 

Each file in the tgt-make directory deals with make rules for compiling target binary files. Certain files are specific to the gcc compiler, others to the ghs compiler. Only common and gcc/powerpc specific files are described here. All files listed in Table 4-5 are located in the bin_dir/tools/tgt-make directory:

Table 4-5 Target Rules for ChorusOS

File 

Description 

gcc-devsys.mkmake rules used by the imake environment
gcc-ld.ld Linker script used to reduce the section number
gcc-variables.rf make variables, for the mkmk and imake environments
gcc-tgtdevsys.rfmake rules, for mkmk
variables.rf Includes the compiler specific file about variables
tgtdevsys.rf Includes the compiler specific file about rules
shared.rfCalls mkmake
Makefile.mkimageMakefile used during image creation
Makefile.confMakefile used during configurable actor links
genLinkGeneric linker, calls genLink.conf and genLink.noconf
genLink.conf Links configurable actors
genLink.noconf Links non-configurable actors
mkdbginfo Generates offsets and symbol information
powerpc/genOff Create offset files
powerpc/genOff.awkawk file used by genOff
powerpc/act.ld Linker script used for actors using dynamic libraries
powerpc/lib.ld Linker script used to create dynamic libraries

The mkmk Build Process

The mkmk tool is used to generate Makefiles that let you build a particular target system image from source code that supports multiple target hardware architectures. The mkmk rules allow you to manage system configuration entities such as features, parameters and tunables.

The mkmk build process consists of the following steps:

  1. Merging -- creating links to source files from the build directory; the links enable mkmk to locate source code during builds.

  2. Generating Makefiles in the build subdirectory for the component using mkmk.

  3. Building the object component.

  4. Creating the dependency files for subsequent builds.

  5. Building the system image.

Merging

The role of mkmerge is to link the source files and the component's build directory. For further information, see the mkmerge(1CC) man page.

The code for ChorusOS components containing family-specific code is organized in projected trees. Within the projected trees, there are sub-trees for:

Before generation begins, subtrees are merged into a merged tree. There is only one merged tree in each merged component. Initially, it contains symbolic, or hard, links that point to files in the projected trees. The build takes place in the merged tree, so the projected trees remain free of generated files, such as object files and Makefiles. You can delete a merged tree at any time. This will not affect the source code, as it remains clean in the projected trees.

Different merged trees can be built from a given set of subtrees of the projected trees. This allows you to produce several system configurations concurrently.

Building the merged tree is called the merge operation. When performing this operation, you provide a number of first-level options, called generation options. These options correspond to fundamental production choices, such as the choice of a development system or the target family and are typically found in the build profile.

On systems running the Solaris operating environment, mkmerge populates the merge directory with symbolic links. These links point to the source directories required for your build.

merge.rf

Source directories within the projected tree can be populated with special files, named merge.rf (for merge rule files), which provide a number of directives for mkmerge, for example:

During a merge, directories are examined recursively and merge.rf files are analyzed. If no problems are encountered, the real merge begins: directories, links and files are created as specified in the various merge.rf files found.

A merge.rf file is composed of lines that are evaluated one at a time. A status is associated with this file. This status evolves as the file is analyzed. Depending on its value at the end of the merge.rf file, the current directory will be merged or cut.

A merge.rf file can contain commands to describe how the current directory should be merged, where it will go, and when it will be merged. The MKMERGE_IGNORE environment variable can be used to specify a list of file suffixes that should be ignored during the merge process.

For more information about merge.rf, see the mkmerge(1CC) man page.

Build Profile

The build profile used by the configure command is an argument of the mkmerge command. There is one default profile for each board, as shown in"Families, Targets and Profiles" . For non-standard system generation, customize the build profile using the information on the file entries described here.

The build profile contains entries of the following type:

The range of value values depends on the variable. Note that:

Build profile files provide configuration flags used during the merge. The following listing shows an example microkernel build profile file for UltraSPARCTM family targets.


Example 4-1 UltraSPARCTM Target Profile File

[profile]
FLAG=host=solaris
FLAG=target=upSparc
FLAG=devsys=gcc
FLAG=flm=on
FLAG=locks=rt
FLAG=optim=on
FLAG=tree=upSparc

[profile]
devsys=gcc
binfmt=elf

# directories to merge

tree=./../common
tree=./../sparc
tree=./../sparc_v9
tree=./../usparc
 
# kernel locks configuration :
# 2 choices : locks=rt, locks=gp
locks=rt

# available memory management implementations
flm=on
prm=on
vm=off
 
#
# shared_lib support
# choices : sharedlib=on, sharedlib=off
sharedlib=on

# stack fault support :
# 2 choices : stack_fault_support=on, stack_fault_support=off
stack_fault_support=on

# FPU support :
# 2 choices : fpu_support=on, fpu_support=off
fpu_support=on
 
# optimisation type
# choices : optim=on, optim=no
optim=on

# debug on or off (default)
debug=off
 
# profiling on or off (default)
profile=off

The predefined flags include:

Table 4-6 Configuration Flags

Name 

Possible values 

Description 

debug

(off|on)

Indicates whether to compile with debugging information; default is off

devsys

(gcc)

Indicates which host development tool chain is used for compilation; default is gcc

flm

(off|on)

Indicates whether flat memory is in use. 

prm

(off|on)

Indicates whether protected memory is in use 

vm

(off|on)

Indicates whether virtual memory is in use 

locks

(gp|rt)

Specifies which type of locking to use in the core executive; default is gp

merge_dir

(dir)

Specifies the path to the root of the merge tree 

optim

(off|on|size|speed)

Indicates how to optimize compilation; setting this flag to speed might make symbolic debugging impossible; default is on, a compromise between size and speed optimizations

profile

(off|on)

Indicates whether to compile with performance profiling capabilities; default is off

shared_lib

(off|on)

Shared library support. Default is on.

softload

(off|on)

Library fp emulation. Default is on.

tree

(dir1,dir2,...)

Specifies projected tree directories to merge 

mkmk Files

The mkmk tool uses portable description files, independently of both the host and target systems. High-level mkmk rules are included in .bf, .df and .mf portable description files for a component, and are then processed to create Makefiles and .dp dependency files for the builds.

The mkmk command uses three types of build description files, suffixed by .df, .bf, and .mf, to produce Makefiles and generate all .dp dependencies. With mkmk, you create a .mf file for each host. In this way the mkmk tool ensures portability during cross compilation and so ensures the portability of hosts and targets.

.bf Files

The .bf suffix denotes build file.

The .bf files are a subset of Imakefiles. They contain link directives , and you can have several .bf files per directory. The mkmk tool concatenates the .bf files inside the Makefile product. The .bf file is preprocessed by the macro processor m4(1).

Table 4-7 lists the macros used in a .bf file. The Actor, ConfigurableActor, Library and BigObject macros use getExport, either directly or indirectly, to get the list of object files. The getExport command computes the list of object files to use when creating a link.

Table 4-7 Macros used in .bf Files

Macro 

Description 

Build actor using libs

Build actor using libs

Build lib

Build a relocatable object file 

Copy file into dir

Copy file into dir

Build actor using libs

Build actor using libs

Build lib

Build a relocatable object file 

Copy file into dir

Copy file into dir

Build a pre-built actor and its finalized makefile using libs and local_libs.

.df Files

The .df suffix denotes definitions file.

The .df files are used as shell scripts that are launched when the Makefile is created to adjust variables before they are written into the Makefile. The .df files define the following variables:

The .df files have similar properties to the Project.tmpl files of the imake tool. They affect the building of the Makefiles for all the subdirectories. With mkmk, you can have several .df files in each directory of the source tree. This contrasts with the imake tool, which has only one Project.tmpl file per component.

The inheritance mechanism of the mkmk tool is different from that of the imake tool. With mkmk, every Makefile is dependent on the Makefile present in the parent directory. However, with imake, every Makefile is dependent on the Project.tmpl file present in the top-level directory of the component and on the few variables inherited from the parent directory. The variables and macros are defined in the production tools. Table 4-8 lists those you must not modify and Table 4-9 lists those you can modify.

Table 4-8 Variables for the .df Files that must not Change

Variable 

Description 

DTL(DEVTOOLS_DIR)/host/bin/
GROOT ../../ (the relative path to the root component)
BDIR build_dir
BNAME Name of current directory
HOST Type of host
FAMILY Type of target
COMPILER  Type of compiler

MPATH

Pathname of current directory relative to the component root 

BFILESList of .bf files found in your work directory
MFILESList of .lf and .mf files found in your work directory
DFILESList of .df files in your work directory

Table 4-9 Variables in the .df Files hat can Change

Variable 

Description 

DEFINES List of macro definitions to use in every compilation rule
INCLUDES List of directories to search for header files
VARIABLESThe list of user defined variables to export in Makefiles produced in subdirectories
SUB_DIRS The list of directories to use when compiling; these are usually the subdirectories of your build directory
EXTRA_DIRS A list of directories to use, in addition to SUB_DIRS, when creating libraries or linking actors (usually empty)
MODULES The name of the module to which the object in your build directory (and subdirectories) belong; this is only useful in configurable actors

FARROP

Application profiling 

FEXCEPTION  (ON/OFF): Compile with exception support
FPU  (ON/OFF): Compile with FPU support
FOPTIM  (ON/OFF): Compile with optimization
FPROF  (ON/OFF): Support for profiling
FREMOTEDEB  (ON/OFF): Compile with debug options, to enable source level debugging
FVERBOSE (ON/OFF): Verbose compilations
FWARN(STRICT/ON/OFF): Enable production of warnings during compilation; with STRICT, warnings are treated as errors. The NUCLEUS component uses STRICT

FASSERT

(ON/OFF): Enable or disable assertions 

FGCOV

(ON/OFF): Enable or disable code coverage testing with gcov

FPIC

(ON/OFF): Enable or disable compilation for inclusion in shared libraries 

FVEC

(ON/OFF): Enable or disable generation/build options to use or not use a unit vector 

.mf Files

The .mf suffix denotes make file.

The .mf files contain lists of source files. The .mf files are used during make sources when the binary file to be built uses many subdirectories, each subdirectory containing a variable number of files to be compiled.

Another form of .mf files are .lf files. The variables and macros used in the .mf and .lf files are listed in Table 4-10.

Table 4-10 Variables and Macros used in .mf and .lf Files

Variable 

Description 

C++SRCS  C++ source files
C_SRCS  C source files
AS_SRCS  Assembly code source files
M4_SRCS  M4 source files (assembly code source files preprocessed with m4).
OF_SRCS C++ source files used to produce offset files

The Makefiles Created by the mkmk Tool

During generation, mkmk goes down the build tree and creates a Makefile for each build directory. The Makefiles are used to build the binary files and each of these Makefiles is autonomous. This means that you can set make running from any directory and all files located in the subdirectories attached to that directory are built automatically. The Makefile content depends on the mkmk production files.

In each directory, where mkmk produces a Makefile, mkmk:

The list of files to be compiled varies depending on the merge operation. Writing a Makefile that will work on several configurations can be complicated. The solution offered by mkmk is to:

The .mf files do not have an equivalent within the imake tool.

The mkmk tool will regenerate the Makefile produced if the .df, .bf or .mf files used to build it change.

Managing Dependencies

Once a file has been modified, for example with an editor, or by a previous compilation, the files that depend on the altered file must be rebuilt. Most development tools only deal with the dependencies between source and binary files. The mkmk system goes further, taking into account any changes which occur in the source files during the build process.

The relationship between the different components is managed through the components' Makefile.bin and Makefile.src files and through the build paths found in the Paths file in your ChorusOS build directory. For example, applications can access both the microkernel API and the OS API through the variables set in the Paths file:

Make Targets for mkmk

This section presents the complete list of make targets you can use with the mkmk tool.

Table 4-11 Description of Make Targets used with mkmk

Make Target 

Description 

all  Default make target, builds everything
Makefile Rebuild the Makefile in current directory
makemk Rebuild the Makefiles (recursively)
merge  Remerge the current component
makesrc  Build offset files (recursively)
sources  Build offset files in the current directory
makeprod  Build object files and libraries (recursively)
prod Build object files and libraries in the current directory
makelink Link libraries and actors (recursively)
link  Link libraries and actors in the current directory
depend Generate dependencies (recursively)
cleanRemove files produced (recursively), with the exception of Makefiles and dependency files
clobber Remove files produced (recursively)

Compiling a binary with cdstool

There also exists an alternative to imake, cdstool, which you can use to compile simple binaries. The cdstool utility is a wrapper for the C compiler delivered with the ChorusOS operating system.

#include <stdio.h>
main()
{
		printf("Hello world\n");
}
host% build_dir/bin/cdstool cc example.c -o example

$