From 8e234e933e0e469f5123b8a6881342654bb4f156 Mon Sep 17 00:00:00 2001 From: Andrew Lilley Brinker <andrewbrinker@me.com> Date: Mon, 22 Jun 2020 06:29:28 -0700 Subject: [PATCH] Add cmake and an example (#23) Adds CMake to both power Cargo compilation and generation of header files with cbindgen, and enable easy use of the FFI from other languages with a more accessible build system. --- rust/pact_matching_ffi/.gitignore | 1 + rust/pact_matching_ffi/CMakeLists.txt | 299 ++++++++++++++++++ rust/pact_matching_ffi/Cargo.toml | 2 +- rust/pact_matching_ffi/cbindgen.toml | 103 ++++++ rust/pact_matching_ffi/cmake/FindCargo.cmake | 20 ++ .../cmake/FindCbindgen.cmake | 20 ++ .../cmake/PactMatchingFFIConfig.cmake.in | 27 ++ rust/pact_matching_ffi/example/.gitignore | 1 + rust/pact_matching_ffi/example/CMakeLists.txt | 85 +++++ rust/pact_matching_ffi/example/src/main.c | 41 +++ rust/pact_matching_ffi/include/.gitignore | 1 + rust/pact_matching_ffi/include/.gitkeep | 0 12 files changed, 599 insertions(+), 1 deletion(-) create mode 100644 rust/pact_matching_ffi/.gitignore create mode 100644 rust/pact_matching_ffi/CMakeLists.txt create mode 100644 rust/pact_matching_ffi/cbindgen.toml create mode 100644 rust/pact_matching_ffi/cmake/FindCargo.cmake create mode 100644 rust/pact_matching_ffi/cmake/FindCbindgen.cmake create mode 100644 rust/pact_matching_ffi/cmake/PactMatchingFFIConfig.cmake.in create mode 100644 rust/pact_matching_ffi/example/.gitignore create mode 100644 rust/pact_matching_ffi/example/CMakeLists.txt create mode 100644 rust/pact_matching_ffi/example/src/main.c create mode 100644 rust/pact_matching_ffi/include/.gitignore create mode 100644 rust/pact_matching_ffi/include/.gitkeep diff --git a/rust/pact_matching_ffi/.gitignore b/rust/pact_matching_ffi/.gitignore new file mode 100644 index 000000000..0ec9e7f98 --- /dev/null +++ b/rust/pact_matching_ffi/.gitignore @@ -0,0 +1 @@ +/build* diff --git a/rust/pact_matching_ffi/CMakeLists.txt b/rust/pact_matching_ffi/CMakeLists.txt new file mode 100644 index 000000000..e565b460f --- /dev/null +++ b/rust/pact_matching_ffi/CMakeLists.txt @@ -0,0 +1,299 @@ +################################################################################################# +# CMAKE VERSION +################################################################################################# + +# Set the minimum to 3.15. This is arbitrary and we should probably try to +# test everything with older CMake versions once this is all written, to +# figure out an actual lower-bound. +cmake_minimum_required(VERSION 3.15...3.17) + +# Set policies appropriately, so it knows when to warn about policy +# violations. +if(${CMAKE_VERSION} VERSION_LESS 3.17) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.17) +endif() + +################################################################################################# +# CONFIG FILES +# +# Set the location of various config files we'll use throughout. +################################################################################################# + +# The path to the cargo config file. +set(CARGO_CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/Cargo.toml") + +# The path to the cbindgen config file. +set(CBINDGEN_CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cbindgen.toml") + +################################################################################################# +# PROJECT NAME +# +# This is pulled from the `Cargo.toml` file. +################################################################################################# + +# Regex for 'name = "<name>"' +set(NAME_REGEX "name = \"(.+)\"") + +# Read in the line containing the name +file(STRINGS ${CARGO_CONFIG_FILE} NAME_STRING REGEX ${NAME_REGEX}) + +# Pick out just the name +string(REGEX REPLACE ${NAME_REGEX} "\\1" NAME_STRING "${NAME_STRING}") + +################################################################################################# +# PROJECT VERSION +# +# This is pulled from the `Cargo.toml` file. +################################################################################################# + +# Regex for 'version = "<version>"' +set(VERSION_REGEX "^version = \"(.+)\"$") + +# Read in the line containing the version +file(STRINGS ${CARGO_CONFIG_FILE} VERSION_STRING REGEX ${VERSION_REGEX}) + +# Pick out just the version +string(REGEX REPLACE ${VERSION_REGEX} "\\1" VERSION_STRING "${VERSION_STRING}") + +################################################################################################# +# PROJECT DESCRIPTION +# +# This is pulled from the `Cargo.toml` file. +################################################################################################# + +# Regex for 'description = "<description>"' +set(DESCRIPTION_REGEX "description = \"(.+)\"") + +# Read in the line containing the description +file(STRINGS ${CARGO_CONFIG_FILE} DESCRIPTION_STRING REGEX ${DESCRIPTION_REGEX}) + +# Pick out just the description +string(REGEX REPLACE ${DESCRIPTION_REGEX} "\\1" DESCRIPTION_STRING "${DESCRIPTION_STRING}") + +################################################################################################# +# PROJECT DECLARATION +################################################################################################# + +# Print message indicating we found the crate information. +message("Found crate ${NAME_STRING} (version ${VERSION_STRING}): ${DESCRIPTION_STRING}") + +# Define the project for the current file. +project( + ${NAME_STRING} + VERSION ${VERSION_STRING} + DESCRIPTION ${DESCRIPTION_STRING} + LANGUAGES NONE) + +################################################################################################# +# CMAKE UTILITIES +# +# Add CMake utilities for finding Cargo and Cbindgen to the module path. +################################################################################################# + +set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH}) + +################################################################################################# +# OUT OF SOURCE BUILDS +# +# Require out-of-source builds for this project. It keeps things much simpler +# and cleaner. +################################################################################################# + +# Set a path to the CMake config (this file) +file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) + +# Define the error message to potentially be printed. +set(OOS_MSG "\ +You cannot build in a source directory (or any directory with a CMakeLists.txt file). \ +Please make a build subdirectory. \ +Feel free to remove CMakeCache.txt and CMakeFiles. +") + +# If that file path exists, we're doing an in-source build, so we should exit with a fatal +# error complaining only out-of-source builds are supported. +if(EXISTS ${LOC_PATH}) + message(FATAL_ERROR ${OOS_MSG}) +endif() + +################################################################################################# +# DEFAULT BUILD TYPE +# +# Make release the default build type +################################################################################################# + +# The default build type is Release. +set(default_build_type "Release") + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + # Tell the user they're getting the default build type. + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + + # Cache the build type. + set(CMAKE_BUILD_TYPE ${default_build_type} CACHE STRING "Choose the type of build." FORCE) + + # Set the possible values of build type + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release") +endif() + +################################################################################################# +# Find Cargo & Cbindgen +# +# Uses custom finders to locate the cargo and cbindgen executables and identify their versions +################################################################################################# + +# Uses the finder specified in `cmake/FindCargo.cmake` +find_package(Cargo REQUIRED) + +# Uses the finder specified in `cmake/FindCbindgen.cmake` +find_package(Cbindgen REQUIRED) + +################################################################################################# +# VARIABLES +# +# Sets important variables to be used by the custom targets. +################################################################################################# + +# Set cargo build type flag, and name of the folder containing the library file, +# based on the configured build type. +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(CARGO_BUILD_TYPE "") + set(TARGET_TYPE "debug") +else() + set(CARGO_BUILD_TYPE "--release") + set(TARGET_TYPE "release") +endif() + +# There could be something more generic here using `cargo metadata` output to discover +# the workspace root and get the target dir from that, and in a more general context +# that's what ought to be done, but for now we know where the target dir is, and should +# just reuse it. +set(CARGO_TARGET_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../target") + +# The name of the crate itself. +set(CRATE_NAME ${NAME_STRING}) + +# Set the CARGO_LIBRARY_NAME based on whether we're on Windows +if(WIN32) + set(CARGO_LIBRARY_NAME "${CRATE_NAME}.dll") +else() + set(CARGO_LIBRARY_NAME "${CRATE_NAME}.a") +endif() + +# The path to the library file. +set(CARGO_LIBRARY_FILE "${CARGO_TARGET_DIR}/${TARGET_TYPE}/${CARGO_LIBRARY_NAME}") + +# On Windows, dynamic linking requires both a .dll file (which will be dynamically +# linked), and a library file (which describes _how_ to link to the DLL, and will +# itself be statically linked). We need to make sure both are included on installation. +# +# For Rust specifically, the name of the .lib file is the name of the .dll file with +# .lib appended (so the extension is .dll.lib). +if(WIN32) + set(CARGO_INSTALL_FILES ${CARGO_LIBRARY_FILE} "${CARGO_LIBRARY_FILE}.lib") +else() + set(CARGO_INSTALL_FILES ${CARGO_LIBRARY_FILE}) +endif() + +# Name of the header file. +set(CBINDGEN_HEADER_NAME "pact_matching.h") + +# Path to the header file. +set(CBINDGEN_HEADER_FILE "${CMAKE_CURRENT_SOURCE_DIR}/include/${CBINDGEN_HEADER_NAME}") + +################################################################################################# +# LIBRARY +# +# Defines the target for building the library file. +################################################################################################# + +# Defines the cargo command to build the library file. +add_custom_command( + OUTPUT ${CARGO_LIBRARY_FILE} + COMMAND + ${CARGO_EXECUTABLE} + build + ${CARGO_BUILD_TYPE} + --target-dir ${CARGO_TARGET_DIR} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# Add target for the library file +add_custom_target(build_library ALL + COMMENT "Building library file with cargo" + DEPENDS ${CARGO_LIBRARY_FILE}) + +# Teach CMake to install the library file(s) built by the pact_matching_ffi target +install(FILES ${CARGO_INSTALL_FILES} TYPE LIB) + +################################################################################################# +# HEADER +# +# Defines the target for generating the header file. +################################################################################################# + +# Defines the cbindgen command to generate the header file. +add_custom_command( + OUTPUT ${CBINDGEN_HEADER_FILE} + COMMAND + ${CBINDGEN_EXECUTABLE} + --config ${CBINDGEN_CONFIG_FILE} + --crate ${CRATE_NAME} + --output ${CBINDGEN_HEADER_FILE} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +# Add target for the header file +add_custom_target(generate_header ALL + COMMENT "Generating header file with cbindgen" + DEPENDS ${CBINDGEN_HEADER_FILE}) + +# Teach CMake to install the header file built by the generate_header target +install(FILES "${CBINDGEN_HEADER_FILE}" TYPE INCLUDE) + +################################################################################################# +# PACKAGE FILES +# +# Defines packaging information for the current project, so it can be used via `find_package`. +################################################################################################# + +# Bring in some functions to help generate the config files. +include(CMakePackageConfigHelpers) + +# Set the name of the final package configuration file. +set(PACKAGE_CONFIG_NAME "PactMatchingFfiConfig.cmake") + +# Set the name of the final package version file. +set(PACKAGE_VERSION_NAME "PactMatchingFfiConfigVersion.cmake") + +# Set the path to the package configuration input file. +set(PACKAGE_CONFIG_INPUT_FILE "cmake/${PACKAGE_CONFIG_NAME}.in") + +# Set the path to the package configuration output file. +set(PACKAGE_CONFIG_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_CONFIG_NAME}") + +# Set locations in the installation prefix to put the relevant files. +set(INCLUDE_INSTALL_DIR "include") +set(LIB_INSTALL_DIR "lib") + +# Relative path (within install prefix) to place the configuration file. +set(PACKAGE_CONFIG_INSTALL_DIR "${LIB_INSTALL_DIR}/cmake") + +# Set the path to the generated package version file. +set(PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/${PACKAGE_VERSION_NAME}") + +# Generate the configuration file from the input and put it in the right place +configure_package_config_file( + # Input file + ${PACKAGE_CONFIG_INPUT_FILE} + # Output file + ${PACKAGE_CONFIG_FILE} + # Installation destination within the install prefix dir + INSTALL_DESTINATION ${PACKAGE_CONFIG_INSTALL_DIR} + # Variables to pass along to the input file + PATH_VARS INCLUDE_INSTALL_DIR LIB_INSTALL_DIR) + +# Generate the version file based on the project version info. +write_basic_package_version_file(${PACKAGE_VERSION_FILE} COMPATIBILITY SameMajorVersion) + +# Install config files in the proper directory. +install(FILES ${PACKAGE_CONFIG_FILE} ${PACKAGE_VERSION_FILE} DESTINATION ${PACKAGE_CONFIG_INSTALL_DIR}) diff --git a/rust/pact_matching_ffi/Cargo.toml b/rust/pact_matching_ffi/Cargo.toml index 9bcbf89be..f4fa8ef44 100644 --- a/rust/pact_matching_ffi/Cargo.toml +++ b/rust/pact_matching_ffi/Cargo.toml @@ -22,4 +22,4 @@ log = "0.4.8" serde_json = "1.0.51" [lib] -crate-type = ["cdylib", "staticlib", "rlib"] +crate-type = ["cdylib"] diff --git a/rust/pact_matching_ffi/cbindgen.toml b/rust/pact_matching_ffi/cbindgen.toml new file mode 100644 index 000000000..595f4fcb5 --- /dev/null +++ b/rust/pact_matching_ffi/cbindgen.toml @@ -0,0 +1,103 @@ +# This is a template cbindgen.toml file with all of the default values. +# Some values are commented out because their absence is the real default. +# +# See https://github.com/eqrion/cbindgen/blob/master/docs.md#cbindgentoml +# for detailed documentation of every option here. + +language = "C" + +############## Options for Wrapping the Contents of the Header ################# + +# header = "/* Text to put at the beginning of the generated file. Probably a license. */" +# trailer = "/* Text to put at the end of the generated file */" +include_guard = "pact_matching_ffi_h" +autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" +include_version = true +namespace = "pact_matching" +namespaces = [] +using_namespaces = [] +sys_includes = [] +includes = [] +no_includes = false +cpp_compat = true + +############################ Code Style Options ################################ + +braces = "SameLine" +line_length = 100 +tab_width = 2 +documentation_style = "auto" + +############################# Codegen Options ################################## + +style = "both" + +[defines] +# "target_os = freebsd" = "DEFINE_FREEBSD" +# "feature = serde" = "DEFINE_SERDE" + +[export] +include = [] +exclude = [] +# prefix = "CAPI_" +item_types = [] +renaming_overrides_prefixing = false + +[export.rename] + +[export.body] + +[fn] +rename_args = "None" +# must_use = "MUST_USE_FUNC" +# prefix = "START_FUNC" +# postfix = "END_FUNC" +args = "auto" +sort_by = "None" + +[struct] +rename_fields = "None" +# must_use = "MUST_USE_STRUCT" +derive_constructor = false +derive_eq = false +derive_neq = false +derive_lt = false +derive_lte = false +derive_gt = false +derive_gte = false + +[enum] +rename_variants = "None" +# must_use = "MUST_USE_ENUM" +add_sentinel = false +prefix_with_name = true +derive_helper_methods = false +derive_const_casts = false +derive_mut_casts = false +# cast_assert_name = "ASSERT" +derive_tagged_enum_destructor = false +derive_tagged_enum_copy_constructor = false +enum_class = true +private_default_tagged_enum_constructor = false + +[const] +allow_static_const = true +allow_constexpr = false + +[macro_expansion] +bitflags = false + +############## Options for How Your Rust library Should Be Parsed ############## + +[parse] +parse_deps = true +include = ["pact_matching"] +exclude = [] +clean = false +extra_bindings = [] + +[parse.expand] +crates = [] +all_features = false +default_features = true +features = [] diff --git a/rust/pact_matching_ffi/cmake/FindCargo.cmake b/rust/pact_matching_ffi/cmake/FindCargo.cmake new file mode 100644 index 000000000..1f0c2e482 --- /dev/null +++ b/rust/pact_matching_ffi/cmake/FindCargo.cmake @@ -0,0 +1,20 @@ + +# Find Cargo, possibly in ~/.cargo. Make sure to check in any `bin` subdirectories +# on the program search path +find_program(CARGO_EXECUTABLE cargo PATHS "$ENV{HOME}/.cargo" PATH_SUFFIXES bin) + +# If we found it, see if we can get its version. +if(CARGO_EXECUTABLE) + execute_process(COMMAND ${CARGO_EXECUTABLE} -V OUTPUT_VARIABLE CARGO_VERSION_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(CARGO_VERSION_OUTPUT MATCHES "cargo ([0-9]+\\.[0-9]+\\.[0-9]+).*") + set(CARGO_VERSION ${CMAKE_MATCH_1}) + endif() +endif() + +# Hides the CARGO_EXECUTABLE variable unless advanced variables are requested +mark_as_advanced(CARGO_EXECUTABLE) + +# Require that we find both the executable and the version. Otherwise error out. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Cargo REQUIRED_VARS CARGO_EXECUTABLE CARGO_VERSION VERSION_VAR CARGO_VERSION) diff --git a/rust/pact_matching_ffi/cmake/FindCbindgen.cmake b/rust/pact_matching_ffi/cmake/FindCbindgen.cmake new file mode 100644 index 000000000..b0431be3b --- /dev/null +++ b/rust/pact_matching_ffi/cmake/FindCbindgen.cmake @@ -0,0 +1,20 @@ + +# Find Cbindgen, possibly in ~/.cargo. Make sure to check in any `bin` subdirectories +# on the program search path +find_program(CBINDGEN_EXECUTABLE cbindgen PATHS "$ENV{HOME}/.cargo" PATH_SUFFIXES bin) + +# If we found it, see if we can get its version. +if(CBINDGEN_EXECUTABLE) + execute_process(COMMAND ${CBINDGEN_EXECUTABLE} -V OUTPUT_VARIABLE CBINDGEN_VERSION_OUTPUT OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(CBINDGEN_VERSION_OUTPUT MATCHES "cbindgen ([0-9]+\\.[0-9]+\\.[0-9]+).*") + set(CBINDGEN_VERSION ${CMAKE_MATCH_1}) + endif() +endif() + +# Hides the CBINDGEN_EXECUTABLE variable unless advanced variables are requested +mark_as_advanced(CBINDGEN_EXECUTABLE) + +# Require that we find both the executable and the version. Otherwise error out. +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Cbindgen REQUIRED_VARS CBINDGEN_EXECUTABLE CBINDGEN_VERSION VERSION_VAR CBINDGEN_VERSION) diff --git a/rust/pact_matching_ffi/cmake/PactMatchingFFIConfig.cmake.in b/rust/pact_matching_ffi/cmake/PactMatchingFFIConfig.cmake.in new file mode 100644 index 000000000..df9860985 --- /dev/null +++ b/rust/pact_matching_ffi/cmake/PactMatchingFFIConfig.cmake.in @@ -0,0 +1,27 @@ + +@PACKAGE_INIT@ + +set_and_check(PactMatchingFfi_INCLUDE_DIRS "@PACKAGE_INCLUDE_INSTALL_DIR@") + +if(WIN32) + set(LIB_NAME "@PACKAGE_LIB_INSTALL_DIR@/pact_matching_ffi.dll") + set(IMPORT_NAME "${LIB_NAME}.lib") +else() + set(LIB_NAME "@PACKAGE_LIB_INSTALL_DIR@/pact_matching_ffi.a") + set(IMPORT_NAME "") +endif() + +set(HEADER_NAME "@PACKAGE_INCLUDE_INSTALL_DIR@/pact_matching.h") + +set_and_check(PactMatchingFfi_LIBRARIES ${LIB_NAME} ${IMPORT_NAME}) + +add_library(PactMatchingFfi SHARED IMPORTED) + +set_target_properties(PactMatchingFfi PROPERTIES + IMPORTED_LOCATION ${LIB_NAME} + IMPORTED_IMPLIB ${IMPORT_NAME} + INTERFACE_INCLUDE_DIRECTORIES @PACKAGE_INCLUDE_INSTALL_DIR@ + INSTALL_RPATH @PACKAGE_LIB_INSTALL_DIR@ + BUILD_RPATH @PACKAGE_LIB_INSTALL_DIR@) + +check_required_components(PactMatchingFfi) diff --git a/rust/pact_matching_ffi/example/.gitignore b/rust/pact_matching_ffi/example/.gitignore new file mode 100644 index 000000000..567609b12 --- /dev/null +++ b/rust/pact_matching_ffi/example/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/rust/pact_matching_ffi/example/CMakeLists.txt b/rust/pact_matching_ffi/example/CMakeLists.txt new file mode 100644 index 000000000..eee02b890 --- /dev/null +++ b/rust/pact_matching_ffi/example/CMakeLists.txt @@ -0,0 +1,85 @@ +################################################################################################# +# CMAKE VERSION +################################################################################################# + +# Set the minimum to 3.15. This is arbitrary and we should probably try to +# test everything with older CMake versions once this is all written, to +# figure out an actual lower-bound. +cmake_minimum_required(VERSION 3.15...3.17) + +# Set policies appropriately, so it knows when to warn about policy +# violations. +if(${CMAKE_VERSION} VERSION_LESS 3.17) + cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) +else() + cmake_policy(VERSION 3.17) +endif() + +################################################################################################# +# PROJECT DECLARATION +################################################################################################# + +project(C_EXAMPLE_1 + VERSION "0.1.0" + DESCRIPTION "A basic example of a C consumer for the pact matching FFI" + LANGUAGES C) + +################################################################################################# +# OUT OF SOURCE BUILDS +# +# Require out-of-source builds for this project. It keeps things much simpler +# and cleaner. +################################################################################################# + +# Set a path to the CMake config (this file) +file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH) + +# Define the error message to potentially be printed. +set(OOS_MSG "\ +You cannot build in a source directory (or any directory with a CMakeLists.txt file). \ +Please make a build subdirectory. \ +Feel free to remove CMakeCache.txt and CMakeFiles. +") + +# If that file path exists, we're doing an in-source build, so we should exit with a fatal +# error complaining only out-of-source builds are supported. +if(EXISTS ${LOC_PATH}) + message(FATAL_ERROR ${OOS_MSG}) +endif() + +################################################################################################# +# DEFAULT BUILD TYPE +# +# Make release the default build type +################################################################################################# + +set(default_build_type "Release") +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + message(STATUS "Setting build type to '${default_build_type}' as none was specified.") + set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE STRING "Choose the type of build." FORCE) + # Set the possible values of build type + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release") +endif() + +################################################################################################# +# FIND PACT MATCHING FFI +# +# This ensures CMake can find the pact matching FFI library file +################################################################################################# + +# Sets the search path to the location of the package config +get_filename_component(REAL_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/.." ABSOLUTE) +set(SEARCH_PATH "${REAL_ROOT}/build/install/lib/cmake") + +# Find the pact matching FFI package and load the imported target +find_package(PactMatchingFfi REQUIRED CONFIG PATHS ${SEARCH_PATH}) + +################################################################################################# +# BUILD +################################################################################################# + +# Define the executable +add_executable(example src/main.c) + +# Link to pact matching FFI +target_link_libraries(example PRIVATE PactMatchingFfi) diff --git a/rust/pact_matching_ffi/example/src/main.c b/rust/pact_matching_ffi/example/src/main.c new file mode 100644 index 000000000..b322022d3 --- /dev/null +++ b/rust/pact_matching_ffi/example/src/main.c @@ -0,0 +1,41 @@ + +#include "pact_matching.h" +#include <stdlib.h> +#include <stdio.h> + +#define ERROR_MSG_LEN 256 + +int main(void) { + logger_init(); + logger_attach_sink("stdout", LevelFilter_Trace); + logger_apply(); + + Message *msg = message_new(); + int error = message_delete(msg); + + if (error == EXIT_FAILURE) { + char error_msg[ERROR_MSG_LEN]; + + int error = get_error_message(error_msg, ERROR_MSG_LEN); + + printf("%s\n", error_msg); + + return EXIT_FAILURE; + } + + char *json_str = "{\ + \"description\": \"String\",\ + \"providerState\": \"provider state\",\ + \"matchingRules\": {}\ + }"; + Message *msg_json = message_from_json(0, json_str, PactSpecification_V3); + + if (NULL == msg_json) { + char error_msg[ERROR_MSG_LEN]; + int error = get_error_message(error_msg, ERROR_MSG_LEN); + printf("%s\n", error_msg); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/rust/pact_matching_ffi/include/.gitignore b/rust/pact_matching_ffi/include/.gitignore new file mode 100644 index 000000000..aec901578 --- /dev/null +++ b/rust/pact_matching_ffi/include/.gitignore @@ -0,0 +1 @@ +pact_matching.h diff --git a/rust/pact_matching_ffi/include/.gitkeep b/rust/pact_matching_ffi/include/.gitkeep new file mode 100644 index 000000000..e69de29bb