.. _section-building-source:

Building |me_h| for Common Platforms
====================================

This section describes how to compile |me|, either the Platform Support 
Libraries (PSL) or the full source if available, for an architecture 
supported by RTI (see :ref:`section-platforms` for more information). 

.. Please refer to :ref:`porting` for documentation on how 
   to port |me| to an *unsupported* architecture.

For information about how to compile and link 
|me| applications, please refer to :ref:`section-prepare-development-environment`.

This section is written for developers and engineers with a background in 
software development. RTI recommends reading this section in order, as 
one subsection may refer to or assume knowledge about concepts described in a
preceding subsection. 

.. _section-set-up-build-environment:

Setting up the build 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 will run |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 
....................

|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 <https://cmake.org/>`_ (www.cmake.org) installed. Note that it 
  is not required to use `CMake <https://cmake.org/>`_ to build |me|, and in 
  some cases it may also not be recommended. As a rule of thumb, if |me| can 
  be built from the command-line, `CMake <https://cmake.org/>`_ is recommended. 
- be able to run bash shell scripts (Unix type systems) or BAT scripts 
  (Windows machines).

Supported host environments are Windows (cygwin and mingw are not tested), 
Linux, and macOS systems.

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

The target compiler should:

- be C99 compliant. Note that many non-standard
  compilers work, but may require additional configuration. 
- be C++98 compliant.

The remainder of this manual assumes that the target environment is one 
supported by RTI:

- POSIX (Linux, macOS, QNX®)
- Windows

.. _`psl_compiling`:

Building the PSL
----------------

As described in :ref:`section-libraries`, |me| comes with Platform Support 
Libraries (PSL) that are compatible with specific Platform Independent 
Libraries (PIL). The source code for the PSL is also available in the host 
package. This section describes how to build the PSL from the provided
source code.

RTI provides the PSL source code because it allows the PSL to be recompiled 
for a specific platform configuration. This may be important in some use cases 
if the header files include platform-specific information that is different 
from the binaries provided by RTI.

There are two recommended methods to compile the PSL: by running the rtime-make 
script (which invokes CMake), or by invoking CMake manually. Both are described 
in more detail below. 

`CMake <https://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 does not depend on external tools to build |me|.


Building the PSL with rtime-make
................................

The |me| source bundle includes a bash (UNIX) and BAT (Windows) script to
simplify the invocation of `CMake <https://cmake.org/>`_. These scripts are 
a convenient way to invoke `CMake <https://cmake.org/>`_ with the correct 
options.

.. note::

  rtime-make must be invoked from the RTIMEHOME directory. 


Run the rtime-make script with the following command:

.. tabs::

    .. group-tab:: Linux

        .. code-block:: console

          RTIMEHOME/resource/scripts/rtime-make --config Debug --target x86_64leElfgcc7.3.0-Linux4 \
                                -G "Unix Makefiles" --build

    .. group-tab:: Windows

        .. code-block:: console

          RTIMEHOME\resource\scripts\rtime-make --config Debug --target x86_64lePEvs2017-Win10 \
                            -G "Visual Studio 15 2017" --build

When the compilation has finished, the PSL is copied to the 
directory ``RTIMEHOME/lib/<target>`` where ``<target>`` is the argument passed
to the ``--target <target>``.

  .. warning::
    
    The above command will overwrite the PSL installed by RTI. To use
    a different output directory refer to :ref:`target_name`.

Here is an explanation of each argument in the above command:

- ``--config Debug``: Create Debug build. Use ``--config Release`` to 
  create a release build.
- ``--target <target>``: The target for the sources to be built. Refer to 
  :ref:`rl_supported` for the architecture abbreviations of supported
  platforms.
- ``--build Build``: Build the generated project files.

To get a list of all the options, run:

  .. code-block:: console

    rtime-make -h

To get help for a specific target, run:

  .. code-block:: console

    rtime-make --target <target> --help

.. _`target_name`:

Specifying a different output directory
'''''''''''''''''''''''''''''''''''''''

By default, rtime-make copies the compiled PSL into a directory named 
``RTIMEHOME/lib/<target>`` where ``<target>`` is the argument that was passed
to the ``--target <target>`` option.

To copy the compiled PSL to a different output directory, the 
``--name <name>`` option can be used together with ``--target <target>``. 
In this case, the PSL will be compiled using the same options as
specified for ``--target <target>``, but instead the PSLs will be
copied to the directory ``RTIMEHOME/lib/<name>``. 

.. note::

  You should use the same naming convention for ``--name`` as for
  ``--target``. |me| may use the directory name to determine the 
  appropriate Platform Independent Library (PIL) for the compiled
  PSL.

For example, the following command will compile the PSL using the 
same target configuration as for ``x86_64leElfgcc7.3.0-Linux4``, but copy
the compiled PSL to ``RTIMEHOME/lib/x86_64leElfgcc7.3.0-mypsl``

      .. code-block:: console

        RTIMEHOME/resource/scripts/rtime-make --config Debug \
            --target x86_64leElfgcc7.3.0-Linux4 \
            --name x86_64leElfgcc7.3.0-mypsl \
            -G "Unix Makefiles" --build

Building the PSL with CMake
...........................

.. _`prepare-psl`:

Preparing to build
''''''''''''''''''

RTI recommends creating 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 toolchain files in 
:ref:`xbuild` use the ``<name>`` parameter passed to ``--target <name>``
to determine various compiler options and selections. 

RTI uses the following format for the target architecture PSL:

.. code-block:: none

  {cpu}{compiler}{profile}-{OS}

- ``{cpu}``: the CPU that the library was compiled for.
- ``{compiler}``: the compiler used to build the library.
- ``{profile}``: CERT if the library was built to be Cert-compatible;
  otherwise empty.
- ``{OS}``: The operating system that the PSL was compiled for.

Some examples of target names:

- ``x86_64leElfgcc7.3.0-Linux4``: PSL for |me| for an x64 CPU compiled using 
  GCC 7.3.0 and running a Linux4 kernel.
- ``x86_64lePEvs2017-Win10``: PSL for |me| for an x64 CPU compiled using VS2017
  and running in Windows 10.

Files built by each build configuration will be stored under  
``RTIMEHOME/build/[Debug | Release]/<name>``. 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 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
with the following arguments:


.. note::

  This section assumes that cmake is invoked from the RTIMEHOME directory.

.. code-block:: console

    cmake -G <generator> -DCMAKE_BUILD_TYPE=<Debug | Release> \
          -DCMAKE_TOOLCHAIN_FILE=<toolchain file>  \
          -DCMAKE_MODULE_PATH=RTIMEHOME/resource/cmake/architectures \
          -DRTIME_TARGET_NAME=<target-name> \
          -DRTIME_TARGET=<target-name> \
          RTIMEHOME

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/<target-name>``.

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_<name>``: Builds only the specific library. Note that that dependent
  libraries are built first.
- ``ZERO_CHECK``: Runs `CMake <https://cmake.org/>`_ 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 ``<tool> help`` for a list of available targets to 
build. For example, if UNIX makefiles were generated::

    make help


.. _`source_compiling`:

Building the source
-------------------

.. warning::

  This section only applies to |me| source bundles (``rti_connext_dds_micro-<version>-source.zip``). 
  For other bundles, refer to :ref:`psl_compiling`.

When you build |me| from the source bundle, you have two options:

* Build a Platform Independent Library (PIL) and a compatible Platform Support
  Library (PSL).
* Build an integrated library.

The source code for the PIL, PSL, and integrated libraries are all included in
the source bundle. Refer to :ref:`section-libraries` for more information
on the differences between them. The following sections explain how to compile 
each library type.

There are two recommended methods to compile libraries: by running the 
rtime-make script (which invokes CMake), or by invoking CMake manually. Both 
are described in more detail below. 


Building with rtime-make
........................

The |me| source bundle includes a bash (UNIX) and BAT (Windows) script to
simplify the invocation of `CMake <https://cmake.org/>`_. These scripts are 
a convenient way to invoke `CMake <https://cmake.org/>`_ with the correct 
options.

Run the rtime-make script with the following commands:

.. tabs::

    .. group-tab:: Linux

        To build the PIL:

        .. code-block:: console

          RTIMEHOME/resource/scripts/rtime-make --config Debug --target x86_64leElfgcc7.3.0 \
                                -G "Unix Makefiles" --build

        To build the PSL using the above PIL:

        .. code-block:: console

          RTIMEHOME/resource/scripts/rtime-make --config Debug --target x86_64leElfgcc7.3.0-Linux4 \
                                -G "Unix Makefiles" --build

        To build the integrated library:

        .. code-block:: console

          RTIMEHOME/resource/scripts/rtime-make --config Debug --target x64Linux4gcc7.3.0 \
                                -G "Unix Makefiles" --build

    .. group-tab:: Windows

        To build the PIL:

        .. code-block:: console
          
          RTIMEHOME\resource\scripts\rtime-make --config Debug --target x86_64lePEvs2017 \
                            -G "Visual Studio 15 2017" --build

        To build the PSL using the above PIL:

        .. code-block:: console

          RTIMEHOME\resource\scripts\rtime-make --config Debug --target x86_64lePEvs2017-Win10 \
                            -G "Visual Studio 15 2017" --build

        To build the integrated library:
        
        .. code-block:: console

          RTIMEHOME\resource\scripts\rtime-make --config Debug --target x64Win64VS2017 \
                            -G "Visual Studio 15 2017" --build

Here is an explanation of each argument in the above commands:

- ``--config Debug``: Create Debug build.
- ``--target <target>``: The target for the sources to be built. Refer to 
  :ref:`rl_supported` for the architecture abbreviations of supported
  platforms.
- ``--build Build``: The generated project files.

To get a list of all the options, run:

  .. code-block:: console

    rtime-make -h

To get help for a specific target, run:

  .. code-block:: console

    rtime-make --target <target> --help

Building with CMake
...................

.. _`prepare`:

Preparing to build
''''''''''''''''''

RTI recommendeds creating 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 toolchain files in 
:ref:`xbuild` use the **RTIME_TARGET_NAME** variable to determine various
compiler options and selections. 

RTI uses the following formats for the target architecture libraries:

.. tabs::

    .. group-tab:: PIL

        .. code-block:: none

          {cpu}{compiler}{profile}

        - ``{cpu}``: the CPU that the library was compiled for.
        - ``{compiler}``: the compiler used to build the library.
        - ``{profile}``: CERT if the library was built to be Cert-compatible;
          otherwise empty.

    .. group-tab:: PSL

        .. code-block:: none

          {cpu}{compiler}{profile}-{OS}

        - ``{cpu}``: the CPU that the library was compiled for.
        - ``{compiler}``: the compiler used to build the library.
        - ``{profile}``: CERT if the library was built to be Cert-compatible;
          otherwise empty.
        - ``{OS}``: The operating system that the PSL was compiled for.

    .. group-tab:: Integrated

        .. code-block:: none

          {cpu}{OS}{compiler}{profile}

        - ``{cpu}``: the CPU that the library was compiled for.
        - ``{OS}``: The operating system that the integrated library was compiled for.
        - ``{compiler}``: the compiler used to build the library.
        - ``{profile}``: CERT if the library was built to be Cert-compatible;
          otherwise empty.

Some examples of target names:

- ``x86_64leElfgcc7.3.0``: PIL for |me| for an x64 CPU, running Ubuntu 18.04 LTS
  compiled with gcc 7.3.0.
- ``x86_64leElfgcc7.3.0-Linux4``: PSL for |me| for an x64 CPU, running Ubuntu 18.04 LTS
  compiled with gcc 7.3.0.
- ``x64Linux4gcc7.3.0``: Integrated library for |me| for an x64 CPU, running 
  Ubuntu 18.04 LTS compiled with gcc 7.3.0.
- ``x86_64lePEvs2017``: PIL for |me| for an x64 CPU, running Windows 10 compiled
  with Visual Studio 2017.
- ``x86_64lePEvs2017-Win10``: PSL for |me| for an x64 CPU, running Windows 10 compiled
  with Visual Studio 2017.
- ``x64Win64VS2017``: Integrated library for |me| for an x64 CPU, running Windows
  10 compiled with Visual Studio 2017.

Files built by each build configuration will be stored under  
``RTIMEHOME/build/[Debug | Release]/<name>``. 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 from the command line
''''''''''''''''''''''''''''''''''''''''''

.. note::

  This section assumes that CMake is invoked from the ``RTIMEHOME`` directory.
  For out-of-source builds using CMake, refer to :ref:`out_of_source_cmake`.

Open a terminal window in the ``RTIMEHOME`` directory and create the ``RTIMEBUILD`` 
directory. Change to the ``RTIMEBUILD`` directory and invoke CMake
with the following arguments:

.. code-block:: console

    cmake -G <generator> -DCMAKE_BUILD_TYPE=<Debug | Release> \
          -DCMAKE_TOOLCHAIN_FILE=<toolchain file>  \
          -DCMAKE_MODULE_PATH=RTIMEHOME/resource/cmake/architectures \
          -DRTIME_TARGET_NAME=<target-name> \
          -DRTIME_TARGET=<target-name> \
          RTIMEHOME

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/<name>``.

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_<name>``: Builds only the specific library. Note that that dependent
  libraries are built first.
- ``ZERO_CHECK``: Runs `CMake <https://cmake.org/>`_ 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 ``<tool> help`` for a list of available targets to 
build. For example, if UNIX makefiles were generated::

    make help

.. _`out_of_source_cmake`:

Building with CMake outside of source
'''''''''''''''''''''''''''''''''''''

 .. note::

    This option is only available with the |me| source bundle.

You may need to build |me| in a directory that is located
outside ``RTIMEHOME`` and to install |me| in a separate installation directory.
In this case, do the following:

1. Create a build directory and change the current directory to it.

2. Invoke CMake with the following command to create build files for an
   integrated library:

  .. code-block:: console

      cmake -DCMAKE_TOOLCHAIN_FILE=<RTI toolchain> \
            -DRTIME_TARGET=<target-name> \
            -DRTIME_TARGET_NAME=<target-name> \
            -DCMAKE_BUILD_TYPE=[debug | Release]  \
            <path to RTIMEHOME/CMakeLists.txt>

  Alternatively, you can create build files for split libraries.
  This requires two commands, one for the PIL and one for the PSL. 
  
  To build the PIL:

  .. code-block:: console

      cmake -DCMAKE_TOOLCHAIN_FILE=<RTI toolchain> \
            -DRTIME_TARGET=<target-name> \
            -DRTIME_TARGET_NAME=<target-name> \
            -DCMAKE_BUILD_TYPE=[debug | Release]  \
            <path to RTIMEHOME/CMakeLists.txt>

  To build the PSL:

  .. code-block:: console

      cmake -DCMAKE_TOOLCHAIN_FILE=<RTI toolchain> \
            -DRTIME_TARGET=<target-name> \
            -DRTIME_TARGET_NAME=<target-name> \
            -DCMAKE_BUILD_TYPE=[debug | Release]  \
            -DRTIME_PIL_PATH=<path to  RTI's PIL if compiling a PSL> \
            <path to RTIMEHOME/CMakeLists.txt>

3. Invoke the build tool on the generated build-files:

  .. code-block:: console

      make

4. Install the compiled libraries using ``cmake --install``:

  .. code-block:: console

      cmake --install . --prefix <install path>

The last command will copy the header files and libraries to:

  - ``<install path>/include`` (header files)
  - ``<install path>/lib`` (libraries)


.. _`xbuild`:

Cross-compiling |me_h|
----------------------

Cross-compiling the |me| source-code uses the exact same process described
in :ref:`source_compiling`, but requires an additonal toolchain file. 
A toolchain file is a `CMake <https://cmake.org/>`_ file that describes the compiler, 
linker, etc., needed to build the source for the target. 

To see a list of available targets, use ``--list``:

.. code-block:: console

    rtime-make --list