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