diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..4df9ff8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,134 @@ +cmake_minimum_required(VERSION 3.14 FATAL_ERROR) + +set(HDDS_PROJECT_VERSION "") + +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml") + message(WARNING "Unable to find 'Cargo.toml' in current directory: project version UNKNOWN") +else() + file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml" HDDS_CARGO_TOML) + set(HDDS_SEARCHING_FOR_VERSION OFF) + foreach(line IN LISTS HDDS_CARGO_TOML) + # Search in Cargo.toml for the pattern 'major[.minor][.patch][.tweak]' + if(HDDS_SEARCHING_FOR_VERSION AND "${line}" MATCHES "version[\r\n\t ]*=[\r\n\t ]*\"?([0-9]+([\.][0-9]+)?([\.][0-9]+)?([\.][0-9]+)?)\"?$") + set(HDDS_PROJECT_VERSION ${CMAKE_MATCH_1}) + break() + endif() + + if(${line} MATCHES "workspace.package") + set(HDDS_SEARCHING_FOR_VERSION ON) + endif() + endforeach() +endif() + +if(NOT HDDS_PROJECT_VERSION) + message(WARNING "Unable to read rust library version") +endif() + +project(hdds + VERSION ${HDDS_PROJECT_VERSION} + DESCRIPTION "High-performance DDS" + LANGUAGES C CXX +) + +option(BUILD_SHARED_LIBS "Build static or shared library" OFF) +option(BUILD_HDDS_CXX "Enable building hdds_cxx library" ON) + +# Set CMAKE_BUILD_TYPE if neither parent nor project set it or if we are using +# a multi-config generator +get_property(HDDS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(NOT HDDS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type for the library") +endif() + +# Ensure cargo is installed +set(CARGO_EXECUTABLE) +find_program(CARGO_EXECUTABLE NAMES cargo) +if("${CARGO_EXECUTABLE}" STREQUAL "CARGO_EXECUTABLE-NOTFOUND") + message(FATAL_ERROR "Cargo not found. Look at: https://rust-lang.org/learn/get-started") +endif() + +# Determine library extensions and suffixes for the current OS +if(WIN32) + set(HDDS_SHARED_LIBRARY_EXTENSION "dll") + set(HDDS_STATIC_LIBRARY_EXTENSION "lib") + set(HDDS_LIBRARY_PREFIX "") +else() + set(HDDS_SHARED_LIBRARY_EXTENSION "so") + set(HDDS_STATIC_LIBRARY_EXTENSION "a") + set(HDDS_LIBRARY_PREFIX "lib") +endif() +set(HDDS_C_LIBRARY_NAME ${HDDS_LIBRARY_PREFIX}hdds_c) + +# Use the build type to know the folder in which the library will be built +if("${CMAKE_BUILD_TYPE}" STREQUAL "Release" OR "${CMAKE_BUILD_TYPE}" STREQUAL "Debug") + string(TOLOWER "${CMAKE_BUILD_TYPE}" HDDS_BUILD_TYPE) +else() + set(HDDS_BUILD_TYPE "release") +endif() + +set(HDDS_CMAKE_LIBRARY_TYPE "STATIC") +if(BUILD_SHARED_LIBS) + set(HDDS_CMAKE_LIBRARY_TYPE "SHARED") +endif() + +# Set the path to the library binary file depending on the build type +set(HDDS_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${HDDS_BUILD_TYPE}") +if(BUILD_SHARED_LIBS) + set(HDDS_LIBRARY_OUTPUT ${HDDS_OUTPUT_DIR}/${HDDS_C_LIBRARY_NAME}.${HDDS_SHARED_LIBRARY_EXTENSION}) +else() + set(HDDS_LIBRARY_OUTPUT ${HDDS_OUTPUT_DIR}/${HDDS_C_LIBRARY_NAME}.${HDDS_STATIC_LIBRARY_EXTENSION}) +endif() + +# Set location of library headers +set(HDDS_C_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdk/c/include") +set(HDDS_C_HEADERS "${HDDS_C_INCLUDE_DIR}/hdds.h") + +# Set build flag for cargo only if building in Release +if(${HDDS_BUILD_TYPE} STREQUAL "release") + set(HDDS_CARGO_RELEASE_BUILD_FLAG "--${HDDS_BUILD_TYPE}") +endif() + +# Add a custom command to build the library and a custom target that depends on the output of the command +# that will triger the cargo build task +add_custom_target(${PROJECT_NAME}_rust ALL + ${CARGO_EXECUTABLE} "rustc" "--manifest-path" "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml" + "--package" "hdds-c" "${HDDS_CARGO_RELEASE_BUILD_FLAG}" + "--crate-type" $,cdylib,staticlib> + "--target-dir" "${CMAKE_CURRENT_BINARY_DIR}" + DEPENDS ${HDDS_C_HEADERS} # CMake will re-run the command whenever the files change + BYPRODUCTS ${HDDS_LIBRARY_OUTPUT} + VERBATIM +) + +# Generate the imported library for HDDS and link it to the custom target to ensure the custom command to be called +add_library(${PROJECT_NAME}_c ${HDDS_CMAKE_LIBRARY_TYPE} IMPORTED GLOBAL ${HDDS_C_HEADERS}) +add_library(${PROJECT_NAME}::${PROJECT_NAME}_c ALIAS ${PROJECT_NAME}_c) + +if (WIN32) + # Link Windows libraries + target_link_libraries(${PROJECT_NAME}_c INTERFACE ntdll kernel32 ws2_32 userenv iphlpapi bcrypt) +endif() + +# Manually specify the dependency between HDDS target and the fake one to ensure compiler will not invert the order +add_dependencies(${PROJECT_NAME}_c ${PROJECT_NAME}_rust) + +# Change imported library location to the built one +set(HDDS_LIBRARY_IMPORTED_LOCATION ${HDDS_LIBRARY_OUTPUT}) + +# Set imported target library location and implib. +# On Windows if the library is static then both properties +# must be the same .lib file. On Linux the 'IMPORTED_IMPLIB' will be ignored +set_target_properties( + ${PROJECT_NAME}_c + PROPERTIES IMPORTED_LOCATION ${HDDS_LIBRARY_IMPORTED_LOCATION} + IMPORTED_IMPLIB ${HDDS_LIBRARY_OUTPUT}.${HDDS_STATIC_LIBRARY_EXTENSION} +) + +target_include_directories(${PROJECT_NAME}_c INTERFACE + "${HDDS_C_INCLUDE_DIR}" # Allows inclusion as '#include ' +) + +# Expose also hdds_cxx target +if(BUILD_HDDS_CXX) + add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/sdk/cxx") +endif() diff --git a/crates/hdds-c/cbindgen.toml b/crates/hdds-c/cbindgen.toml index 6fbf258..8c9d500 100644 --- a/crates/hdds-c/cbindgen.toml +++ b/crates/hdds-c/cbindgen.toml @@ -2,6 +2,7 @@ language = "C" include_guard = "HDDS_H" +cpp_compat = true header = """ /* * HDDS C FFI Bindings diff --git a/crates/hdds-c/hdds.h b/crates/hdds-c/hdds.h index 9f96453..900c38c 100644 --- a/crates/hdds-c/hdds.h +++ b/crates/hdds-c/hdds.h @@ -844,6 +844,10 @@ typedef struct HddsParticipantConfig { uint8_t PRIVATE[0]; } HddsParticipantConfig; +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + /** * Create a new DDS Participant with default settings (UdpMulticast transport) * @@ -2953,4 +2957,8 @@ enum HddsError hdds_config_set_security(struct HddsParticipantConfig *aConfig, */ struct HddsParticipant *hdds_config_build(struct HddsParticipantConfig *aConfig); +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + #endif /* HDDS_H */ diff --git a/sdk/c/include/hdds.h b/sdk/c/include/hdds.h index fa1cc80..7e29221 100644 --- a/sdk/c/include/hdds.h +++ b/sdk/c/include/hdds.h @@ -847,6 +847,10 @@ typedef struct HddsParticipantConfig { uint8_t PRIVATE[0]; } HddsParticipantConfig; +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + /** * Create a new DDS Participant with default settings (UdpMulticast transport) * @@ -2956,4 +2960,8 @@ enum HddsError hdds_config_set_security(struct HddsParticipantConfig *aConfig, */ struct HddsParticipant *hdds_config_build(struct HddsParticipantConfig *aConfig); +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + #endif /* HDDS_H */ diff --git a/sdk/cxx/CMakeLists.txt b/sdk/cxx/CMakeLists.txt index 82aa495..5af42ac 100644 --- a/sdk/cxx/CMakeLists.txt +++ b/sdk/cxx/CMakeLists.txt @@ -3,58 +3,46 @@ project(hdds_cxx VERSION 0.8.0 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) -# Find hdds-c library -set(HDDS_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../.." CACHE PATH "Path to HDDS root") -set(HDDS_C_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/../c/include" CACHE PATH "Path to hdds-c headers") -set(HDDS_C_LIB "${HDDS_ROOT}/target/release" CACHE PATH "Path to hdds-c library") +option(BUILD_SHARED_LIBS "Build static or shared library" OFF) +option(BUILD_EXAMPLES "Build examples" OFF) +option(BUILD_TESTS "Build tests" OFF) + +# Find thread library +find_package(Threads REQUIRED) # Library -add_library(hdds_cxx STATIC - src/participant.cpp - src/writer.cpp - src/reader.cpp - src/qos.cpp - src/waitset.cpp - src/logging.cpp - src/telemetry.cpp - src/pubsub.cpp +set(HDDS_CXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/hdds_listener.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/hdds.hpp +) +set(HDDS_CXX_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/logging.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/participant.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/pubsub.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/qos.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/reader.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/telemetry.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/waitset.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/writer.cpp ) +add_library(hdds_cxx ${HDDS_CXX_HEADERS} ${HDDS_CXX_SOURCES}) +add_library(hdds::hdds_cxx ALIAS hdds_cxx) + target_include_directories(hdds_cxx PUBLIC $ $ - PRIVATE - ${HDDS_C_INCLUDE} -) - -target_link_directories(hdds_cxx PRIVATE ${HDDS_C_LIB}) -target_link_libraries(hdds_cxx PRIVATE hdds_c pthread dl m) - -# Install -install(TARGETS hdds_cxx - EXPORT hdds_cxx-targets - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib ) -install(DIRECTORY include/ DESTINATION include) - -install(EXPORT hdds_cxx-targets - FILE hdds_cxxTargets.cmake - NAMESPACE hdds:: - DESTINATION lib/cmake/hdds_cxx -) +target_link_libraries(hdds_cxx PUBLIC hdds::hdds_c PRIVATE Threads::Threads ${CMAKE_DL_LIBS}) # Examples -option(BUILD_EXAMPLES "Build examples" ON) if(BUILD_EXAMPLES) add_subdirectory(examples) endif() # Tests -option(BUILD_TESTS "Build tests" ON) if(BUILD_TESTS) enable_testing() add_subdirectory(tests) diff --git a/sdk/cxx/examples/CMakeLists.txt b/sdk/cxx/examples/CMakeLists.txt index bca8a82..7489ad1 100644 --- a/sdk/cxx/examples/CMakeLists.txt +++ b/sdk/cxx/examples/CMakeLists.txt @@ -1,3 +1,2 @@ add_executable(basic_pubsub basic_pubsub.cpp) -target_link_directories(basic_pubsub PRIVATE ${HDDS_C_LIB}) -target_link_libraries(basic_pubsub hdds_cxx hdds_c pthread dl m) +target_link_libraries(basic_pubsub PRIVATE hdds::hdds_cxx)