.. _section-building-source:
Building the Source for Common Platforms
========================================
Introduction
------------
|rti_me| has been engineered for reasonable portability to common platforms and
environments, such as Darwin, iOS, Linux, and Windows. This section
explains how to build the |me| source-code. The focus of this section is
building |me| for an architecture supported by RTI (please refer to
:ref:`section-platforms` for more information). Please refer to
:ref:`porting` for documentation on how to
port |me| to an *unsupported* architecture.
This section is written for developers and engineers with a background in
software development. We recommend reading this section in order, as
one subsection may refer to or assume knowledge about concepts described in a
preceding subsection.
The Host and Target Environment
-------------------------------
The following terminology is used to refer to the environment in which |me|
is built and run:
- The *host* is the machine that runs the software to compile and
link |me|.
- The *target* is the machine that runs |me|.
- In many cases |me| is built *and* run on the same machine. This
is referred to as a *self-hosted environment*.
The *environment* is the collection of tools, OS, compiler, linker,
hardware etc. needed to build and run applications.
The word *must* describes a requirement that must be met.
Failure to meet a *must* requirement may result in failure to
compile, use or run |me|.
The word *should* describes a requirement that is strongly recommended
to be met. A failure to meet a *should* recommendation may
require modification to how |me| is built, used, or run.
The word *may* is used to describe an optional feature.
The Host Environment
....................
|rti_me| has been designed to be easy to build and to require few tools on
the host.
The host machine **must**:
- support long filenames (8.3 will not work). |me| does not require a
case sensitive file-system.
- have the necessary compiler, linkers, and build-tools installed.
The host machine **should**:
- have `CMake `_ (www.cmake.org) installed. Note that it is not
required to use `CMake `_ to build |me|, and in some cases it may
also not be recommended. As a rule of thumb, if |rti_me| can be built
from the command-line, `CMake `_ is recommended.
- be able to run bash shell scripts (Unix type systems) or BAT scripts
(Windows machines).
Typical examples of host machines are:
- a Linux PC with the GNU tools installed (make, gcc, g++, etc).
- a Mac computer with Xcode and the command-line tools installed.
- a Windows computer with Microsoft Visual Studio Express edition.
- a Linux, Mac or Windows computer with an embedded development tool-suite.
The Target Environment
......................
|me| has been designed to run on a wide variety of targets. For example,
|me| can be ported to run with no OS, an RTOS, GNU libc or a non-standard
C library etc. This section only lists the minimum requirements. Please refer to
:ref:`porting` for how to port |me|.
The target machine must:
- support 8, 16, and 32-bit signed and unsigned integer. Note that a
16 bit CPU (or even 8 bit) is supported as long as the listed types are
supported.
|me| supports 64 bit CPUs, and it does not use any native 64 bit
quantities internally.
The target compiler should:
- have a C compiler that is C99 compliant. Note that many non-standard
compilers work, but may require additional configuration.
- have a C++ compiler that is C++98 compliant.
The remainder of this manual assumes that the target environment is one
supported by RTI:
- POSIX (Linux, Darwin, QNX®, VOS, iOS, Android).
- VxWorks 6.9 or later.
- Windows.
- QNX.
Overview of the |me_h| Source Bundle
------------------------------------
The |me| source is available from the
`RTI support portal `_.
If you do not have access, please contact `RTI Support `_.
The source-code is exactly the same as developed and
tested by RTI. No filtering or modifications are performed, except for
line-ending conversion for the Windows source bundle.
The source-bundle is in a directory called **src/** under your |me| installation.
::
RTIMEHOME--+-- CmakeLists.txt
|
+-- build -- cmake --+-- Debug --+-- --
| |
| |
| +-- Release --+-- --
+-- doc --
|
+-- example
|
+-- include
|
+-- lib +-- --
|
+-- resource --+-- cmake
| |
| +-- scripts
|
+-- rtiddsgen
|
+-- rtiddsmag
|
+-- src
In this section, ``RTIMEHOME`` refers to the root directory where RTI archives are
extracted and installed.
Directory Structure
...................
The recommended directory structure is described below and *should*
be used (1) because:
- the source bundle includes a helper script to run `CMake `_ that
expects this directory structure.
- this directory structure supports multiple architectures.
- this directory structure mirrors the structure shipped by RTI. (2).
NOTE 1: This applies to builds using `CMake `_. To build in a
custom environment, please refer to `Custom Build Environments`_.
NOTE 2: The path to an installation of *rtiddsgen*, likely from a
bundle shipped by RTI, will also have to be specified separately.
CMakeLists.txt is the main input file to `CMake `_ and is used to
generate build files.
The *RTIMEHOME/include* directory contains the public header files.
By default it is identical to *RTIMEHOME/include*. However, custom ports
will typically add files to this directory.
The *RTIMEHOME/src* directory contains the |me| source files.
RTI does not support modifications to these files unless explicitly stated
in the porting guide. A custom port will typically add specific files to
this directory.
The *RTIMEHOME/build* directory is empty by default. `CMake `_
generates one set of build-files for each configuration. A build configuration
can be an architecture, |me| options, language selection, etc. This directory
will contain `CMake `_ generated build-files per architecture
per configuration. By convention the *Debug* directory is used to
generate build-files for debug libraries and the *Release*
directory is used for release libraries.
The *RTIMEHOME/lib* directory is empty by default. All libraries
successfully built with the `CMake `_ generated build-files,
regardless of which generator was used, will be copied to the
*RTIMEHOME/lib* directory.
The following naming conventions are used regardless of the build-tool:
- Static libraries have a *z* suffix.
- Shared libraries do *not* have an additional suffix.
- Debug libraries have a *d* suffix.
- Release libraries do *not* have an additional suffix.
The following libraries are built:
- *rti_me* - the core library, including the DDS C API
- *rti_me_discdpde* - the Dynamic Participant Dynamic Endpoint (DPDE) plugin
- *rti_me_discdpse* - the Dynamic Participant Static Endpoint (DPSE) plugin
- *rti_me_rhsm* - the Reader History plugin
- *rti_me_whsm* - the Writer History plugin
- *rti_me_netioshmem* - the Shared Memory Transport
- *rti_me_netiosdm* - the Zero Copy over shared memory transport library
- *rti_me_appgen* - the Application Generation plugin
- *rti_me_cpp* - the C++ API
To link a C application, the libraries are required in the following order:
#. *rti_me_appgen* (if using the Application Generation plugin)
#. *rti_me_netioshmem* (if using the Shared Memory Transport)
#. *rti_me_netiosdm* (if using the Zero Copy transport)
#. *rti_me_discdpde* (if using DPDE)
#. *rti_me_discdpse* (if using DPSE)
#. *rti_me_rhsm* *rti_me_whsm* *rti_me* (always required)
To link a C++ application, the libraries are required in the following order:
#. *rti_me_appgen* (if using the Application Generation plugin)
#. *rti_me_cpp* *rti_me_netioshmem* *rti_me_netiosdm* *rti_me_discdpde* *rti_me_discdpse* *rti_me_rhsm* *rti_me_whsm* *rti_me* (always required)
.. note::
The names above are the RTI library names. Depending on the
target architecture, the library name is prefixed with *lib*
and the library suffix also varies between target architectures,
such as .so, .dylib, etc.
For example:
- rti_mezd indicates a static debug library
- rti_me indicates a dynamically linked release library
.. _`source_compiling`:
Compiling |me_h|
----------------
This section describes in detail how to compile |me| using `CMake `_.
It starts with an example that uses the included scripts followed
by a section showing how to build manually.
`CMake `_, available from www.cmake.org, is the
preferred tool to build |me| because it simplifies configuring the |me|
build options and generates build files for a variety of environments.
Note that `CMake `_ itself does not compile anything. `CMake `_
is used to *generate* build files for a number of environments,
such as make, Eclipse® CDT, Xcode® and Visual Studio. Once the build-files
have been generated, any of the tools mentioned can be used to build |me|.
This system makes it easier to support building |me| in different build
environments. `CMake `_ is easy to install with pre-built binaries
for common environments and has no dependencies on external tools.
NOTE: It is not required to use `CMake `_. Please refer to
`Custom Build Environments`_ for other ways to build |me|.
Building |me_h| with rtime-make
...............................
The |me| source bundle includes a bash (UNIX) and BAT (Windows) script to
simplify the invocation of `CMake `_. These scripts are
a convenient way to
invoke `CMake `_ with the correct options.
On UNIX-based systems:
::
RTIMEHOME/resource/scripts/rtime-make --config Debug --target x64Linux4gcc7.3.0 \
-G "Unix Makefiles" --build
On Windows systems:
::
RTIMEHOME\resource\scripts\rtime-make --config Debug --target x64Win64VS2017 \
-G "Visual Studio 15 2017" --build
Explanation of arguments:
- ``--config Debug`` : Create Debug build.
- ``--target `` : The target for the sources to be built.
- ``--build Build``: The generated project files.
On UNIX-based systems:
- If gcc is part of the name, GCC is assumed.
- If clang is part of the name, clang is assumed.
On Windows systems:
- If Win32 is part of the name, a 32 bit Windows build is assumed.
- If Win64 is part of the name, a 64 bit Windows build is assumed.
To get a list of all the options::
rtime-make -h
To get help for a specific target::
rtime-make --target --help
Manually Building with CMake
............................
.. _`prepare`:
Preparing for a Build
'''''''''''''''''''''
As mentioned, it is recommended to create a unique directory for each build
configuration. A build configuration can be created to address specific
architectures, compiler settings, or different |me| build options.
RTI recommends assigning a descriptive *name* to each build
configuration, using a common format. While there are no requirements to
the format for functional correctness, the tool-chain files in
:ref:`xbuild` uses the **RTIME_TARGET_NAME** variable to determine various
compiler options and selections.
RTI uses the following name format::
{cpu}{OS}{compiler}_{config}
In order to avoid a naming conflict with RTI, the following name format is
recommended::
{prefix}_{cpu}{OS}{compiler}_{config}
Some examples:
- acme_ppc604FreeRTOSgcc4.6.1 - |me| for a PPC 604 CPU running FreeRTOS
compiled with gcc 4.6.1, compiled by acme.
- acme_i86Win32VS2015 - |me| for an i386 CPU running Windows XP or higher
compiled with Visual Studio 2015, compiled by acme.
- acme_i86Linux4gcc4.4.5_test - a test configuration build of |me| for an
i386 CPU running Linux 3 or higher compiled with gcc 4.4.5, compiled by
acme.
Files built by each build configuration will be stored under
*RTIMEHOME/build/[Debug | Release]/\*. These directories are referred to
as build directories or ``RTIMEBUILD``. The structure of the ``RTIMEBUILD`` depends on
the generated build files and should be regarded as an intermediate directory.
Creating Build Files for |me_h| Using the CMake GUI
'''''''''''''''''''''''''''''''''''''''''''''''''''
Start the `CMake `_ GUI, either from a terminal window or a menu.
Please note that the Cmake GUI does *not* set the **CMAKE_BUILD_TYPE** variable.
This variable is used to determine the names of the |me| libraries. Thus,
it is necessary to add **CMAKE_BUILD_TYPE** manually and specify either Debug
or Release. To add this variable manually, click the 'Add Entry' button,
specify the name as a string type.
As an alternative, rtime-make's ``--gui`` option can be used. This option starts
the `CMake `_ and also adds the **CMAKE_BUILD_TYPE** option when the
`CMake `_ GUI exits.
Please note that when using Visual Studio or Xcode, it is important to build the
same configuration as was specified with rtime-make's ``--config`` option. While
it is possible to build a different configuration from the IDE, selecting
a different configuration does *not* update the build configuration
generated for |me|.
The GUI should be started from the ``RTIMEHOME`` directory. If
this is not the case, check that:
- The source directory is the location of ``RTIMEHOME``.
- The binary directory is the location of ``RTIMEBUILD``.
With the `CMake `_ GUI running:
- Press 'Configure'.
- Select a generator. You must have a compatible tool installed to process the
generated files.
- Select 'Use default native compilers'.
- Press 'Done'.
- Press 'Configure'.
- Check 'Grouped'.
- Expand RTIME and select your build options. All available build options for
|me| are listed here.
- Type a target name for **RTIME_TARGET_NAME**. This should be the same as the
*\* used to create the ``RTIMEBUILD`` directory, that is the ``RTIMEBUILD``
should be on the form *\/\*.
- Press 'Configure'. All red lines should disappear. Due to how `CMake `_
works, it is strongly recommended to always press 'Configure' whenever a value
is changed for a variable. Other variables may depend on the modified variable
and pressing 'Configure' will mark those with a red line. No red lines
means everything has been configured.
- Press 'Generate'. This creates the build-files in the ``RTIMEBUILD`` directory.
Whenever an option is changed and Configure is re-run, press Generate again.
- Exit the GUI.
Depending on the generator, do one of the following:
- For IDE generators (such as Eclipse, Visual Studio, Xcode) open the generated
solution/project files and build the project/solution.
- For command-line tools (such as make, nmake, ninja) change to the
RTIMEBUILD directory and run the build-tool.
After a successful build, the output is placed in RTIMEHOME/lib/\.
The generated build-files may contain different sub-projects that are
specific to the tool. For example, when using Xcode or Visual Studio, the following
targets are available:
- ALL_BUILD - Builds all the projects.
- \rti_me_\ - Builds only the specific library. Note that that dependent
libraries are built first.
- ZERO_CHECK - Runs `CMake `_ to regenerate project files in case something
changed in the build input. This target does not need to be built
manually.
For command-line tools, try `` help`` for a list of available targets to
build. For example, if UNIX makefiles were generated::
make help
Creating Build Files for |me_h| Using CMake from the Command Line
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Open a terminal window in the ``RTIMEHOME`` directory and create the ``RTIMEBUILD``
directory. Change to the ``RTIMEBUILD`` directory and invoke cmake
using the following arguments::
cmake -G -DCMAKE_BUILD_TYPE= \
-DCMAKE_TOOLCHAIN_FILE= \
-DRTIME_TARGET_NAME=
Depending on the generator, do one of the following:
- For IDE generators (such as Eclipse, Visual Studio, Xcode) open the generated
solution/project files and build the project/solution.
- For command-line tools (such as make, nmake, ninja) run the build-tool.
After a successful build, the output is placed in *RTIMEHOME/lib/\*.
The generated build-files may contain different sub-projects that are
specific to the tool. For example, in Xcode and Visual Studio the following
targets are available:
- ALL_BUILD - Builds all the projects.
- \rti_me_\ - Builds only the specific library. Note that that dependent
libraries are built first.
- ZERO_CHECK - Runs `CMake `_ to regenerate project-files in case something
changed in the build input. This target does not need to be built
manually.
For command-line tools, try `` help`` for a list of available targets to
build. For example, if UNIX makefiles were generated::
make help
CMake Flags used by |me_h|
''''''''''''''''''''''''''
The following CMake flags (-D) are understood by |me| and may be useful
when building outside of the source bundle installed by RTI. An example would
be incorporating the |me| source in a project tree and invoking cmake directly
on the CMakeLists.txt provided by |me|.
- ``-DRTIME_TARGET_NAME=\`` - The name of the target (equivalant to ``--target`` to rtime-make).
The default value is the name of the source directory.
- ``-DRTIME_CMAKE_ROOT=\`` - Where to place the CMake build files.
The default value is *\/build/cmake*.
- ``-DRTIME_BUILD_ROOT=\`` - Where to place the intermediate build files.
The default value is *\/build*.
- ``-DRTIME_SYSTEM_FILE=\`` or an empty string - This file can be used to
set the PLATFORM_LIBS variable used by |me| to link with. If an empty
string is specified no system file is loaded. This option may be useful
when cmake can detect all that is needed. The default value
is not defined, which means try to detect the system to build for.
- ``-DRTI_NO_SHARED_LIB=true`` - Do not build shared libraries. The default is undefined,
which means shared libraries are built. NOTE: This flag must be undefined
to build shared libraries. Setting the value to false is not supported.
- ``-DRTI_MANUAL_BUILDID=true`` - Do not automatically generate a build ID.
The default value is undefined, which means generate a new build each time
the libraries are built. Setting the value to false is not supported. The
build ID is in its own source and only forces a recompile of a few files.
Note that it is necessary to generate a build ID at least once (this is done
automatically). Also, a build ID is not supported for cmake versions
less than 2.8.11 because the TIMESTAMP function does not exist.
- ``-DRTIME_DDS_DISABLE_PARTICIPANT_MESSAGE_DATA=false`` Disables P2P Message Data
inter-participant channel. This channel is needed to use **DDS_AUTOMATIC_LIVELINESS_QOS**
and **DDS_MANUAL_BY_PARTICIPANT_LIVELINESS_QOS** with a finite lease duration.
|me_h| Compile Options
----------------------
The |me| source supports compile-time options. These options
are in general used to control:
- Enabling/Disabling features.
- Inclusion/Exclusion of debug information.
- Inclusion/Exclusion of APIs.
- Target platform definitions.
- Target compiler definitions.
NOTE: It is no longer possible to build a single library using `CMake `_.
Please refer to `Custom Build Environments`_ for information on customized builds.
|me_h| Debug Information
........................
Please note that |me| debug information is independent of a debug build
as defined by a compiler. In the context of |me|, debug information refers
to inclusion of:
- Logging of error-codes.
- Tracing of events.
- Precondition checks (argument checking for API functions).
Unless explicitly included/excluded, the following rule is used:
- For CMAKE_BUILD_TYPE = Release, the NDEBUG preprocessor directive is defined.
Defining NDEBUG includes logging, but excludes tracing and precondition checks.
- For CMAKE_BUILD_TYPE = Debug, the NDEBUG preprocessor directive is undefined.
With NDEBUG undefined, logging, tracing and precondition checks are included.
To manually determine the level of debug information, the following options
are available:
- **OSAPI_ENABLE_LOG** (Include/Exclude/Default)
- Include - Include logging.
- Exclude - Exclude logging.
- Default - Include logging based on the default rule.
- **OSAPI_ENABLE_TRACE** (Include/Exclude/Default)
- Include - Include tracing.
- Exclude - Exclude tracing.
- Default - Include tracing based on the default rule.
- **OSAPI_ENABLE_PRECONDITION** (Include/Exclude/Default)
- Include - Include tracing.
- Exclude - Exclude tracing.
- Default - Include precondition checks based on the default rule.
|me_h| Platform Selection
.............................
The |me| build system looks for target platform files in
*RTIMEHOME/include/osapi*. All files that match \*osapi_os_*.h are listed
under **RTIME_OSAPI_PLATFORM**. Thus, if a new port is added it will automatically
be listed and available for selection.
The default behavior, \, is to try to determine the target platform
based on header-files. The following target platforms are known to work:
- Linux (posix)
- VOS (posix)
- QNX (posix)
- Darwin (posix)
- iOS (posix)
- Android (posix)
- Win32 (windows)
- VxWorks 6.9 and later (vxworks)
However, for custom ports this may not work. Instead the appropriate
platform definition file can be selected here.
|me_h| Compiler Selection
.........................
The |me| build system looks for target compiler files in
*RTIMEHOME/include/osapi*. All files that match \*osapi_cc_*.h are listed
under **RTIME_OSAPI_COMPILER**. Thus, if a new compiler definition file
is added it will automatically be listed and available for selection.
The default behavior, \, is to try to determine the target
compiler based on header-files. The following target compilers are known
to work:
- GCC (stdc)
- clang (stdc)
- MSVC (stdc)
However, for others compilers this this may not work. Instead the appropriate
compiler definition file can be selected here.
|me_h| UDP Options
..................
Checking the **RTIME_UDP_ENABLE_IPALIASES** disables filtering out IP aliases.
Note that this currently only works on platforms where each IP alias has
its own interface name, such as eth0:1, eth1:2, etc.
Checking the **RTIME_UDP_ENABLE_TRANSFORMS_DOC** enables UDP transformations in
the UDP transport.
Checking the **RTIME_UDP_EXCLUDE_BUILTIN** excludes the UDP transport from being built.
.. _`xbuild`:
Cross-Compiling |me_h|
----------------------
Cross-compiling the |me| source-code uses the exact same process described
in :ref:`source_compiling`, but requires a additonal *tool-chain file*.
A tool-chain file is a `CMake `_ file that describes the compiler,
linker, etc. needed to build the source for the target. The |me| source bundle
includes a few basic, generic tool-chain files for cross-compilation.
In general it is expected that users will provide their own cross-compilation
tool-chain files.
To see a list of available targets, use ``--list`` :
::
rtime-make --list
By convention, RTI only provides generic tool-chain files that can be used
to build for a broad range of targets. For example, the Linux target can
be used to build for any Linux architecture as long as it is a self-hosted
build. The same is true for Windows and Darwin systems. The VxWorks tool-chain
file uses the Wind River environment variables to select the compiler.
For example, to build on a Linux machine with Kernel 2.6 and gcc 4.7.3::
rtime-make --target x64Linux4gcc7.3.0 --config Debug --build
By convention, a specific name such as i86Linux2.6gcc4.4.5 is expected to
only build for a specific target architecture. Note however that this cannot be
enforced by the script provided by RTI. To create a target specific tool-chain
file, copy the closest matching file and add it to the
*RTIMEHOME/source/Unix/resource/CMake/architectures* or
*RTIMEHOME/source/windows/resource/CMake/architectures* directory.
Once a tool-chain file has been created, or a suitable file has been found,
edit it as needed. Then invoke rtime-make, specifying the new tool-chain
file as the target architecture. For example::
rtime-make --target i86Linux2.6gcc4.4.5 --config Debug --build
Custom Build Environments
-------------------------
The preferred method to build |me| is to use `CMake `_. However,
in some cases it may be more convenient, or even necessary, to use a custom build
environment. For example:
- Embedded systems often have numerous compiler, linker and board specific
options that are easier to manage in a managed build.
- The compiler cannot be invoked outside of the build environment, it may
be an integral part of the development environment.
- Sometimes better optimization may be achieved if all the components of
a project are built together.
- It is easier to port |me|.
Importing the |me_h| Code
.........................
The process for importing the |me| Source Code into a project varies
depending on the development environment. However, in general the following
steps are needed:
- Create a new project or open an existing project.
- Import the entire |me| source tree from the file-system. Note that
some environments let you choose whether to make a copy only link
to the original files.
- Add the following include paths:
- \/include
- \/src/dds_c/domain
- \/src/dds_c/infrastructure
- \/src/dds_c/publication
- \/src/dds_c/subscription
- \/src/dds_c/topic
- \/src/dds_c/type
- Add a compile-time definition ``-DRTIME_TARGET_NAME="target name"``
(note that the \" must be included).
- Add a compile-time definition ``-DNDEBUG`` for a release build.
- Add a compile-time definition of either ``-DRTI_ENDIAN_LITTLE`` for a
little-endian platform or ``-DRTI_ENDIAN_BIG`` for a big-endian platform.
- If custom OSAPI definitions are used, add a compile-time
definition ``-DOSAPI_OS_DEF_H="my_os_file"``.
- If custom compiler definitions are used, add a compile-time
definition ``-DOSAPI_CC_DEF_H="my_cc_file.h"`` .