.. include:: ../vars.rst

.. _chapter-building-apps:

****************************************************************
Building and Running |RTI_SP_PRODUCT_HEADING|-Based Applications
****************************************************************

To use the |RTI_SP_PRODUCT| with your DDS applications:

#. Decide whether to load the |RTI_SP_PRODUCT| statically or dynamically. 
   (See :ref:`p2_core/building_apps:Linking Applications with the |RTI_SP_PRODUCT_HEADING|`.)
#. Configure the |DPs| based on that decision. This includes specifying how
   to load the |RTI_SP_PRODUCT|, by setting the security-related participant properties
   listed in :numref:`Properties for Enabling Security`. The properties you
   have to configure depend on whether you link your libraries statically or
   dynamically. You also need to configure the security artifacts that your
   |DPs| need to communicate securely
   (as specified in :ref:`p1_welcome/using_dds_secure:Using |RTI_SP_PRODUCT_HEADING|`).
#. Link your DDS application against the proper |RTI_SP_PRODUCT| libraries
   (either builtin or custom) and the OpenSSL
   libraries. These libraries will be different for each target architecture.

   The builtin libraries are in the
   :file:`rti_security_plugins-<connext version>-target-openssl-3.5-<target architecture>.rtipkg` bundle; 
   
   There are two types of OpenSSL bundles that you need to install, a host and a target: 
   
   - :file:`openssl-<openssl version>-<connext version>-host-<host platform>.rtipkg` 
   - :file:`openssl-<openssl version>-<connext version>-target-<target architecture>.rtipkg` 
   
   See :link_connext_dds_secure_ig:`Download Instructions
   <#security_plugins/installation_guide/download.html>` in the |SP_IG|.
   Refer to :ref:`p2_core/building_apps:Libraries Required for Using the |SP_BUILTIN_HEADING|` and
   :ref:`p2_core/building_apps:Libraries Required for Using the |LIGHT_SP_BUILTIN_HEADING|` 
   to select the appropriate files for your platform and your chosen library format.

.. note::

  You must set the security-related participant properties before you create a |DP| (see :numref:`Properties for Enabling Security`). You cannot create a |DP| without security and then call ``DomainParticipant::set_qos()`` with security properties, even if the |DP| has not yet been enabled.


.. note::

  You can have secure and unsecure |DPs| in the same DDS application. However, all your |SecDPs| will load the same OpenSSL library with the same configuration (including the same OpenSSL Engines or Providers). If you manually load OpenSSL before creating any participant, your |SecDPs| will reuse that OpenSSL library and its configuration.


Linking Applications with the |RTI_SP_PRODUCT_HEADING|
======================================================

Your application's start sequence will be different depending on whether you use static or dynamic linking. This choice will also have an impact on how you need to configure your application.

:numref:`Properties for Enabling Security` defines the properties that you need to set in your |DP| to load the |RTI_SP_PRODUCT|. Depending on whether you link your libraries statically or dynamically, you need to set different properties to load the |RTI_SP_PRODUCT|. The following sections will guide you through the linking process.

.. figure:: ../static/linking-static-dynamic.png
  :scale: 50%
  :alt: Differences in the Startup Sequence of |RTI_SP_PRODUCT_HEADING| Applications Using Static Linking and Dynamic Linking
  :name: Differences in the Startup Sequence of |RTI_SP_PRODUCT_HEADING| Applications Using Static Linking and Dynamic Linking
  :align: center

  Differences in the Startup Sequence of |RTI_SP_PRODUCT_HEADING| Applications Using Static Linking and Dynamic Linking


.. important::

  Do not mix dynamic and static libraries. See :ref:`p2_core/building_apps:Mixing Libraries Not Supported` for further information.


Dynamic Linking
---------------

.. note::

  For a step-by-step example on dynamic linking, please see the |SP_GSG_LINK|.

When you use dynamic linking, your application loads the |CONNEXT| Core libraries at load time and all the plugins (Transport, Security, Discovery, etc.) at runtime. On Linux systems, for instance, your applications need to link against :file:`libnddsc.so` and :file:`libnddscore.so`. You can link your applications to these libraries with GCC using the following command:

.. code-block:: console

  $ gcc -o myApp myApp.o -L$NDDSHOME/lib/$ARCH -lnddsc -lnddscore

Note that in the above command, no builtin security library is included in
the list of required libraries, because it is dynamically loaded at runtime from the
DomainParticipantQos :property:`com.rti.serv.secure.library` (see
:numref:`Properties for Enabling Security`). Using dynamic linking allows you to
control the loaded libraries from the DomainParticipantQos. For example, if you are
configuring the DomainParticipantQos using XML, the required snippet will look
similar to:

.. code-block:: xml

  <domain_participant_qos>
    <property>
      <value>
        <element>
          <name>com.rti.serv.secure.library</name>
          <value>nddssecurity</value>
        </element>
      </value>
    </property>
  </domain_participant_qos>

This example QoS will make your |DP| load the `nddssecurity` (|SP_BUILTIN|)
library
(:file:`libnddssecurity.so` on Linux systems), which in turn loads the OpenSSL
libraries. Note that the library is loaded on a per |DP| basis. Therefore,
you can have secure and unsecure |DPs| in the same application. Similarly, each
of your |DPs| can load a different set of plugins.

Dynamic loading is particularly useful if, for example, you use your own
security plugins library, because the library can be easily defined at runtime
through the QoS.

This is the initialization sequence of a DDS application using the
|SP_BUILTIN| with dynamic linking:

#. When your application starts, the dynamic loader automatically loads the
   |CONNEXT| libraries (:file:`libnddsc.so`, :file:`libnddscore.so`) from your
   dynamic library search path (``LD_LIBRARY_PATH`` on Linux systems).
#. When the |DP| is created and the QoS is set, the |CONNEXT| Core libraries
   dynamically load the security library (:file:`libnddssecurity.so`) at run
   time. Because the |SP_BUILTIN| library depends on :file:`libnddscore.so`, the dynamic
   loader knows that the library has already been loaded, and it automatically
   resolves the undefined symbols to use the currently loaded library.
#. Since the |SP_BUILTIN| library depends on OpenSSL shared objects, these are
   automatically loaded by the dynamic loader. Therefore, OpenSSL libraries have
   to be accessible from your dynamic library search path (``LD_LIBRARY_PATH``
   on Linux systems).
#. On Linux systems, if you encounter a segmentation fault in
   :file:`libcrypto.so`, you may be dynamically loading the :file:`libcrypto.so`
   from the operating system (possibly in addition to loading the
   :file:`libcrypto.so` from RTI). In that case, set ``LD_PRELOAD`` to the RTI
   :file:`libcrypto.so`. Example:

   .. code-block:: bash

      export LD_PRELOAD=$NDDSHOME/resource/app/lib/x64Linux4gcc8.5.0/libcrypto.so.1.1 $NDDSHOME/bin/rtiadminconsole

.. hint::

  When linking dynamically, the ``%PATH%`` or ``$LD_LIBRARY_PATH`` environment variable must include RTI and OpenSSL DLLs or libraries.


Static Linking
--------------

If you choose to statically link the RTI libraries, the mechanism for dynamically selecting and loading the |RTI_SP_PRODUCT| is no longer available. Compared to dynamic linking, you need to pay attention to two things with static linking.

First, you need to include the chosen |RTI_SP_PRODUCT| library and the OpenSSL dependency libraries in the list of libraries needed during linking:

.. code-block:: console

  $ gcc -o myApp myApp.o -L$NDDSHOME/lib/$ARCH -lnddssecurityz $NDDSHOME/third_party/openssl-<version>/$ARCH/release/lib/libssl.a $NDDSHOME/third_party/openssl-<version>/$ARCH/release/lib/libcrypto.a

.. note::

  For an example of the full linking command see :file:`<path to examples>/connext_dds/c/hello_security`.

Second, you need to manually tell |CONNEXT| the pointer to the function of the entry point of the |RTI_SP_PRODUCT| before you create the |DP|. Setting this pointer requires setting the :property:`com.rti.serv.secure.create_function_ptr` property (see :numref:`Properties for Enabling Security`). Here is an example on how to set this pointer in code:

.. tabs::

  .. group-tab:: C

    .. literalinclude:: ../snippets/building_apps.cpp
      :language: c
      :start-after: Static Linking in C
      :end-before: EOF

  .. group-tab:: C++98

    .. literalinclude:: ../snippets/building_apps.cpp
      :language: c++
      :start-after: Static Linking in C++98
      :end-before: EOF

  .. group-tab:: C++11

    .. literalinclude:: ../snippets/building_apps.cpp
      :language: c++
      :start-after: Static Linking in C++11
      :end-before: EOF

Enabling the |RTI_SP_PRODUCT| in code requires recompiling your application each time you want to enable and disable them.
As an alternative, you can set the function pointer value for :property:`com.rti.serv.secure.create_function_ptr` property in an environment variable that is set programmatically. Hence you can specify the function pointer in an XML file, which allows you to enable and disable the |RTI_SP_PRODUCT| without recompiling.

If you choose to use this method, you have to specify the environment variable from which the pointer will be loaded, as follows:

.. code-block:: xml

    <domain_participant_qos>
      <property>
        <value>
          <element>
            <name>com.rti.serv.load_plugin</name>
            <value>com.rti.serv.secure</value>
          </element>
          <element>
            <name>com.rti.serv.secure.create_function_ptr</name>
            <value>$(RTISECURITYFUNCPTR)</value>
          </element>
        </value>
      </property>
    </domain_participant_qos>

In this example, we will be loading the |SP_BUILTIN|. Therefore, in the DDS
application that links in the |SP_BUILTIN|, we need to get the function pointer
of ``RTI_Security_PluginSuite_create`` and write it to the same environment
variable you named in the XML file (``RTISECURITYFUNCPTR`` in this example).
Be aware that your application must set the environment variable before it
creates the |DP| that loads the QoS Profile using that variable, as shown in the following snippet:

.. literalinclude:: ../snippets/building_apps.cpp
  :language: c
  :start-after: Setting an environment variable in C
  :end-before: EOF

Finally, you have to create a |DP| by using the XML profile where you load the function pointer.

.. caution::

  ``putenv()`` will not export variables from your process to the calling process (e.g., to the shell). Instead, the environment variables set in your process will only apply to your process and child processes of it.
  Therefore, you need to use this function in the same process that links in the |SP_BUILTIN| (or a child process).

This is the initialization sequence of a DDS application using the |RTI_SP_PRODUCT| with static linking:

#. Since your application includes the binary code of the |CONNEXT| libraries,
when it starts, these libraries are copied in the memory space of your application.
#. When the |DP| is created and the QoS is set, the |CONNEXT| Core libraries
initialize the configured security libraries, which are also in the application's memory space along with the OpenSSL library.

.. important::

  If you statically link the |RTI_SP_PRODUCT|, the QoS property
  :property:`com.rti.serv.secure.library` will be silently ignored, if defined.
  With static linking, the |RTI_SP_PRODUCT| are only set at compile time; there is no runtime selection.


Mixing Libraries Not Supported
==============================

You must choose *either* static or dynamic linking. Mixing static and dynamic
RTI libraries —for example, using static |CONNEXT| Core libraries and dynamic
|RTI_SP_PRODUCT| libraries— is not supported.

The examples in this section are for Linux systems, but except for small
differences in names, the same concepts apply to Windows and macOS systems as well.

Suppose you have a |CONNEXT|-based application, :file:`myApp`, and you want to
use the |RTI_SP_PRODUCT| to protect the communication. The library dependency looks something like :numref:`Library Dependency`.

.. figure:: ../static/library-dependency.png
  :scale: 50%
  :alt: Library Dependency
  :name: Library Dependency
  :align: center

  Library Dependency


:numref:`Library Dependency` is a simple and common situation, but make sure
that the |CONNEXT| Core libraries that your application uses are the same kind
of libraries that the |RTI_SP_PRODUCT| uses. For example, if :file:`myApp` links
statically with :file:`nddsc`, but you load :file:`nddssecurity` dynamically,
there will be a mismatch between the libraries, potentially creating a dangerous
situation. In particular, problems may become visible when you enable the |RTI_SP_PRODUCT|
logging distribution (see :ref:`p2_core/logging:Configuring the Logging Distribution`).

You can easily end up in a mixed linking scenario without realizing it.
For example, suppose you design your statically linked application without
security in mind, then add security from the QoS. This scenario is not valid
because when the runtime dynamic loader loads the |RTI_SP_PRODUCT| library, it
also loads a second copy of the |CONNEXT| Core libraries in memory as shown by :numref:`Mixed Library Linking`.

.. figure:: ../static/mixed-libraries.png
  :scale: 50%
  :alt: Mixed Library Linking (Not Supported)
  :name: Mixed Library Linking
  :align: center

  Mixed Library Linking (Not Supported)


If you mix static and dynamic libraries, your application might still work, but **this configuration is not supported and you might end up with unexpected behavior at runtime**. To avoid undesired situations, you must use static or dynamic linking, but not both.

.. important::

  Even if a combination of static and dynamic libraries seems to work, RTI cannot guarantee there won't be issues when running the |CONNEXT| application.


Properties for Enabling Security
================================

:numref:`Properties for Enabling Security` lists the properties that you can use for enabling security. These properties are configured through the |DP|'s PROPERTY QosPolicy (see :ref:`section-sp-properties`).

.. list-table:: Properties for Enabling Security
  :name: Properties for Enabling Security
  :widths: 40 60
  :header-rows: 1
  :class: longtable

  * - Property Name (prefix with :property:`com.rti.serv.secure.`) [#fPrefix]_
    - Property Value Description

  * - :property:`com.rti.serv.load_plugin`

      Note:
        This property does not take a prefix.

    - :required:`Required`

      The prefix name of the Security Plugins library that will be loaded by |CONNEXT|. For example: :value:`com.rti.serv.secure`. You will use this string as the prefix to some of the property names. Setting this value to non-NULL will also configure the |DP| to attempt authentication with newly discovered remote participants.

      Note:
        You can load only one Security Plugins library.

      :type:`String`.

      Default: :value:`NULL` unless using the :xmlval:`Generic.Security` builtin profile

  * - :property:`library`
    - :required:`Only required if linking dynamically`

      Must be set to the dynamic library that implements the Security Plugins.
      If using one of |CONNEXT|'s provided |RTI_SP_PRODUCT| libraries, you
      must set this value to either :value:`nddssecurity` (|SP_BUILTIN| library) or
      :value:`nddslightweightsecurity` (|LIGHT_SP_BUILTIN| library).

      This library and the dependent OpenSSL libraries must be in your library
      search path (pointed to by the environment variable ``LD_LIBRARY_PATH``
      on Linux systems, ``Path`` on Windows systems, or ``DYLD_LIBRARY_PATH``
      on macOS systems).

      :type:`String`.

      Default: :value:`NULL` unless using the :xmlval:`Generic.Security` builtin profile

  * - :property:`create_function`
    - :required:`Only required if linking dynamically`

      Must be set to the Security Plugins creation function that is implemented
      by the library. If using one of |CONNEXT|'s provided |RTI_SP_PRODUCT|
      libraries, you must set this value to either
      :value:`RTI_Security_PluginSuite_create` (|SP_BUILTIN| library) or
      :value:`RTI_SecurityLightweight_PluginSuite_create` (|LIGHT_SP_BUILTIN|
      library).

      :type:`String`.

      Default: :value:`NULL` unless using the :xmlval:`Generic.Security` builtin profile

  * - :property:`create_function_ptr`
    - :required:`Only required if linking statically`

      Must be set to the Security Plugins creation function implemented by the
      library. If using one of |CONNEXT|'s provided |RTI_SP_PRODUCT|
      libraries, you must set the stringified pointer value of either
      :value:`RTI_Security_PluginSuite_create` (|SP_BUILTIN| library) or
      :value:`RTI_SecurityLightweight_PluginSuite_create` (|LIGHT_SP_BUILTIN|
      library), as demonstrated in the :file:`hello_security` and
      :file:`hello_lightweight_security` examples.

      Notes:
        * You cannot set this value in an XML profile. You must set it in code.
        * If this property is set to a value other than NULL, it will always take effect, even if create_function is also set to a value other than NULL.

      :type:`String`.

      Default: :value:`NULL`

  * - :property:`property_validation_action`
    - :required:`Optional`

      By default, property names given in the PROPERTY QoSPolicy are validated to avoid using incorrect or unknown names (for example, due to a typo). This behavior is controlled by the :property:`dds.participant.property_validation_action` property (see :link_connext_dds_pro_um:`Property Validation in the RTI Connext DDS Core Libraries User’s Manual<#users_manual/PROPERTY_Qos.htm#PropertyValidationUM>` for more information).

      In general, we recommend that you use :property:`dds.participant.property_validation_action`
      to control the validation of the properties for both the |CONNEXT| Core
      libraries and the |RTI_SP_PRODUCT| libraries. However, there are cases
      where you might want to configure different behaviors for the Core and the
      |RTI_SP_PRODUCT|. For example, suppose you are running a customized
      version of the plugins that supports a new, experimental property. In that
      case, you will need to disable the |CONNEXT| Core property validation but
      still may want to keep the |RTI_SP_PRODUCT| property validation.

      The |RTI_SP_PRODUCT|'s :property:`property_validation_action` property
      configures the validation of the property names associated with the |RTI_SP_PRODUCT|:

      * :value:`VALIDATION_ACTION_EXCEPTION`: validate the properties. Upon failure, log exceptions and fail.
      * :value:`VALIDATION_ACTION_SKIP`: skip validation.
      * :value:`VALIDATION_ACTION_WARNING`: validate the properties. Upon failure, log warnings and do not fail.

      If this property is not set, the property validation behavior will be the same as that of the |DP| (controlled by the :property:`dds.participant.property_validation_action` property), which by default is :value:`VALIDATION_ACTION_EXCEPTION`. See :link_connext_dds_pro_um:`Property Validation in the Connext DDS Core Libraries User's Manual <#users_manual/PROPERTY_Qos.htm#PropertyValidationUM>` for more information. See also the :link_connext_dds_pro_properties_ref:`Properties Reference Guide <property_tag.html#dds-secure>`.

      :type:`Enum`: :value:`VALIDATION_ACTION_EXCEPTION`, :value:`VALIDATION_ACTION_SKIP`, :value:`VALIDATION_ACTION_WARNING`.

      Default: not set


.. [#fPrefix] Assuming you used :value:`com.rti.serv.secure` as the alias to load the plugin. If not, change the prefix to match the string used with :property:`com.rti.serv.load_plugins`, followed by the :value:`.` character.


Advanced Concepts
=================

Creating/Deleting a DomainParticipant as a C++ Static Object
------------------------------------------------------------

In some scenarios, you may want a |DP| that can be shared by multiple functions. You could implement this by declaring a |DP| as a C++ static object, as in the following example.

.. literalinclude:: ../snippets/building_apps.cpp
  :language: c++
  :start-after: Declaring a DP as a C++ static object
  :end-before: EOF


This |DP| is created and deleted outside of the ``main()`` function. This code may crash because |OpenSSL_TM|'s cleanup function, ``OPENSSL_cleanup()`` (see :link_external_openssl_docs:`OPENSSL_cleanup in OpenSSL Documentation <OPENSSL_cleanup.html>`), may get executed before the ``~Test()`` destructor gets executed, in which case some of the |DP|'s internal OpenSSL state will be inconsistent. To work around this problem, you must invoke ``OPENSSL_init_crypto()`` and ``OPENSSL_cleanup()`` as follows:

.. literalinclude:: ../snippets/building_apps.cpp
  :language: c++
  :start-after: Invoke OPENSSL_init_crypto and OPENSSL_cleaup
  :end-before: EOF


Platform-Specific Notes
=======================

Building |RTI_SP_PRODUCT_HEADING|-Based Applications for VxWorks 7
------------------------------------------------------------------

You can use the |RTI_SP_PRODUCT| on supported VxWorks 7 platforms (see Supported
Platforms in the |SP_RN_LINK|).

Building VxWorks applications requires cross-compiling your source code for
your target platform. When building |RTI_SP_PRODUCT| applications for VxWorks
7, you will use the OpenSSL libraries from Wind River that are installed on
your VxWorks system. Therefore, there's no need to install any OpenSSL
bundle provided by RTI. Instead, applications should be linked against the
OpenSSL libraries provided with the OS (installed by default).

.. 
  DOC-78
  ADD THIS LINK WHEN VXWORKS IS SUPPORTED (temporarily removed for 7.1.0)
  For further information on building |CONNEXT| applications, refer to
  :link_connext_dds_pro_pn:`VxWorks Platforms in the RTI Connext Core Libraries Platform Notes <#platform_notes/VxWorks_Platforms.htm>`.
..


The OpenSSL binaries (such as :file:`openssl`) will be under
:file:`<vxworks_toolchain_path>/vxworks-7/host/<host_arch>/bin`.

The OpenSSL libraries (such as :file:`libcrypto`) will be under
:file:`<your_vsb_directory>/usr/lib/common`.


Considerations for Building and Running |RTI_SP_PRODUCT_HEADING| in Kernel Modules
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. Note:: 
  
   Load the ``libnddssecurity`` (or ``libnddslightweightsecurity``) module
   before running your application.

To be able to run the |SP_BUILTIN| (or |LIGHT_SP_BUILTIN|) as a kernel module,
the OpenSSL symbols must be available in the kernel. To do that, you must
include the component ``INCLUDE_IPSSL`` in your kernel. Once you have done this,
OpenSSL is already included in the kernel itself, and you do not have to include
it in the application kernel module. If ``INCLUDE_IPSSL`` is not enabled, you
will need to rebuild your kernel, including this component.


Considerations for Building and Running |RTI_SP_PRODUCT_HEADING| in RTP Executables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When running an RTP (Real-Time Process) executable, the process runs at user level, which means that the program does not have access to the kernel memory directly. Thus, the process described in the previous section, :ref:`p2_core/building_apps:Considerations for Building and Running |RTI_SP_PRODUCT_HEADING| in Kernel Modules`, is not valid in this case. In other words, even if you already included OpenSSL symbols in your kernel, the RTP executable cannot use them directly, and thus, you must link it against :file:`libcrypto`.

As you will be using the OpenSSL shipped by Wind River, when you link :file:`libcrypto` against the application, you need to link the one placed into :file:`<your_vsb_directory>/usr/lib/common`. To do that, replace `$NDDSHOME/third_party/openssl-<version>` with :file:`<your_vsb_directory>/usr/lib/common`, where your system’s libraries live. Other than that, follow the steps in `Dynamic Linking`.


Libraries Required for Using the |SP_BUILTIN_HEADING|
=====================================================

To use the |SP_BUILTIN|, link against the additional libraries in one of the
following tables, depending on your platform. Select the files appropriate for your chosen library format.

.. tabs::

  .. tab:: Linux

    .. list-table:: Additional Libraries for Using |SP_BUILTIN| on Linux Systems
      :name: Additional Libraries for Using |SP_BUILTIN_HEADING| on Linux Systems
      :widths: 19 27 27 27
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |SP_BUILTIN| Libraries [#SP_libs]_
        - OpenSSL 1.1.1 Libraries [#OPENSSL111_libs]_
        - OpenSSL 3.5 Libraries [#OPENSSL35_libs]_

      * - Dynamic Release
        - :file:`libnddssecurity.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`

      * - Dynamic Debug
        - :file:`libnddssecurityd.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`

      * - Static Release
        - :file:`libnddssecurityz.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddssecurityzd.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`


  .. tab:: macOS

    .. list-table:: Additional Libraries for Using |SP_BUILTIN| on macOS Systems
      :name: Additional Libraries for Using |SP_BUILTIN_HEADING| on macOS Systems
      :widths: 19 27 27 27
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |SP_BUILTIN| Libraries [#SP_libs]_
        - OpenSSL 1.1.1 Libraries [#OPENSSL111_libs]_
        - OpenSSL 3.5 Libraries [#OPENSSL35_libs]_

      * - Dynamic Release
        - :file:`libnddssecurity.dylib`
        -
          - :file:`libssl.dylib`
          - :file:`libcrypto.dylib`
        -
          - :file:`libssl.dylib`
          - :file:`libcrypto.dylib`

      * - Dynamic Debug
        - :file:`libnddssecurityd.dylib`
        -
          - :file:`libssl.dylib`
          - :file:`libcrypto.dylib`
        -
          - :file:`libssl.dylib`
          - :file:`libcrypto.dylib`

      * - Static Release
        - :file:`libnddssecurityz.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddssecurityzd.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`


  .. tab:: QNX

    .. list-table:: Additional Libraries for Using |SP_BUILTIN| on QNX Systems
      :name: Additional Libraries for Using |SP_BUILTIN_HEADING| on QNX Systems
      :widths: 19 27 27 27
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |SP_BUILTIN| Libraries [#SP_libs]_
        - OpenSSL 1.1.1 Libraries [#OPENSSL111_libs]_
        - OpenSSL 3.5 Libraries [#OPENSSL35_libs]_

      * - Dynamic Release
        - :file:`libnddssecurity.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`

      * - Dynamic Debug
        - :file:`libnddssecurityd.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`

      * - Static Release
        - :file:`libnddssecurityz.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddssecurityzd.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`


  .. tab:: VxWorks 7

    .. list-table:: Additional Libraries for Using |SP_BUILTIN| on VxWorks 7 Systems (Kernel Modules)
      :name: Additional Libraries for Using |SP_BUILTIN_HEADING| on VxWorks 7 Kernel
      :widths: 30 70
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |SP_BUILTIN| Libraries [#SP_libs]_

      * - Dynamic Release
        - :file:`libnddssecurity.so`

      * - Dynamic Debug
        - :file:`libnddssecurityd.so`

      * - Static Release
        - :file:`libnddssecurityz.a`

      * - Static Debug
        - :file:`libnddssecurityzd.a`


    .. list-table:: Additional Libraries for Using |SP_BUILTIN| on VxWorks 7 Systems (RTP Executables)
      :name: Additional Libraries for Using |SP_BUILTIN_HEADING| on VxWorks 7 RTP
      :widths: 30 35 35
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |SP_BUILTIN| Libraries [#SP_libs]_
        - OpenSSL Libraries [#OPENSSL_libs_VxWorks7]_

      * - Dynamic Release
        - :file:`libnddssecurity.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`

      * - Dynamic Debug
        - :file:`libnddssecurityd.so`
        -
          - :file:`libssl.so`
          - :file:`libcrypto.so`

      * - Static Release
        - :file:`libnddssecurityz.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddssecurityzd.a`
        -
          - :file:`libssl.a`
          - :file:`libcrypto.a`

    .. [#OPENSSL_libs_VxWorks7] These libraries are in :file:`<your vsb directory>/usr/lib/common`.


  .. tab:: Windows

    .. list-table:: Additional Libraries for Using |SP_BUILTIN| on Windows Systems
      :name: Additional Libraries for Using |SP_BUILTIN_HEADING| on Windows Systems
      :widths: auto
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |SP_BUILTIN| Libraries [#SP_libs_Win]_
        - OpenSSL 1.1.1 Libraries [#OPENSSL111_libs_Win]_
        - OpenSSL 3.5 Libraries [#OPENSSL35_libs_Win]_
        - System Libraries

      * - Dynamic Release
        - :file:`nddssecurity.dll`
        -
          - :file:`libssl-1_1-x64.dll`
          - :file:`libcrypto-1_1-x64.dll`
        -
          - :file:`libssl-3-x64.dll`
          - :file:`libcrypto-3-x64.dll`
        - (none)

      * - Dynamic Debug
        - :file:`nddssecurityd.dll`
        -
          - :file:`libssl-1_1-x64.dll`
          - :file:`libcrypto-1_1-x64.dll`
        -
          - :file:`libssl-3-x64.dll`
          - :file:`libcrypto-3-x64.dll`
        - (none)

      * - Static Release
        - :file:`nddssecurityz.lib`
        -
          - :file:`libssl.lib`
          - :file:`libcrypto.lib`
        -
          - :file:`libssl.lib`
          - :file:`libcrypto.lib`
        - :file:`crypt32.lib`

      * - Static Debug
        - :file:`nddssecurityzd.lib`
        -
          - :file:`libssl.lib`
          - :file:`libcrypto.lib`
        -
          - :file:`libssl.lib`
          - :file:`libcrypto.lib`
        - :file:`crypt32.lib`

    .. [#SP_libs_Win] These libraries are in :file:`<NDDSHOME>\\lib\\<architecture>`.
    .. [#OPENSSL111_libs_Win] These libraries are in :file:`<NDDSHOME>\\third_party\\openssl-1.1.1<letter>\\<architecture>\\<debug, release, static_debug, or static_release dir>\\<bin or lib>`.
    .. [#OPENSSL35_libs_Win] These libraries are in :file:`<NDDSHOME>\\third_party\\openssl-3.5.<number>\\<architecture>\\<debug, release, static_debug, or static_release dir>\\<bin or lib>`.


.. [#SP_libs] These libraries are in :file:`<NDDSHOME>/lib/<architecture>`.
.. [#OPENSSL111_libs] These libraries are in :file:`<NDDSHOME>/third_party/openssl-1.1.1<letter>/<architecture>/<debug or release dir>/lib`.
.. [#OPENSSL35_libs] These libraries are in :file:`<NDDSHOME>/third_party/openssl-3.5.<number>/<architecture>/<debug or release dir>/lib`.

Libraries Required for Using the |LIGHT_SP_BUILTIN_HEADING|
===========================================================

To use the |LIGHT_SP_BUILTIN|, link against the additional libraries in one of
the following tables, depending on your platform. Select the files appropriate for your chosen library format.

.. tabs::

  .. tab:: Linux

    .. list-table:: Additional Libraries for Using |LIGHT_SP_BUILTIN| on Linux Systems
      :name: Additional Libraries for Using |LIGHT_SP_BUILTIN_HEADING| on Linux Systems
      :widths: 19 27 27 27
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |LIGHT_SP_BUILTIN| Libraries [#LT_SP_libs]_
        - OpenSSL 1.1.1 Libraries [#LT_OPENSSL111_libs]_
        - OpenSSL 3.5 Libraries [#LT_OPENSSL35_libs]_

      * - Dynamic Release
        - :file:`libnddslightweightsecurity.so`
        - :file:`libcrypto.so`
        - :file:`libcrypto.so`

      * - Dynamic Debug
        - :file:`libnddslightweightsecurityd.so`
        - :file:`libcrypto.so`
        - :file:`libcrypto.so`

      * - Static Release
        - :file:`libnddslightweightsecurityz.a`
        - :file:`libcrypto.a`
        - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddslightweightsecurityzd.a`
        - :file:`libcrypto.a`
        - :file:`libcrypto.a`


  .. tab:: macOS

    .. list-table:: Additional Libraries for Using |LIGHT_SP_BUILTIN| on macOS Systems
      :name: Additional Libraries for Using |LIGHT_SP_BUILTIN_HEADING| on macOS Systems
      :widths: 19 27 27 27
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |LIGHT_SP_BUILTIN| Libraries [#LT_SP_libs]_
        - OpenSSL 1.1.1 Libraries [#LT_OPENSSL111_libs]_
        - OpenSSL 3.5 Libraries [#LT_OPENSSL35_libs]_

      * - Dynamic Release
        - :file:`libnddslightweightsecurity.dylib`
        - :file:`libcrypto.dylib`
        - :file:`libcrypto.dylib`

      * - Dynamic Debug
        - :file:`libnddslightweightsecurityd.dylib`
        - :file:`libcrypto.dylib`
        - :file:`libcrypto.dylib`

      * - Static Release
        - :file:`libnddslightweightsecurityz.a`
        - :file:`libcrypto.a`
        - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddslightweightsecurityzd.a`
        - :file:`libcrypto.a`
        - :file:`libcrypto.a`


  .. tab:: QNX

    .. list-table:: Additional Libraries for Using |LIGHT_SP_BUILTIN| on QNX Systems
      :name: Additional Libraries for Using |LIGHT_SP_BUILTIN_HEADING| on QNX Systems
      :widths: 19 27 27 27
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |LIGHT_SP_BUILTIN| Libraries [#LT_SP_libs]_
        - OpenSSL 1.1.1 Libraries [#LT_OPENSSL111_libs]_
        - OpenSSL 3.5 Libraries [#LT_OPENSSL35_libs]_

      * - Dynamic Release
        - :file:`libnddslightweightsecurity.so`
        - :file:`libcrypto.so`
        - :file:`libcrypto.so`

      * - Dynamic Debug
        - :file:`libnddslightweightsecurityd.so`
        - :file:`libcrypto.so`
        - :file:`libcrypto.so`

      * - Static Release
        - :file:`libnddslightweightsecurityz.a`
        - :file:`libcrypto.a`
        - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddslightweightsecurityzd.a`
        - :file:`libcrypto.a`
        - :file:`libcrypto.a`


  .. tab:: VxWorks 7

    .. list-table:: Additional Libraries for Using |LIGHT_SP_BUILTIN| on VxWorks 7 Systems (Kernel Modules)
      :name: Additional Libraries for Using |LIGHT_SP_BUILTIN_HEADING| on VxWorks 7 Kernel
      :widths: 30 70
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |LIGHT_SP_BUILTIN| Libraries [#LT_SP_libs]_

      * - Dynamic Release
        - :file:`libnddslightweightsecurity.so`

      * - Dynamic Debug
        - :file:`libnddslightweightsecurityd.so`

      * - Static Release
        - :file:`libnddslightweightsecurityz.a`

      * - Static Debug
        - :file:`libnddslightweightsecurityzd.a`


    .. list-table:: Additional Libraries for Using |LIGHT_SP_BUILTIN| on VxWorks 7 Systems (RTP Executables)
      :name: Additional Libraries for Using |LIGHT_SP_BUILTIN_HEADING| on VxWorks 7 RTP
      :widths: 30 35 35
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |LIGHT_SP_BUILTIN| Libraries [#LT_SP_libs]_
        - OpenSSL Libraries [#LT_OPENSSL_libs_VxWorks7]_

      * - Dynamic Release
        - :file:`libnddslightweightsecurity.so`
        - :file:`libcrypto.so`

      * - Dynamic Debug
        - :file:`libnddslightweightsecurityd.so`
        - :file:`libcrypto.so`

      * - Static Release
        - :file:`libnddslightweightsecurityz.a`
        - :file:`libcrypto.a`

      * - Static Debug
        - :file:`libnddslightweightsecurityzd.a`
        - :file:`libcrypto.a`

    .. [#LT_OPENSSL_libs_VxWorks7] These libraries are in :file:`<your vsb directory>/usr/lib/common`.


  .. tab:: Windows

    .. list-table:: Additional Libraries for Using |LIGHT_SP_BUILTIN| on Windows Systems
      :name: Additional Libraries for Using |LIGHT_SP_BUILTIN_HEADING| on Windows Systems
      :widths: auto
      :width: 100%
      :header-rows: 1
      :class: longtable

      * - Library Format
        - |LIGHT_SP_BUILTIN| Libraries [#LT_SP_libs_Win]_
        - OpenSSL 1.1.1 Libraries [#LT_OPENSSL111_libs_Win]_
        - OpenSSL 3.5 Libraries [#LT_OPENSSL35_libs_Win]_
        - System Libraries

      * - Dynamic Release
        - :file:`nddslightweightsecurity.dll`
        - :file:`libcrypto-1_1-x64.dll`
        - :file:`libcrypto-3-x64.dll`
        - (none)

      * - Dynamic Debug
        - :file:`nddslightweightsecurityd.dll`
        - :file:`libcrypto-1_1-x64.dll`
        - :file:`libcrypto-3-x64.dll`
        - (none)

      * - Static Release
        - :file:`nddslightweightsecurityz.lib`
        - :file:`libcrypto.lib`
        - :file:`libcrypto.lib`
        - :file:`crypt32.lib`

      * - Static Debug
        - :file:`nddslightweightsecurityzd.lib`
        - :file:`libcrypto.lib`
        - :file:`libcrypto.lib`
        - :file:`crypt32.lib`

    .. [#LT_SP_libs_Win] These libraries are in :file:`<NDDSHOME>\\lib\\<architecture>`.
    .. [#LT_OPENSSL111_libs_Win] These libraries are in :file:`<NDDSHOME>\\third_party\\openssl-1.1.1<letter>\\<architecture>\\<debug, release, static_debug, or static_release dir>\\<bin or lib>`.
    .. [#LT_OPENSSL35_libs_Win] These libraries are in :file:`<NDDSHOME>\\third_party\\openssl-3.5.<number>\\<architecture>\\<debug, release, static_debug, or static_release dir>\\<bin or lib>`.


.. [#LT_SP_libs] These libraries are in :file:`<NDDSHOME>/lib/<architecture>`.
.. [#LT_OPENSSL111_libs] These libraries are in :file:`<NDDSHOME>/third_party/openssl-1.1.1<letter>/<architecture>/<debug or release dir>/lib`.
.. [#LT_OPENSSL35_libs] These libraries are in :file:`<NDDSHOME>/third_party/openssl-3.5.<number>/<architecture>/<debug or release dir>/lib`.
