make all
For clarity, we define the following terms, which will be used throughout this document:
The DAT group periodically announces the distribution of the Cluster Computing Toolkit in a well-known location. (Confluence, probably).
A DAT distribution consists of the following parts:
Typically, the build tools and the RTEMS distribution are tightly coupled: patches to the build tools are dependent on the RTEMS version and RTEMS is built using the tools. The DAT Core distribution is then dependent on both. In addition, the DAT build system uses advanced features from GNU make
, and requires a gmake
version higher than 3.80. (To check yours, type make --version
at your command line. Default for RHEL4 is 3.80, RHEL5 is 3.81.)
Users of the DAT code will install all three distributions and then compile and link against them. Developers of the DAT Core codebase will work against the RTEMS and the build tool distributions.
Information on building RTEMS and the build tools can be found here.
Need to formalize release and distribution process on that page. (2011/03/24) |
The DAT development environment is documented here. Several environment variables are defined by the setup, but the one used by the build system is
The core DAT codebase is held in a subversion repository on SLAC AFS: SVNROOT = file
:///afs/slac/g/cci/repositories/ctkrepo
. Each project in the repository is laid out in the format
project_A/ trunk/ branches/ tags/ project_B/ ... |
where the trunk is the main line of development (roughly equivalent to the CVS HEAD), tags contains various milestones and branches contains development forks. More information on subversion is found at subversion.tigris.org and in the book Version Control with Subversion. More information on the repository is here.
To start development on the DAT core, the developer first checks out a copy of the workspace directory from $SVNROOT/workspace/trunk
or from the specific release tag they need to work with. The workspace contains only the toplevel Makefile
, the core build system (make/
), core header files (datCode.hh, bldInfo.h, bldInfo.hh
) and examples of the makefile fragments packages.mk
and compilation.mk
. Now, check out the core projects listed on the repository page and type make all
at the command line.
The makefile fragments workspace/projects.mk
and workspace/compilation.mk
control compilation and development in your workspace.
projects.mk
simply determines which projects will be compiled.
# List of projects (low level first) projects := configuration projects += oldPpi projects += ppi projects += service projects += platform projects += tool projects += bootstrap |
compilation.mk
is more interesting: it determines what platforms is compiled.
# Platforms platforms := i386-linux platforms += ppc-rtems-rce405 # Compilation switches codetypes := # clear the name, just in case codetypes += opt # turn on optimization compilation (opt only) codetypes += dbg # turn on debug compilation (debug only) #codetypes += plain # just compile it verbose := false # Turn off verbose messages |
With the fragments typing make all
will build four targets: i386-linux-dbg
, i386-linux-opt
, ppc-rtems-rce405-dbg
and ppc-rtems-rce405-opt
. As of 2012/05, the valid platforms are all listed under workspace/make/sw/flags.mk:
All the variables may be overridden from the command line.
make all verbose=true codetypes=plain |
The directories directly under the workspace are called projects. The level under your project is called a package. The base setup for both is similar, starting with template files located in the make/
directory in the workspace.
To create a new software project in the workspace:
workspace/make/share/Makefile.project.template
workspace/make/sw/flags.mk.template
workspace/make/share/packages.mk.template
Makefile.project.template
to Makefile
packages.mk.template
to packages.mk
flags.mk.template
to flags.mk
workspace/projects.mk
file and add a use
statement in the versions section.Your project is now ready, and it is time to add packages.
To create a new software package in a project:
workspace/make/sw/Makefile.package.template
workspace/make/constituents.mk.template
project/packages.mk
fileYour package is now ready, time to add code constituents.
The workspace also contains rules and scripts for building firmware under |
Controlling the compilation of code files is the job of the constituents.mk
file, created from the template in the previous section. As an example, here is a hypothetical package that sets up a module to be run under RTEMS, plus a test executable for Linux. (Makefile fragments are suppressed at each level.)
workspace/ myProject/ myPackage/ foo.hh bar.hh src/ afile.cc gen2/ gen2code.cc bfile.cc test/ testMyModule.cc i86-linux/ testLinux.cc |
A valid constituents.mk
file for the above package could look like this:
modlibnames := myModule libsrcs_myModule := src/afile.cc libsrcs_myModule += src/bfile.cc ifeq ($(tgt_board),rce440) libsrcs_myModule += src/gen2/gen2code.cc endif ifeq ($(tgt_os),rtems) modnames := testMyModule branch_testMyModule := test majorv_testMyModule := 1 minorv_testMyModule := 7 modsrcs_testMyModule := test/testMyModule.cc modlibs_testMyModule := myProject/myModule endif ifeq ($(tgt_os),linux) tgtnames := testMyModule tgtsrcs_testMyModule := test/i86-linux/testLinux.cc tgtlibs_testMyModule := myProject/myModule tgtslib_testMyModule := /usr/lib/rt endif |
The constituents file is broken into logical pieces:
The linked libraries, executables, documentation and public header files are deliverables for the DAT group, and thus must be able to be released to external users such as ATLAS or LSST. The following steps are required to make a release of DAT:
svn cp $SVNROOT/rce/trunk $SVNROOT/rce/tags/TAGNAME
make all
make install
install/
directory under workspace
make install DESTDIR=/foo/bar/baz
The created directory will contain the following files and directories:
Once we have a release generated, we can package and place it in our "well known location". (Packaging at this point consists of generating a tarball of the release.)
In order to standardize the DAT codebase, the DAT group has adopted several coding and structural conventions:
README
files where appropriate
libfoo.so
files is verboten.)constituents.mk
First off, we define several symbols usable by make
for conditional compilation, as well as parallel symbols for C and C++.
In a package's constituents.mk
we have four categories of items to be built: modules, module libraries, static libraries, and targets. The variables for specifying the items to be built are:
Variable |
Description |
Usage Example |
---|---|---|
modnames |
name of relocatable module to be built |
modnames := testMyModule |
modlibnames |
Name of an "internal" library to build; the resulting library is suitable for linking into a module at build time. |
modlibnames := myModule |
libnames |
Name of an "external" library to build; the resulting library is not suitable to link to a module at build time. |
libnames := myLib |
tgtnames |
name of an executable to be built |
tgtnames := testMyTarget |
For modules, there are make variables that control compilation and output. These are keyed on the entries in modnames
. The items built will follow the form <modname>.<majorv>.<minorv>.<branch>.so.
Variable |
Description |
Mandatory? |
Usage Example |
---|---|---|---|
modsrcs_<modname> |
Source files from which the module is built. |
Yes |
modsrcs_testMyModule := test/test.cc |
majorv_<modname> |
Major version number. Forms part of the .so name. |
Yes |
majorv_testMyModule := 1 |
minorv_<modname> |
Minor version number. Forms part of the .so name. |
Yes |
minorv_testMyModule := 7 |
branch_<modname> |
Branch Identifier. Forms part of the .so name. |
Yes |
branch_testMyModule := test |
modincs_<modname> |
Include directories for headers inside your workspace |
No |
modincs_testMyModule := foo/bar |
modsinc_<modname> |
Include directories for headers outside your workspace. |
No |
modsinc_testMyModule := /usr/include/foo/bar |
modlibs_<modname> |
Internal libraries to be linked to the target module at build time. |
No |
modlibs_testMyModule := rce/service |
modrlib_<modname> |
External release libraries to be linked to the target module at build time. |
No |
modrlib_testMyModule := quarks/quarks |
modslib_<modname> |
External system libraries to be linked to the target module at build time. |
No |
modslib_testMyModule := /usr/lib/rt |
modsneeded_<modname> |
Indirect dependencies the module may have on other modules at runtime, which the dynamic linker cannot infer from the code. |
No |
modsneeded_testMyModule := rceapp/core.2.0.devel |
For targets, the make variables are keyed on tgtnames
:
Variable |
Description |
Mandatory? |
Usage Example |
---|---|---|---|
tgtsrcs_<tgtname> |
Source files from which the target is built. |
Yes |
tgtsrcs_testMyModule := test/test.cc |
tgtlibs_<tgtname> |
Internal static or shared libraries to be linked to the target at build time. |
No |
tgtlibs_testMyModule := rce/shell |
tgtrlib_<tgtname> |
External release libraries to be linked. |
No |
tgtrlibs_testMyModule := quarks/quarks |
tgtslib_<tgtname> |
External system or 3rd party libraries to be linked at build time. |
No |
tgtslib_testMyModule := /usr/lib/foo |
For module and static libraries, the make variables are keyed on either modlibnames
or libnames
, and have the same syntax:
Variable |
Description |
Mandatory? |
Usage Example |
---|---|---|---|
libsrcs_<libname> |
Source files from which the library is built |
Yes |
libsrcs_myModule := src/afile.cc |
liblibs_<modname> |
Internal libraries to be linked to the target library at build time. |
No |
liblibs_testMyModule := rce/service |
librlib_<modname> |
External release libraries to be linked to the target library at build time. |
No |
librlib_testMyModule := quarks/quarks |
libslib_<modname> |
External system libraries to be linked to the target library at build time. |
No |
libslib_testMyModule := /usr/lib/rt |
make
and C/C++category |
make syntax |
C syntax |
Valid entries |
---|---|---|---|
CPU family |
ifeq ($(tgt_cpu_family),ppc) |
#ifdef tgt_cpu_family_ppc |
i386, x86_64, sparc |
Operating system |
ifeq ($(tgt_os),linux) |
#ifdef tgt_os_linux |
linux, rtems, solaris |
Board |
ifeq ($(tgt_board,rce405) |
#ifdef tgt_board_rce405 |
rce405, rce440, "" |
Optimization/Debug |
ifeq ($(tgt_opt),dbg) |
#ifdef tgt_opt_dbg |
opt, dbg, "" |
setup.{sh,csh
} files mentioned above for more information. This isn't actually true, gnu is a softlink to /reg/g/common...Checkout top level release
directory (svn co $SVNROOT/release/trunk release
) and cd
into it.
This directory contains the Makefile infrastructure.
Checkout the core of the RCE system:
svn co ${SVNROOT}/rce/trunk rce svn co ${SVNROOT}/rceusr/trunk rceusr svn co ${SVNROOT}/rceapp/trunk rceapp |
The ideas behind these three projects are as follows:
rce/
provides common infrastructure that should be re-usable for all software that runs on the RCE. It is like a C++ extension of the RTEMS BSP (e.g. network, thread wrappers, ethernet/PGP PIC drivers).There are several files of importance to building executables:
toplevel/projects.mk
contains the list of projects that will be builttoplevel/compilation.mk
contains the compilation settingstoplevel/project/packages.mk
contains the list of the project packages that will be built.toplevel/project/package/constituents.mk
contains the detailed build instructions for each package.toplevel/make/sw
swig
, you would add the line include $(RELEASE_DIR)/make/sw/python.mk
to toplevel/project/package/Makefile
toplevel/make
.To build, we use the GNU make supplied with RedHat. The Makefile system provides several default architectures, the purpose of which should be self-explanatory:
Appending -opt
to the architecture name will build optimized, and -dbg
will build with debugging information.
There is at least one command line tag we can supply to make which provides more information: make <target> verbose=y
will display all commands used to build, rather than just progress messages.
The make commands can be issued at the top level to build the specified architecture for all projects in the release, at the project level to build all packages for that project or at the package level to build one package only. Note that:
gmake rceapp.console.ppc-rtems-rce405 |
and
cd rceapp/console gmake ppc-rtems-rce405 |
are equivalent.
Note that we use shared libraries on Linux, but with the much-improved-but-not-perfect $ORIGIN approach for locating shared libraries, so there is no more LD_LIBRARY_PATH or RPATH to worry about.