How to import RealTimeSDK cmake targets into my own project?

I am looking for information on how to import the Real Time SDK cmake project into my project.


I have downloaded the Real Time SDK, and built it on a supported platform.


There is no cmake INSTALL option. As such, what is the recommended way to import the cmake targets (eg libema) from the Real Time SDK into my own cmake project?


Should I be using ExternalProject_Add? This doesn't seem like the correct cmake function to use as using this will attempt to build the project - I have already built it, I just want to import the cmake targets.

Best Answer

  • steve.l
    Answer ✓

    Answering my own question.


    Unfortunately this is not natively supported in the Refinitiv CMakeFiles.


    Since the SDK only supports certain platforms, I ended up installing it in a docker image, which then allows any developer to build it locally.


    For anyone interested in doing the same, this is the relevant excerpt from my Dockerfile:


    ARG REFINITIV_SDK_VERSION=2.0.1.G1
    ARG REFINITIV_SDK_TAG=Real-Time-SDK-${REFINITIV_SDK_VERSION}
    ARG GCC_VERSION=921
    RUN cd /opt \
        && curl -fSL https://github.com/Refinitiv/Real-Time-SDK/archive/refs/tags/${REFINITIV_SDK_TAG}.zip -o ${REFINITIV_SDK_TAG}.zip \
        && unzip ${REFINITIV_SDK_TAG}.zip \
        && mv Real-Time-SDK-${REFINITIV_SDK_TAG} rtsdk \
        && cd rtsdk \
        && cmake -Bbuild \
            -DBUILD_UNIT_TESTS=OFF \
            -DBUILD_EMA_DOXYGEN=OFF \
            -DBUILD_EMA_EXAMPLES=OFF \
            -DBUILD_EMA_PERFTOOLS=OFF \
            -DBUILD_EMA_TRAINING=OFF \
            -DBUILD_EMA_UNIT_TESTS=OFF \
            -DBUILD_ETA_APPLICATIONS=OFF \
            -DBUILD_ETA_DOXYGEN=OFF \
            -DBUILD_ETA_EXAMPLES=OFF \
            -DBUILD_ETA_PERFTOOLS=OFF \
            -DBUILD_ETA_TRAINING=OFF \
            -DBUILD_ETA_UNIT_TESTS=OFF \
            -DBUILD_32_BIT_ETA=OFF \
        && make -C build --jobs ${MAKE_JOBS} \
        && rsync -avr build/install/ /usr \
        && cp Cpp-C/Eta/Libs/CENTOS8_64_GCC${GCC_VERSION}/Optimized/libansi.a /usr/local/lib \
        && cp Cpp-C/Eta/Libs/CENTOS8_64_GCC${GCC_VERSION}/Optimized/librssl.a /usr/local/lib \
        && cp Cpp-C/Eta/Libs/CENTOS8_64_GCC${GCC_VERSION}/Optimized/librsslVA.a /usr/local/lib \
        && cp Cpp-C/Ema/Libs/CENTOS8_64_GCC${GCC_VERSION}/Optimized/libema.a /usr/local/lib \
        && cd /opt \
        && rm ${REFINITIV_SDK_TAG}.zip


    It installs the source into `/opt/rtsdk`, and copies the relevant static libraries to `/usr/local/lib`.


    Later, in my `CMakeLists.txt` I can create an INTERFACE target which imports all the relevant parts of the sdk.


    set(RTSDK_SRC /opt/rtsdk)
    set(Ema_SOURCE_DIR ${RTSDK_SRC}/Cpp-C/Ema)

    find_library(LIB_EMA ema)
    find_library(LIB_RSSLVA rsslVA)
    find_library(LIB_RSSL rssl)
    find_library(LIB_XML2 xml2)

    set(REFINITIV_LIBS
        ${LIB_EMA}
        ${LIB_RSSLVA}
        ${LIB_RSSL}
        ${LIB_XML2}
        Threads::Threads
        dl
        rt
        )

    set(REFINITIV_DIRS
        ${Ema_SOURCE_DIR}/Src/Access/Include
        ${Ema_SOURCE_DIR}/Src/Access/Impl
        ${Ema_SOURCE_DIR}/Src/Domain/Login/Include
        ${Ema_SOURCE_DIR}/Src/Rdm/Include
        ${Ema_SOURCE_DIR}/Src/Include
        ${Ema_SOURCE_DIR}/Src
        )

    set(REFINITIV_OPTS
        "-D__EMA_STATIC_BUILD__"
        "-D__EMA_COPY_ON_SET__"
        -Wno-old-style-cast
        -Wno-ignored-qualifiers
        -Wno-non-virtual-dtor
        )

    add_library               (rtsdk INTERFACE)
    target_link_libraries     (rtsdk INTERFACE ${REFINITIV_LIBS})
    target_include_directories(rtsdk INTERFACE ${REFINITIV_DIRS})
    target_compile_options    (rtsdk INTERFACE ${REFINITIV_OPTS})


    Now in my own source I just link against `rtsdk`.


    I do believe rtsdk should provide an INSTALL target in their CMakeLists.txt, but in lieu of this the above may be help to others

Answers

  • @steve.l

    I don't know much about cmake. However, if you download the released package, the package contains almost everything that you need to compile and build applications.

    For example, the EMA's include files are in the <EMA root>\Cpp-C\Ema\Src directory. The libraries are in the <EMA root>\Cpp-C\Ema\Libs library.

    You can refer to the EMA C++ Compiler Settings tutorial as a guideline to create a make file.

  • I think I am also confused by the state of affairs.

    The link @Jirapongse posted offers information on how to configure either Visual Studio or a Makefile, given the downloaded and unzipped SDK. But it does not help to configure a CMake build.

    I think the question @steve.l has is my own: if I use CMake to configure my own C++ project, how am I supposed to configure it to use the SDK libraries?

    As far as I understand, the SDK has it's own CMake support to build itself, but there is no offering to consume the libraries from my own project.

    I suggest having a readily available CMakeLists.txt file somewhere, so that in my own CMakeLists, the one I use to build *my* project, I can just

    add_subdirectory(<EMA-Root>/CMake-for-SDK-clients)
    target_link_libraries(my_own_library PRIVATE libema)

    and It Just Works

    I'm trying to do this with the top-level CMakeLists under RTSDK-2.0.2.E1.win.rrg, but it doesn't work.

  • I guess that, if there is no other solution, I'll have to create my own IMPORTED targets to consume the SDK in Windows, just as the OP did for Linux... :(

  • FWIW, here is the CMakeLists.txt I am using for the step1 tutorial (https://developers.refinitiv.com/en/api-catalog/refinitiv-real-time-opnsrc/rt-sdk-cc/tutorials#ema-consumer-creating-a-barebones-ema-consumer-application), with values hardcoded for: SDK Root directory, Windows, VS2019, Debug, static libraries.

    As I already mentioned, it would be better if this worked out-of-the-box for all supported platforms and build variants, instead of having to reinvent the wheel.

    cmake_minimum_required(VERSION 3.20 FATAL_ERROR)

    # Project name and a few useful settings
    project(step1
    VERSION 1.0
    LANGUAGES CXX)

    set(RTSDK_ROOT C:/Real-Time-SDK-2.0.2.E1.win/RTSDK-2.0.2.E1.win.rrg)

    set(RTSDK_INCLUDES
    ${RTSDK_ROOT}/Cpp-C/Ema/Src/Access/Include
    ${RTSDK_ROOT}/Cpp-C/Ema/Src/Domain/Login/Include
    ${RTSDK_ROOT}/Cpp-C/Ema/Src/Rdm/Include
    ${RTSDK_ROOT}/Cpp-C/Ema/Src/Include
    ${RTSDK_ROOT}/Cpp-C/Ema/Src
    ${RTSDK_ROOT}/Cpp-C/Eta/Include/Reactor
    ${RTSDK_ROOT}/Cpp-C/Eta/Include/Util
    ${RTSDK_ROOT}/Cpp-C/Eta/Include/RDM
    ${RTSDK_ROOT}/Cpp-C/Eta/Include/Codec
    ${RTSDK_ROOT}/Cpp-C/Eta/Include/Transport
    ${RTSDK_ROOT}/Cpp-C/Eta/Impl/Util/Include
    ${RTSDK_ROOT}/Cpp-C/Eta/Utils/Libxml2
    ${RTSDK_ROOT}/Cpp-C/Eta/Utils/Libxml2/include/libxml
    ${RTSDK_ROOT}/Cpp-C/Eta/Utils/Libxml2/include
    )

    set(RTSDK_LIBS
    ${RTSDK_ROOT}/Cpp-C/Ema/Libs/WIN_64_VS142/Debug_MDd/libema.lib
    ${RTSDK_ROOT}/Cpp-C/Eta/Libs/WIN_64_VS142/Debug_MDd/libansi.lib
    ${RTSDK_ROOT}/Cpp-C/Eta/Libs/WIN_64_VS142/Debug_MDd/librssl.lib
    ${RTSDK_ROOT}/Cpp-C/Eta/Libs/WIN_64_VS142/Debug_MDd/librsslVA.lib
    Ws2_32.lib
    wininet.lib
    Iphlpapi.lib
    crypt32.lib
    )

    set(RTSDK_DEFINES
    __EMA_STATIC_BUILD__
    )

    add_library (rtsdk INTERFACE)
    target_link_libraries (rtsdk INTERFACE ${RTSDK_LIBS})
    target_include_directories(rtsdk INTERFACE ${RTSDK_INCLUDES})
    target_compile_definitions(rtsdk INTERFACE ${RTSDK_DEFINES})

    add_executable(step1 Consumer.cpp Consumer.h)

    target_link_libraries(step1 PRIVATE rtsdk)