Skip to content

[MDAPI-254][C++] Migrate to dxFeed Graal Native SDK 2.5.0 #80

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 20 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ set(DXFCXX_VERSION "v4.2.0" CACHE STRING "The dxFeed Graal CXX API package versi

dxfcxx_ParseVersion(${DXFCXX_VERSION} DXFCXX_MAJOR_VERSION DXFCXX_MINOR_VERSION DXFCXX_PATCH_VERSION DXFCXX_SUFFIX_VERSION)

set(DXFEED_GRAAL_NATIVE_SDK_VERSION "2.2.1" CACHE STRING "")
set(DXFEED_GRAAL_NATIVE_SDK_VERSION "2.5.0" CACHE STRING "")
set(FMTLIB_VERSION "11.0.2")
set(BOOST_VERSION "1.84.0")
set(UTFCPP_VERSION "3.2.3")
Expand Down Expand Up @@ -63,7 +63,7 @@ option(DXFCXX_INSTALL_SAMPLES "Prepare install the samples" ${DXFCXX_IS_ROOT_PRO
option(DXFCXX_INSTALL_TOOLS "Prepare install the tools" ${DXFCXX_IS_ROOT_PROJECT})

option(DXFCXX_LINK_STATIC_RUNTIME "Compile and link with -MT/-MTd or equivalent flag(s) to use a multi-threaded statically-linked runtime library. Visual Studio only." OFF)
option(DXFCXX_NODEFAULTLIB_LIBCMT "Ignore libcmt/libcmtd. Use if DXFCXX_LINK_STATIC_RUNTIME == ON." ${DXFCXX_LINK_STATIC_RUNTIME})
option(DXFCXX_NODEFAULTLIB "Ignore libcmt/libcmtd/msvcrt/msvcrtd. Use if DXFCXX_LINK_STATIC_RUNTIME == ON." ${DXFCXX_LINK_STATIC_RUNTIME})

option(DXFCXX_ENABLE_METRICS "Enable metrics collection" OFF)

Expand Down Expand Up @@ -93,6 +93,7 @@ set(DXFCXX_GRAAL_TARGET_CPU "unknown" CACHE STRING "")
include(cmake/ParseAndDetectPlatforms.cmake)
include(cmake/LinkStacktrace.cmake)
include(cmake/LinkAsanUbsan.cmake)
include(cmake/SetupStaticRuntimeMSVC.cmake)

if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/graal-native-sdk-${DXFEED_GRAAL_NATIVE_SDK_VERSION}-${DXFCXX_GRAAL_TARGET_PLATFORM}/CMakeLists.txt")
add_subdirectory(third_party/graal-native-sdk-${DXFEED_GRAAL_NATIVE_SDK_VERSION}-${DXFCXX_GRAAL_TARGET_PLATFORM})
Expand Down Expand Up @@ -146,17 +147,8 @@ else ()
CPMAddPackage("gh:ttldtor/Process#v${PROCESS_VERSION}")
endif ()

if (DXFCXX_LINK_STATIC_RUNTIME)
set_target_properties(process PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

if (DXFCXX_NODEFAULTLIB_LIBCMT)
target_link_options(process PRIVATE
"/NODEFAULTLIB:LIBCMT"
"/NODEFAULTLIB:LIBCMTD"
)
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
SetupStaticRuntimeMSVC(process ${DXFCXX_LINK_STATIC_RUNTIME} ${DXFCXX_NODEFAULTLIB})
endif ()

if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/Console-${CONSOLE_VERSION}/CMakeLists.txt")
Expand All @@ -165,12 +157,20 @@ else ()
CPMAddPackage("gh:ttldtor/Console#v${CONSOLE_VERSION}")
endif ()

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
SetupStaticRuntimeMSVC(console ${DXFCXX_LINK_STATIC_RUNTIME} ${DXFCXX_NODEFAULTLIB})
endif ()

if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/third_party/portals/CMakeLists.txt")
add_subdirectory(third_party/portals)
else ()
CPMAddPackage("gh:ttldtor/portals#default")
endif ()

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
SetupStaticRuntimeMSVC(portals ${DXFCXX_LINK_STATIC_RUNTIME} ${DXFCXX_NODEFAULTLIB})
endif ()

add_subdirectory(third_party/utfcpp-${UTFCPP_VERSION})

set(FMT_INSTALL OFF)
Expand All @@ -189,6 +189,10 @@ else ()
FetchContent_MakeAvailable(fmt)
endif ()

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
SetupStaticRuntimeMSVC(fmt ${DXFCXX_LINK_STATIC_RUNTIME} ${DXFCXX_NODEFAULTLIB})
endif ()

#set(BUILD_TZ_LIB ON)
#set(USE_SYSTEM_TZ_DB ON)
add_subdirectory(third_party/date-${DATE_VERSION})
Expand Down Expand Up @@ -469,20 +473,9 @@ add_library(dxfcxx ALIAS ${PROJECT_NAME})
add_library(dxfcxx::static ALIAS ${PROJECT_NAME}_static)
add_library(dxfcxx::graal ALIAS DxFeedGraalNativeSdk)

if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set_target_properties(${PROJECT_NAME} PROPERTIES CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
if (DXFCXX_LINK_STATIC_RUNTIME)
set_target_properties(${PROJECT_NAME}_static PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

if (DXFCXX_NODEFAULTLIB_LIBCMT)
target_link_options(${PROJECT_NAME}_static PRIVATE
"/NODEFAULTLIB:LIBCMT"
"/NODEFAULTLIB:LIBCMTD"
)
endif ()
endif ()
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC"))
# set_target_properties(${PROJECT_NAME} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
SetupStaticRuntimeMSVC(${PROJECT_NAME}_static ${DXFCXX_LINK_STATIC_RUNTIME} ${DXFCXX_NODEFAULTLIB})
endif ()

target_include_directories(${PROJECT_NAME} PUBLIC include)
Expand Down
16 changes: 16 additions & 0 deletions ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
## v4.3.0

* Renamed `DXFCXX_NODEFAULTLIB_LIBCMT` to `DXFCXX_NODEFAULTLIB` CMake project option for clearer purposes and added support for additional libraries in `/NODEFAULTLIB` configuration.
* **\[MDAPI-254]\[C++]** Migrated to Graal SDK v2.5.0
* Added `AGGREGATE`, `COMPOSITE`, `REGIONAL` OrderSource. The new system property `dxscheme.unitaryOrderSource=true|false` has been added.
It controls whether a single or unitary source is used when subscribing to all sources. It is set to 'false' by default.
All separate sources, such as `COMPOSITE_ASK`, `COMPOSITE_BID`, `REGIONAL_ASK`, `REGIONAL_BID`, `AGGREGATE_ASK` and `AGGREGATE_BID` have been
declared deprecated.
* Added new Order source for BlueOcean ATS: ocea.
* Added new Order sources for IG CFDs Gate: IGC, igc.
* Added new Order sources for EDX Gate: EDX, edx.
* Added new Order sources for Nuam Exchange Gate: NUAM, nuam.
* Added the ability to automatically generate the DXEndpoint name.
If the user does not explicitly specify the endpoint name, it will be generated using the template `qdcxx{Id}`,
where `{Id}` will be an empty string for the first instance of the endpoint and "-2", "-3", etc. for subsequent instances.

## v4.2.0

* **\[MDAPI-249]\[C++]** Transitive dependencies are hidden.
Expand Down
2 changes: 1 addition & 1 deletion cmake/LinkAsanUbsan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function(LinkAsan targetName)
target_link_options(${targetName} PRIVATE "-fsanitize=address")
else ()
target_compile_options(${targetName} PRIVATE "/fsanitize=address")
target_link_options(${targetName} PRIVATE "/fsanitize=address")
# target_link_options(${targetName} PRIVATE "/fsanitize=address")

target_compile_definitions(${targetName}
PUBLIC
Expand Down
20 changes: 20 additions & 0 deletions cmake/SetupStaticRuntimeMSVC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2025 Devexperts LLC.
# SPDX-License-Identifier: MPL-2.0

function(SetupStaticRuntimeMSVC targetName linkStaticRuntime noDefaultLib)
if (${linkStaticRuntime})
set_target_properties(${targetName} PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>"
)

if (${noDefaultLib})
target_link_options(${targetName} PRIVATE
/NODEFAULTLIB:libcmt
/NODEFAULTLIB:libcmtd
/NODEFAULTLIB:msvcrt
/NODEFAULTLIB:msvcrtd
/VERBOSE
)
endif ()
endif ()
endfunction()
108 changes: 104 additions & 4 deletions include/dxfeed_graal_cpp_api/event/market/OrderSource.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ class DXFCPP_EXPORT OrderSource final : public IndexedEventSource {
static constexpr std::uint32_t PUB_OTC_MARKETS_ORDER = 0x0004;
static constexpr std::uint32_t PUB_SPREAD_ORDER = 0x0008U;
static constexpr std::uint32_t FULL_ORDER_BOOK = 0x0010U;
static constexpr std::uint32_t PUB_NUAM_ORDER = 0x0020U;

static constexpr std::uint32_t FLAGS_SIZE = 5U;
static constexpr std::uint32_t FLAGS_SIZE = 6U;

public:
static const std::unordered_map<std::variant<std::int32_t, std::string>, std::reference_wrapper<const OrderSource>>
Expand Down Expand Up @@ -85,43 +86,87 @@ class DXFCPP_EXPORT OrderSource final : public IndexedEventSource {
/**
* Bid side of a composite Quote.
* It is a <em>synthetic</em> source.
* It cannot be used with DXFeed::getIndexedEventsPromise method and it cannot be published directly to.
* The subscription on composite Quote event is observed when this source is subscribed to.
* @deprecated Use the OrderSource::COMPOSITE source.
*/
static const OrderSource COMPOSITE_BID;

/**
* Ask side of a composite Quote.
* It is a <em>synthetic</em> source.
* It is a <em>synthetic</em> and <em>separate</em> source.
* It cannot be used with DXFeed::getIndexedEventsPromise method and it cannot be published directly to.
* The subscription on composite Quote event is observed when this source is subscribed to.
* @deprecated Use the OrderSource::COMPOSITE source.
*/
static const OrderSource COMPOSITE_ASK;

/**
* Bid side of a regional Quote.
* It is a <em>synthetic</em> source.
* It is a <em>synthetic</em> and <em>separate</em> source.
* It cannot be used with DXFeed::getIndexedEventsPromise method and it cannot be published directly to.
* The subscription on regional Quote event is observed when this source is subscribed to.
* @deprecated Use the OrderSource::REGIONAL source.
*/
static const OrderSource REGIONAL_BID;

/**
* Ask side of a regional Quote.
* It is a <em>synthetic</em> source.
* It is a <em>synthetic</em> and <em>separate</em> source.
* It cannot be used with DXFeed::getIndexedEventsPromise method and it cannot be published directly to.
* The subscription on regional Quote event is observed when this source is subscribed to.
* @deprecated Use the OrderSource::REGIONAL source.
*/
static const OrderSource REGIONAL_ASK;

/**
* Bid side of an aggregate order book (futures depth and NASDAQ Level II).
* It is a <em>aggregate</em> and <em>separate</em> source.
* This source cannot be directly published via dxFeed API, but otherwise it is fully operational.
* @deprecated Use the OrderSource::AGGREGATE source.
*/
static const OrderSource AGGREGATE_BID;

/**
* Ask side of an aggregate order book (futures depth and NASDAQ Level II).
* It is a <em>aggregate</em> and <em>separate</em> source.
* This source cannot be directly published via dxFeed API, but otherwise it is fully operational.
* @deprecated Use the OrderSource::AGGREGATE source.
*/
static const OrderSource AGGREGATE_ASK;

/**
* Composite Quote.
* It is a <em>synthetic</em> and <em>unitary</em> source, that represents both bid and ask side.
* It cannot be used with DXFeed::getIndexedEventsPromise method and it cannot be published directly to.
* The subscription on composite Quote event is observed when this source is subscribed to.
* To use this source when subscribing to all sources (e.g., when subscribing to an order without specifying a
* source), instead of OrderSource::COMPOSITE_ASK and OrderSource::COMPOSITE_BID, set the system property
* <b>`dxscheme.unitaryOrderSource`</b> to `true`.
*/
static const OrderSource COMPOSITE;

/**
* Regional Quote.
* It is a <em>synthetic</em> and <em>unitary</em> source, that represents both bid and ask side.
* It cannot be used with DXFeed::getIndexedEventsPromise method and it cannot be published directly to.
* The subscription on regional Quote event is observed when this source is subscribed to.
* To use this source when subscribing to all sources (e.g., when subscribing to an order without specifying a
* source), instead of OrderSource::REGIONAL_ASK and OrderSource::REGIONAL_BID, set the system property
* <b>`dxscheme.unitaryOrderSource`</b> to `true`.
*/
static const OrderSource REGIONAL;

/**
* Aggregate order book (futures depth and NASDAQ Level II).
* It is a <em>aggregate</em> and <em>unitary</em> source, that represents both bid and ask side.
* This source cannot be directly published via dxFeed API, but otherwise it is fully operational.
* To use this source when subscribing to all sources (e.g., when subscribing to an order without specifying a
* source), instead of OrderSource::AGGREGATE_ASK and OrderSource::AGGREGATE_BID, set the system property
* <b>`dxscheme.unitaryOrderSource`</b> to `true`.
*/
static const OrderSource AGGREGATE;

/**
* Default source for publishing custom order books.
* Order, AnalyticOrder, OtcMarketsOrder and SpreadOrder events are @ref ::isPublishable() "publishable"
Expand Down Expand Up @@ -402,6 +447,13 @@ class DXFCPP_EXPORT OrderSource final : public IndexedEventSource {
*/
static const OrderSource OCEA;

/**
* Blue Ocean Technologies Alternative Trading System. Record for price level book.
* Order events are @ref ::isPublishable() "publishable" on this source and the corresponding subscription can be
* observed via DXPublisher.
*/
static const OrderSource ocea;

/**
* Pink Sheets. Record for price level book.
* Pink sheets are listings for stocks that trade over-the-counter (OTC).
Expand Down Expand Up @@ -443,6 +495,54 @@ class DXFCPP_EXPORT OrderSource final : public IndexedEventSource {
*/
static const OrderSource cedx;

/**
* IG CFDs Gate.
*
* Order events are @ref ::isPublishable() "publishable" on this source and the corresponding subscription can be
* observed via DXPublisher.
*/
static const OrderSource IGC;

/**
* IG CFDs Gate. Record for price level book.
*
* Order events are @ref ::isPublishable() "publishable" on this source and the corresponding subscription can be
* observed via DXPublisher.
*/
static const OrderSource igc;

/**
* EDX Exchange.
*
* Order events are @ref ::isPublishable() "publishable" on this source and the corresponding subscription can be
* observed via DXPublisher.
*/
static const OrderSource EDX;

/**
* EDX Exchange. Record for price level book.
*
* Order events are @ref ::isPublishable() "publishable" on this source and the corresponding subscription can be
* observed via DXPublisher.
*/
static const OrderSource edx;

/**
* Nuam Exchange Gate.
*
* Order and NuamOrder events are @ref ::isPublishable() "publishable" on this source and the corresponding
* subscription can be observed via DXPublisher.
*/
static const OrderSource NUAM;

/**
* Nuam Exchange Gate. Record for price level book.
*
* Order and NuamOrder events are @ref ::isPublishable() "publishable" on this source and the corresponding
* subscription can be observed via DXPublisher.
*/
static const OrderSource nuam;

/**
* Determines whether specified source identifier refers to special order source.
* Special order sources are used for wrapping non-order events into order events.
Expand Down
23 changes: 13 additions & 10 deletions src/api/DXEndpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,9 @@ std::shared_ptr<DXEndpoint> DXEndpoint::create(void *endpointHandle, DXEndpoint:
", role = " + roleToString(role) + ", properties[" + std::to_string(properties.size()) + "])");
}

auto name = properties.contains(NAME_PROPERTY) ? properties.at(NAME_PROPERTY) : std::string{};

if (name.empty()) {
std::size_t id = ApiContext::getInstance()->getManager<EntityManager<DXEndpoint>>()->getLastId();

name = fmt::format("qdcxx{}", (id <= 1) ? "" : fmt::format("-{}", id));
}

auto endpoint = DXEndpoint::createShared(JavaObjectHandle<DXEndpoint>(endpointHandle), role, name);
auto id = ApiContext::getInstance()->getManager<EntityManager<DXEndpoint>>()->registerEntity(endpoint);
auto endpoint =
DXEndpoint::createShared(JavaObjectHandle<DXEndpoint>(endpointHandle), role, properties.at(NAME_PROPERTY));
const auto id = ApiContext::getInstance()->getManager<EntityManager<DXEndpoint>>()->registerEntity(endpoint);

endpoint->stateChangeListenerHandle_ = isolated::api::IsolatedDXEndpoint::StateChangeListener::create(
dxfcpp::bit_cast<void *>(&Impl::onPropertyChange), dxfcpp::bit_cast<void *>(id.getValue()));
Expand Down Expand Up @@ -336,6 +329,16 @@ std::shared_ptr<DXEndpoint> DXEndpoint::Builder::build() {

loadDefaultPropertiesImpl();

if (auto name = properties_.contains(NAME_PROPERTY) ? properties_.at(NAME_PROPERTY) : std::string{}; name.empty()) {
std::size_t id = ApiContext::getInstance()->getManager<EntityManager<DXEndpoint>>()->getLastId();

name = fmt::format("qdcxx{}", (id <= 1) ? "" : fmt::format("-{}", id));

const auto newBuilder = withProperty(NAME_PROPERTY, name);

return newBuilder->build();
}

return DXEndpoint::create(isolated::api::IsolatedDXEndpoint::Builder::build(handle_), role_, properties_);
}

Expand Down
Loading
Loading