From 5a66ba96d0b3d93afc4164a8a9c71949f4cee64f Mon Sep 17 00:00:00 2001 From: TheMarpe Date: Tue, 29 Jun 2021 12:09:35 +0200 Subject: [PATCH 1/4] Added CMake support --- CMakeLists.txt | 56 ++++ cmake/modules/FindGMock.cmake | 515 ++++++++++++++++++++++++++++++++ docs/getting-started.md | 17 ++ examples/CMakeLists.txt | 33 ++ examples/shared.py | 7 +- test/CMakeLists.txt | 28 ++ test/integration/CMakeLists.txt | 25 ++ 7 files changed, 680 insertions(+), 1 deletion(-) create mode 100644 CMakeLists.txt create mode 100644 cmake/modules/FindGMock.cmake create mode 100644 examples/CMakeLists.txt create mode 100644 test/CMakeLists.txt create mode 100644 test/integration/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..82e64b7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required(VERSION 3.2) +set(TARGET_NAME "libnop") +project(${TARGET_NAME} LANGUAGES CXX) + +# Set modules path +set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) + +# Build tests +option(LIBNOP_BUILD_TESTS "Build libnop tests" OFF) +# Build examples +option(LIBNOP_BUILD_EXAMPLES "Build libnop examples" OFF) + +add_library(${TARGET_NAME} INTERFACE) +# Set C++14 version +if (${CMAKE_VERSION} VERSION_LESS "3.8.0") + target_compile_features(${TARGET_NAME} INTERFACE cxx_generic_lambdas) +else() + target_compile_features(${TARGET_NAME} INTERFACE cxx_std_14) +endif() + +target_include_directories(${TARGET_NAME} INTERFACE + $ + $ +) + +# Tests +if(LIBNOP_BUILD_TESTS) + # Add CMake testing infrastructure + include(CTest) + enable_testing() + add_subdirectory(test) +endif() + +# Examples +if(LIBNOP_BUILD_EXAMPLES) + add_subdirectory(examples) +endif() + +include(GNUInstallDirs) +install(TARGETS ${TARGET_NAME} + EXPORT "${TARGET_NAME}Config" + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +set(config_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${TARGET_NAME}") +export(TARGETS + ${TARGET_NAME} + FILE "${config_install_dir}/${TARGET_NAME}Config.cmake" +) +install(EXPORT + "${TARGET_NAME}Config" + DESTINATION "${config_install_dir}" +) diff --git a/cmake/modules/FindGMock.cmake b/cmake/modules/FindGMock.cmake new file mode 100644 index 0000000..6cf9006 --- /dev/null +++ b/cmake/modules/FindGMock.cmake @@ -0,0 +1,515 @@ +# Get the Google C++ Mocking Framework. +# (This file is almost an copy of the original FindGTest.cmake file, +# altered to download and compile GMock and GTest if not found +# in GMOCK_ROOT or GTEST_ROOT respectively, +# feel free to use it as it is or modify it for your own needs.) +# +# Defines the following variables: +# +# GMOCK_FOUND - Found or got the Google Mocking framework +# GTEST_FOUND - Found or got the Google Testing framework +# GMOCK_INCLUDE_DIRS - GMock include directory +# GTEST_INCLUDE_DIRS - GTest include direcotry +# +# Also defines the library variables below as normal variables +# +# GMOCK_BOTH_LIBRARIES - Both libgmock & libgmock_main +# GMOCK_LIBRARIES - libgmock +# GMOCK_MAIN_LIBRARIES - libgmock-main +# +# GTEST_BOTH_LIBRARIES - Both libgtest & libgtest_main +# GTEST_LIBRARIES - libgtest +# GTEST_MAIN_LIBRARIES - libgtest_main +# +# Accepts the following variables as input: +# +# GMOCK_ROOT - The root directory of the gmock install prefix +# GTEST_ROOT - The root directory of the gtest install prefix +# GMOCK_SRC_DIR -The directory of the gmock sources +# GMOCK_VER - The version of the gmock sources to be downloaded +# +#----------------------- +# Example Usage: +# +# set(GMOCK_ROOT "~/gmock") +# find_package(GMock REQUIRED) +# include_directories(${GMOCK_INCLUDE_DIRS}) +# +# add_executable(foo foo.cc) +# target_link_libraries(foo ${GMOCK_BOTH_LIBRARIES}) +# +#============================================================================= +# Copyright (c) 2016 Michel Estermann +# Copyright (c) 2016 Kamil Strzempowicz +# Copyright (c) 2011 Matej Svec +# +# CMake - Cross Platform Makefile Generator +# Copyright 2000-2016 Kitware, Inc. +# Copyright 2000-2011 Insight Software Consortium +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the names of Kitware, Inc., the Insight Software Consortium, +# nor the names of their contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# ------------------------------------------------------------------------------ +# +# The above copyright and license notice applies to distributions of +# CMake in source and binary form. Some source files contain additional +# notices of original copyright by their contributors; see each source +# for details. Third-party software packages supplied with CMake under +# compatible licenses provide their own copyright notices documented in +# corresponding subdirectories. +# +# ------------------------------------------------------------------------------ +# +# CMake was initially developed by Kitware with the following sponsorship: +# +# * National Library of Medicine at the National Institutes of Health +# as part of the Insight Segmentation and Registration Toolkit (ITK). +# +# * US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel +# Visualization Initiative. +# +# * National Alliance for Medical Image Computing (NAMIC) is funded by the +# National Institutes of Health through the NIH Roadmap for Medical Research, +# Grant U54 EB005149. +# +# * Kitware, Inc. +#============================================================================= +# Thanks to Daniel Blezek for the GTEST_ADD_TESTS code + +function(gtest_add_tests executable extra_args) + if(NOT ARGN) + message(FATAL_ERROR "Missing ARGN: Read the documentation for GTEST_ADD_TESTS") + endif() + if(ARGN STREQUAL "AUTO") + # obtain sources used for building that executable + get_property(ARGN TARGET ${executable} PROPERTY SOURCES) + endif() + set(gtest_case_name_regex ".*\\( *([A-Za-z_0-9]+) *, *([A-Za-z_0-9]+) *\\).*") + set(gtest_test_type_regex "(TYPED_TEST|TEST_?[FP]?)") + foreach(source ${ARGN}) + file(READ "${source}" contents) + string(REGEX MATCHALL "${gtest_test_type_regex} *\\(([A-Za-z_0-9 ,]+)\\)" found_tests ${contents}) + foreach(hit ${found_tests}) + string(REGEX MATCH "${gtest_test_type_regex}" test_type ${hit}) + + # Parameterized tests have a different signature for the filter + if("x${test_type}" STREQUAL "xTEST_P") + string(REGEX REPLACE ${gtest_case_name_regex} "*/\\1.\\2/*" test_name ${hit}) + elseif("x${test_type}" STREQUAL "xTEST_F" OR "x${test_type}" STREQUAL "xTEST") + string(REGEX REPLACE ${gtest_case_name_regex} "\\1.\\2" test_name ${hit}) + elseif("x${test_type}" STREQUAL "xTYPED_TEST") + string(REGEX REPLACE ${gtest_case_name_regex} "\\1/*.\\2" test_name ${hit}) + else() + message(WARNING "Could not parse GTest ${hit} for adding to CTest.") + continue() + endif() + add_test(NAME ${test_name} COMMAND ${executable} --gtest_filter=${test_name} ${extra_args}) + endforeach() + endforeach() +endfunction() + +function(_append_debugs _endvar _library) + if(${_library} AND ${_library}_DEBUG) + set(_output optimized ${${_library}} debug ${${_library}_DEBUG}) + else() + set(_output ${${_library}}) + endif() + set(${_endvar} ${_output} PARENT_SCOPE) +endfunction() + +function(_gmock_find_library _name) + find_library(${_name} + NAMES ${ARGN} + HINTS + ENV GMOCK_ROOT + ${GMOCK_ROOT} + PATH_SUFFIXES ${_gmock_libpath_suffixes} + ) + mark_as_advanced(${_name}) +endfunction() + +function(_gtest_find_library _name) + find_library(${_name} + NAMES ${ARGN} + HINTS + ENV GTEST_ROOT + ${GTEST_ROOT} + PATH_SUFFIXES ${_gtest_libpath_suffixes} + ) + mark_as_advanced(${_name}) +endfunction() + +if(NOT DEFINED GMOCK_MSVC_SEARCH) + set(GMOCK_MSVC_SEARCH MD) +endif() + +set(_gmock_libpath_suffixes lib) +set(_gtest_libpath_suffixes lib) +if(MSVC) + if(GMOCK_MSVC_SEARCH STREQUAL "MD") + list(APPEND _gmock_libpath_suffixes + msvc/gmock-md/Debug + msvc/gmock-md/Release) + list(APPEND _gtest_libpath_suffixes + msvc/gtest-md/Debug + msvc/gtest-md/Release) + elseif(GMOCK_MSVC_SEARCH STREQUAL "MT") + list(APPEND _gmock_libpath_suffixes + msvc/gmock/Debug + msvc/gmock/Release) + list(APPEND _gtest_libpath_suffixes + msvc/gtest/Debug + msvc/gtest/Release) + endif() +endif() + +find_path(GMOCK_INCLUDE_DIR gmock/gmock.h + HINTS + $ENV{GMOCK_ROOT}/include + ${GMOCK_ROOT}/include + ) +mark_as_advanced(GMOCK_INCLUDE_DIR) + +find_path(GTEST_INCLUDE_DIR gtest/gtest.h + HINTS + $ENV{GTEST_ROOT}/include + ${GTEST_ROOT}/include + ) +mark_as_advanced(GTEST_INCLUDE_DIR) + +if(MSVC AND GMOCK_MSVC_SEARCH STREQUAL "MD") + # The provided /MD project files for Google Mock add -md suffixes to the + # library names. + _gmock_find_library(GMOCK_LIBRARY gmock-md gmock) + _gmock_find_library(GMOCK_LIBRARY_DEBUG gmock-mdd gmockd) + _gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main-md gmock_main) + _gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_main-mdd gmock_maind) + + _gtest_find_library(GTEST_LIBRARY gtest-md gtest) + _gtest_find_library(GTEST_LIBRARY_DEBUG gtest-mdd gtestd) + _gtest_find_library(GTEST_MAIN_LIBRARY gtest_main-md gtest_main) + _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_main-mdd gtest_maind) +else() + _gmock_find_library(GMOCK_LIBRARY gmock) + _gmock_find_library(GMOCK_LIBRARY_DEBUG gmockd) + _gmock_find_library(GMOCK_MAIN_LIBRARY gmock_main) + _gmock_find_library(GMOCK_MAIN_LIBRARY_DEBUG gmock_maind) + + _gtest_find_library(GTEST_LIBRARY gtest) + _gtest_find_library(GTEST_LIBRARY_DEBUG gtestd) + _gtest_find_library(GTEST_MAIN_LIBRARY gtest_main) + _gtest_find_library(GTEST_MAIN_LIBRARY_DEBUG gtest_maind) +endif() + +if(NOT TARGET GTest::GTest) + add_library(GTest::GTest UNKNOWN IMPORTED) +endif() +if(NOT TARGET GTest::Main) + add_library(GTest::Main UNKNOWN IMPORTED) +endif() + +if(NOT TARGET GMock::GMock) + add_library(GMock::GMock UNKNOWN IMPORTED) +endif() + +if(NOT TARGET GMock::Main) + add_library(GMock::Main UNKNOWN IMPORTED) +endif() + +set(GMOCK_LIBRARY_EXISTS OFF) +set(GTEST_LIBRARY_EXISTS OFF) + +if(EXISTS "${GMOCK_LIBRARY}" OR EXISTS "${GMOCK_LIBRARY_DEBUG}" AND GMOCK_INCLUDE_DIR) + set(GMOCK_LIBRARY_EXISTS ON) +endif() + +if(EXISTS "${GTEST_LIBRARY}" OR EXISTS "${GTEST_LIBRARY_DEBUG}" AND GTEST_INCLUDE_DIR) + set(GTEST_LIBRARY_EXISTS ON) +endif() + +if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) + + include(ExternalProject) + + if(GTEST_USE_STATIC_LIBS) + set(GTEST_CMAKE_ARGS -Dgtest_force_shared_crt:BOOL=ON -DBUILD_SHARED_LIBS=OFF) + if(BUILD_SHARED_LIBS) + list(APPEND GTEST_CMAKE_ARGS + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + -Dgtest_hide_internal_symbols=ON + -DCMAKE_CXX_VISIBILITY_PRESET=hidden + -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON + -DCMAKE_POLICY_DEFAULT_CMP0063=NEW + ) + endif() + set(GTEST_LIBRARY_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) + else() + set(GTEST_CMAKE_ARGS -DBUILD_SHARED_LIBS=ON) + set(GTEST_LIBRARY_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX}) + endif() + if(WIN32) + list(APPEND GTEST_CMAKE_ARGS -Dgtest_disable_pthreads=ON) + endif() + + if("${GMOCK_SRC_DIR}" STREQUAL "") + message(STATUS "Downloading GMock / GTest version ${GMOCK_VER} from git") + if("${GMOCK_VER}" STREQUAL "1.6.0" OR "${GMOCK_VER}" STREQUAL "1.7.0") + set(GTEST_BIN_DIR "${GMOCK_ROOT}/src/gtest-build") + set(GTEST_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_MAIN_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + mark_as_advanced(GTEST_LIBRARY) + mark_as_advanced(GTEST_MAIN_LIBRARY) + + externalproject_add( + gtest + GIT_REPOSITORY "https://github.com/google/googletest.git" + GIT_TAG "release-${GMOCK_VER}" + PREFIX ${GMOCK_ROOT} + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON + CMAKE_ARGS + ${GTEST_CMAKE_ARGS} + BINARY_DIR ${GTEST_BIN_DIR} + BUILD_BYPRODUCTS + "${GTEST_LIBRARY}" + "${GTEST_MAIN_LIBRARY}" + ) + + set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build") + set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + mark_as_advanced(GMOCK_LIBRARY) + mark_as_advanced(GMOCK_MAIN_LIBRARY) + + externalproject_add( + gmock + GIT_REPOSITORY "https://github.com/google/googlemock.git" + GIT_TAG "release-${GMOCK_VER}" + PREFIX ${GMOCK_ROOT} + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON + CMAKE_ARGS + ${GTEST_CMAKE_ARGS} + BINARY_DIR ${GMOCK_BIN_DIR} + BUILD_BYPRODUCTS + "${GMOCK_LIBRARY}" + "${GMOCK_MAIN_LIBRARY}" + ) + + add_dependencies(gmock gtest) + + add_dependencies(GTest::GTest gtest) + add_dependencies(GTest::Main gtest) + add_dependencies(GMock::GMock gmock) + add_dependencies(GMock::Main gmock) + + externalproject_get_property(gtest source_dir) + set(GTEST_INCLUDE_DIR "${source_dir}/include") + mark_as_advanced(GTEST_INCLUDE_DIR) + externalproject_get_property(gmock source_dir) + set(GMOCK_INCLUDE_DIR "${source_dir}/include") + mark_as_advanced(GMOCK_INCLUDE_DIR) + else() #1.8.0 + set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build") + set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/googlemock/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/googlemock/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/googlemock/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/googlemock/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + mark_as_advanced(GTEST_LIBRARY) + mark_as_advanced(GTEST_MAIN_LIBRARY) + mark_as_advanced(GMOCK_LIBRARY) + mark_as_advanced(GMOCK_MAIN_LIBRARY) + + externalproject_add( + gmock + GIT_REPOSITORY "https://github.com/google/googletest.git" + GIT_TAG "release-${GMOCK_VER}" + PREFIX ${GMOCK_ROOT} + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON + CMAKE_ARGS + ${GTEST_CMAKE_ARGS} + BINARY_DIR "${GMOCK_BIN_DIR}" + BUILD_BYPRODUCTS + "${GTEST_LIBRARY}" + "${GTEST_MAIN_LIBRARY}" + "${GMOCK_LIBRARY}" + "${GMOCK_MAIN_LIBRARY}" + ) + + add_dependencies(GTest::GTest gmock) + add_dependencies(GTest::Main gmock) + add_dependencies(GMock::GMock gmock) + add_dependencies(GMock::Main gmock) + + externalproject_get_property(gmock source_dir) + set(GTEST_INCLUDE_DIR "${source_dir}/googletest/include") + set(GMOCK_INCLUDE_DIR "${source_dir}/googlemock/include") + mark_as_advanced(GMOCK_INCLUDE_DIR) + mark_as_advanced(GTEST_INCLUDE_DIR) + endif() + + # Prevent CMake from complaining about these directories missing when the libgtest/libgmock targets get used as dependencies + file(MAKE_DIRECTORY ${GTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR}) + else() + message(STATUS "Building Gmock / Gtest from dir ${GMOCK_SRC_DIR}") + + set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build") + set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + mark_as_advanced(GTEST_LIBRARY) + mark_as_advanced(GTEST_MAIN_LIBRARY) + mark_as_advanced(GMOCK_LIBRARY) + mark_as_advanced(GMOCK_MAIN_LIBRARY) + + if(EXISTS "${GMOCK_SRC_DIR}/gtest/include/gtest/gtest.h") + set(GTEST_INCLUDE_DIR "${GMOCK_SRC_DIR}/gtest/include") + mark_as_advanced(GTEST_INCLUDE_DIR) + endif() + if(EXISTS "${GMOCK_SRC_DIR}/include/gmock/gmock.h") + set(GMOCK_INCLUDE_DIR "${GMOCK_SRC_DIR}/include") + mark_as_advanced(GMOCK_INCLUDE_DIR) + elseif(EXISTS "${GMOCK_SRC_DIR}/../../include/gmock/gmock.h") + set(GMOCK_INCLUDE_DIR "${GMOCK_SRC_DIR}/../../include") + if(IS_ABSOLUTE "${GMOCK_INCLUDE_DIR}") + get_filename_component(GMOCK_INCLUDE_DIR "${GMOCK_INCLUDE_DIR}" ABSOLUTE) + endif() + mark_as_advanced(GMOCK_INCLUDE_DIR) + endif() + + externalproject_add( + gmock + SOURCE_DIR ${GMOCK_SRC_DIR} + PREFIX ${GMOCK_ROOT} + INSTALL_COMMAND "" + LOG_DOWNLOAD ON + LOG_CONFIGURE ON + LOG_BUILD ON + CMAKE_ARGS + ${GTEST_CMAKE_ARGS} + BINARY_DIR "${GMOCK_BIN_DIR}" + BUILD_BYPRODUCTS + "${GTEST_LIBRARY}" + "${GTEST_MAIN_LIBRARY}" + "${GMOCK_LIBRARY}" + "${GMOCK_MAIN_LIBRARY}" + ) + + add_dependencies(GTest::GTest gmock) + add_dependencies(GTest::Main gmock) + add_dependencies(GMock::GMock gmock) + add_dependencies(GMock::Main gmock) + endif() +endif() + +include(FindPackageHandleStandardArgs) +#find_package_handle_standard_args(GTest DEFAULT_MSG GTEST_LIBRARY GTEST_INCLUDE_DIR GTEST_MAIN_LIBRARY) +find_package_handle_standard_args(GMock DEFAULT_MSG GMOCK_LIBRARY GMOCK_INCLUDE_DIR GMOCK_MAIN_LIBRARY) + +include(CMakeFindDependencyMacro) +find_dependency(Threads) + +set_target_properties(GTest::GTest PROPERTIES + INTERFACE_LINK_LIBRARIES "Threads::Threads" + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GTEST_LIBRARY}" + ) + +if(GTEST_INCLUDE_DIR) + set_target_properties(GTest::GTest PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}" + ) +endif() + +set_target_properties(GTest::Main PROPERTIES + INTERFACE_LINK_LIBRARIES "GTest::GTest" + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GTEST_MAIN_LIBRARY}") + +set_target_properties(GMock::GMock PROPERTIES + INTERFACE_LINK_LIBRARIES "Threads::Threads" + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GMOCK_LIBRARY}") + +if(GMOCK_INCLUDE_DIR) + set_target_properties(GMock::GMock PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIR}" + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${GMOCK_INCLUDE_DIR}" + ) + if(GMOCK_VER VERSION_LESS "1.7") + # GMock 1.6 still has GTest as an external link-time dependency, + # so just specify it on the link interface. + set_property(TARGET GMock::GMock APPEND PROPERTY + INTERFACE_LINK_LIBRARIES GTest::GTest) + elseif(GTEST_INCLUDE_DIR) + # GMock 1.7 and beyond doesn't have it as a link-time dependency anymore, + # so merge it's compile-time interface (include dirs) with ours. + set_property(TARGET GMock::GMock APPEND PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}") + set_property(TARGET GMock::GMock APPEND PROPERTY + INTERFACE_SYSTEM_INCLUDE_DIRECTORIES "${GTEST_INCLUDE_DIR}") + endif() +endif() + +set_target_properties(GMock::Main PROPERTIES + INTERFACE_LINK_LIBRARIES "GMock::GMock" + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${GMOCK_MAIN_LIBRARY}") + +if(GTEST_FOUND) + set(GTEST_INCLUDE_DIRS ${GTEST_INCLUDE_DIR}) + set(GTEST_LIBRARIES GTest::GTest) + set(GTEST_MAIN_LIBRARIES GTest::Main) + set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES}) + if(VERBOSE) + message(STATUS "GTest includes: ${GTEST_INCLUDE_DIRS}") + message(STATUS "GTest libs: ${GTEST_BOTH_LIBRARIES}") + endif() +endif() + +if(GMOCK_FOUND) + set(GMOCK_INCLUDE_DIRS ${GMOCK_INCLUDE_DIR}) + set(GMOCK_LIBRARIES GMock::GMock) + set(GMOCK_MAIN_LIBRARIES GMock::Main) + set(GMOCK_BOTH_LIBRARIES ${GMOCK_LIBRARIES} ${GMOCK_MAIN_LIBRARIES}) + if(VERBOSE) + message(STATUS "GMock includes: ${GMOCK_INCLUDE_DIRS}") + message(STATUS "GMock libs: ${GMOCK_BOTH_LIBRARIES}") + endif() +endif() diff --git a/docs/getting-started.md b/docs/getting-started.md index 1c4c1d1..1ac6f44 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -22,6 +22,23 @@ command line: $ g++ -std=c++14 -Iinclude -o out/simple_protocol_example examples/simple_protocol.cpp ``` +## Building With CMake + +Adding **libnop** to your project using CMake can be done either using `add_subdirectory` or installing and using `find_package` command. + +``` +add_subdirectory(libnop) +target_link_libraries(my_target libnop) +``` + +or + +``` +find_package(libnop CONFIG REQUIRED) +target_link_libraries(my_target libnop) +``` + + ## Basic Usage `nop::Serializer` and `nop::Deserializer` are the top-level types for reading diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt new file mode 100644 index 0000000..453b489 --- /dev/null +++ b/examples/CMakeLists.txt @@ -0,0 +1,33 @@ +# Find threads +find_package(Threads) + +# Helper 'nop_add_example' +macro(nop_add_example example_name example_src) + add_executable(${example_name} ${example_src}) + target_link_libraries(${example_name} Threads::Threads ${TARGET_NAME}) +endmacro() + +# Examples +nop_add_example(stream_example interface.cpp) +nop_add_example(simple_protocol_example pipe.cpp) +nop_add_example(interface_example simple_protocol.cpp) +nop_add_example(pipe_example stream.cpp) +nop_add_example(table_example table.cpp) +nop_add_example(variant_example variant.cpp) + +# Shared library example +add_library(shared_protocol SHARED shared.cpp) +target_link_libraries(shared_protocol ${TARGET_NAME}) +add_custom_target(shared + # Command + python2 ${PROJECT_SOURCE_DIR}/examples/shared.py $ + DEPENDS shared_protocol + VERBATIM + COMMAND_EXPAND_LISTS +) + + + + + + diff --git a/examples/shared.py b/examples/shared.py index 8ab487f..5d2b4f6 100644 --- a/examples/shared.py +++ b/examples/shared.py @@ -21,6 +21,11 @@ import sys import os +# Path to shared_protocol.so +ProtocolLibraryPath = 'out/shared_protocol.so' +if len(sys.argv) > 1: + ProtocolLibraryPath = sys.argv[1] + # Define ctypes structures that mirror the basic protocol types. # Three component vector of floats. @@ -81,7 +86,7 @@ def LoadProtocolLibrary(): global DeserializePolyhedron # Load the shared library. - ProtocolLibrary = cdll.LoadLibrary('out/shared_protocol.so') + ProtocolLibrary = cdll.LoadLibrary(ProtocolLibraryPath) # Load the exported API and setup the function pointer types. GetSerializedPolyhedron = ProtocolLibrary.GetSerializedPolyhedron diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..28b329d --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,28 @@ +# GTest and GMock +set(GMOCK_VER "1.11.0") +set(GMOCK_ROOT ${CMAKE_CURRENT_BINARY_DIR}/gmock) +find_package(GMock REQUIRED) + +# Helper 'nop_add_test' +macro(nop_add_test test_name test_src) + add_executable(${test_name} ${test_src}) + target_link_libraries(${test_name} ${TARGET_NAME} GTest::Main GTest::GTest GMock::GMock) + add_test(${test_name} ${test_name}) +endmacro() + +# Tests +nop_add_test(constexpr_tests constexpr_tests.cpp) +nop_add_test(encoding_tests encoding_tests.cpp) +nop_add_test(endian_tests endian_tests.cpp) +nop_add_test(enum_flags_tests enum_flags_tests.cpp) +nop_add_test(fungible_tests fungible_tests.cpp) +nop_add_test(handle_tests handle_tests.cpp) +nop_add_test(interface_tests interface_tests.cpp) +nop_add_test(nop_tests nop_tests.cpp) +nop_add_test(optional_tests optional_tests.cpp) +nop_add_test(result_tests result_tests.cpp) +nop_add_test(serializer_tests serializer_tests.cpp) +nop_add_test(sip_hash_tests sip_hash_tests.cpp) +nop_add_test(thread_local_tests thread_local_tests.cpp) +nop_add_test(utility_tests utility_tests.cpp) +nop_add_test(variant_tests variant_tests.cpp) diff --git a/test/integration/CMakeLists.txt b/test/integration/CMakeLists.txt new file mode 100644 index 0000000..c0dfebd --- /dev/null +++ b/test/integration/CMakeLists.txt @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.2) + +# Create a project with name 'myapp' +set(TARGET_NAME myapp) +project(integration-test) + +# Select whether to test integration using add_subdirectory or find_package +option(TEST_FIND_PACKAGE "Test integration using find_package command" OFF) + +# Add libnop using find_package +if(TEST_FIND_PACKAGE) + find_package(libnop CONFIG REQUIRED) +else() + add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../" libnop EXCLUDE_FROM_ALL) +endif() + +# Create target dependant on libnop +add_executable(integration-test "../../examples/pipe.cpp") +target_include_directories(integration-test PUBLIC "../../examples/") + +target_link_libraries(integration-test PRIVATE libnop) + +include(CTest) +enable_testing() +add_test(integration-test integration-test) From 83967ad391a30d8f871d57777a91ebd7f9370ad4 Mon Sep 17 00:00:00 2001 From: Martin Peterlin Date: Thu, 30 Dec 2021 23:46:06 +0100 Subject: [PATCH 2/4] Fixed numeric limits usage --- .gitignore | 1 + cmake/modules/FindGMock.cmake | 26 +++++----- include/nop/base/encoding.h | 13 ++--- test/serializer_tests.cpp | 96 +++++++++++++++++------------------ 4 files changed, 70 insertions(+), 66 deletions(-) diff --git a/.gitignore b/.gitignore index da388b0..418ef58 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.swp out/* cscope.* +.vscode/ \ No newline at end of file diff --git a/cmake/modules/FindGMock.cmake b/cmake/modules/FindGMock.cmake index 6cf9006..5a909e4 100644 --- a/cmake/modules/FindGMock.cmake +++ b/cmake/modules/FindGMock.cmake @@ -269,10 +269,12 @@ if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) -DCMAKE_POLICY_DEFAULT_CMP0063=NEW ) endif() + set(GTEST_LIBRARY_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX}) set(GTEST_LIBRARY_PREFIX ${CMAKE_STATIC_LIBRARY_PREFIX}) else() set(GTEST_CMAKE_ARGS -DBUILD_SHARED_LIBS=ON) set(GTEST_LIBRARY_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX}) + set(GTEST_LIBRARY_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX}) endif() if(WIN32) list(APPEND GTEST_CMAKE_ARGS -Dgtest_disable_pthreads=ON) @@ -282,8 +284,8 @@ if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) message(STATUS "Downloading GMock / GTest version ${GMOCK_VER} from git") if("${GMOCK_VER}" STREQUAL "1.6.0" OR "${GMOCK_VER}" STREQUAL "1.7.0") set(GTEST_BIN_DIR "${GMOCK_ROOT}/src/gtest-build") - set(GTEST_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GTEST_MAIN_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${GTEST_LIBRARY_SUFFIX}") + set(GTEST_MAIN_LIBRARY "${GTEST_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${GTEST_LIBRARY_SUFFIX}") mark_as_advanced(GTEST_LIBRARY) mark_as_advanced(GTEST_MAIN_LIBRARY) @@ -305,8 +307,8 @@ if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) ) set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build") - set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${GTEST_LIBRARY_SUFFIX}") + set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${GTEST_LIBRARY_SUFFIX}") mark_as_advanced(GMOCK_LIBRARY) mark_as_advanced(GMOCK_MAIN_LIBRARY) @@ -342,10 +344,10 @@ if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) mark_as_advanced(GMOCK_INCLUDE_DIR) else() #1.8.0 set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build") - set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/googlemock/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/googlemock/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/googlemock/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/googlemock/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/lib/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${GTEST_LIBRARY_SUFFIX}") + set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/lib/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${GTEST_LIBRARY_SUFFIX}") + set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/lib/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${GTEST_LIBRARY_SUFFIX}") + set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/lib/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${GTEST_LIBRARY_SUFFIX}") mark_as_advanced(GTEST_LIBRARY) mark_as_advanced(GTEST_MAIN_LIBRARY) mark_as_advanced(GMOCK_LIBRARY) @@ -388,10 +390,10 @@ if(NOT (${GMOCK_LIBRARY_EXISTS} AND ${GTEST_LIBRARY_EXISTS})) message(STATUS "Building Gmock / Gtest from dir ${GMOCK_SRC_DIR}") set(GMOCK_BIN_DIR "${GMOCK_ROOT}/src/gmock-build") - set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${CMAKE_STATIC_LIBRARY_SUFFIX}") - set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${CMAKE_STATIC_LIBRARY_SUFFIX}") + set(GTEST_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest${GTEST_LIBRARY_SUFFIX}") + set(GTEST_MAIN_LIBRARY "${GMOCK_BIN_DIR}/gtest/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gtest_main${GTEST_LIBRARY_SUFFIX}") + set(GMOCK_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock${GTEST_LIBRARY_SUFFIX}") + set(GMOCK_MAIN_LIBRARY "${GMOCK_BIN_DIR}/${CMAKE_CFG_INTDIR}/${GTEST_LIBRARY_PREFIX}gmock_main${GTEST_LIBRARY_SUFFIX}") mark_as_advanced(GTEST_LIBRARY) mark_as_advanced(GTEST_MAIN_LIBRARY) mark_as_advanced(GMOCK_LIBRARY) diff --git a/include/nop/base/encoding.h b/include/nop/base/encoding.h index e0ed2d0..96e35b3 100644 --- a/include/nop/base/encoding.h +++ b/include/nop/base/encoding.h @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -471,7 +472,7 @@ struct Encoding : EncodingIO { static constexpr EncodingByte Prefix(std::int16_t value) { if (value >= -64 && value <= 127) return static_cast(value); - else if (value >= -128 && value <= 127) + else if (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return EncodingByte::I8; else return EncodingByte::I16; @@ -614,9 +615,9 @@ struct Encoding : EncodingIO { static constexpr EncodingByte Prefix(std::int32_t value) { if (value >= -64 && value <= 127) return static_cast(value); - else if (value >= -128 && value <= 127) + else if (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return EncodingByte::I8; - else if (value >= -32768 && value <= 32767) + else if (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return EncodingByte::I16; else return EncodingByte::I32; @@ -777,11 +778,11 @@ struct Encoding : EncodingIO { static constexpr EncodingByte Prefix(std::int64_t value) { if (value >= -64 && value <= 127) return static_cast(value); - else if (value >= -128 && value <= 127) // Effectively [-128, -64). + else if (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) // Effectively [-128, -64). return EncodingByte::I8; - else if (value >= -32768 && value <= 32767) + else if (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return EncodingByte::I16; - else if (value >= -2147483648 && value <= 2147483647) + else if (value >= std::numeric_limits::min() && value <= std::numeric_limits::max()) return EncodingByte::I32; else return EncodingByte::I64; diff --git a/test/serializer_tests.cpp b/test/serializer_tests.cpp index c0e39eb..622be90 100644 --- a/test/serializer_tests.cpp +++ b/test/serializer_tests.cpp @@ -2459,18 +2459,18 @@ TEST(Serializer, int16_t) { writer.clear(); // Min I16. - value = -32768; + value = std::numeric_limits::min(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I16, Integer(-32768)); + expected = Compose(EncodingByte::I16, Integer(std::numeric_limits::min())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Max I16. - value = 32767; + value = std::numeric_limits::max(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I16, Integer(32767)); + expected = Compose(EncodingByte::I16, Integer(std::numeric_limits::max())); EXPECT_EQ(expected, writer.data()); writer.clear(); } @@ -2518,16 +2518,16 @@ TEST(Deserializer, int16_t) { EXPECT_EQ(127, value); // Min I16. - reader.Set(Compose(EncodingByte::I16, Integer(-32768))); + reader.Set(Compose(EncodingByte::I16, Integer(std::numeric_limits::min()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(-32768, value); + EXPECT_EQ(std::numeric_limits::min(), value); // Max I16. - reader.Set(Compose(EncodingByte::I16, Integer(32767))); + reader.Set(Compose(EncodingByte::I16, Integer(std::numeric_limits::max()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(32767, value); + EXPECT_EQ(std::numeric_limits::max(), value); // TODO(eieio): Test rejection of all other encoding prefix bytes. reader.Set(Compose(EncodingByte::Nil)); @@ -2592,34 +2592,34 @@ TEST(Serializer, int32_t) { writer.clear(); // Min I16. - value = -32768; + value = std::numeric_limits::min(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I16, Integer(-32768)); + expected = Compose(EncodingByte::I16, Integer(std::numeric_limits::min())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Max I16. - value = 32767; + value = std::numeric_limits::max(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I16, Integer(32767)); + expected = Compose(EncodingByte::I16, Integer(std::numeric_limits::max())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Min I32. - value = -2147483648; + value = std::numeric_limits::min(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I32, Integer(-2147483648)); + expected = Compose(EncodingByte::I32, Integer(std::numeric_limits::min())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Max I32. - value = 2147483647; + value = std::numeric_limits::max(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I32, Integer(2147483647)); + expected = Compose(EncodingByte::I32, Integer(std::numeric_limits::max())); EXPECT_EQ(expected, writer.data()); writer.clear(); } @@ -2667,28 +2667,28 @@ TEST(Deserializer, int32_t) { EXPECT_EQ(127, value); // Min I16. - reader.Set(Compose(EncodingByte::I16, Integer(-32768))); + reader.Set(Compose(EncodingByte::I16, Integer(std::numeric_limits::min()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(-32768, value); + EXPECT_EQ(std::numeric_limits::min(), value); // Max I16. - reader.Set(Compose(EncodingByte::I16, Integer(32767))); + reader.Set(Compose(EncodingByte::I16, Integer(std::numeric_limits::max()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(32767, value); + EXPECT_EQ(std::numeric_limits::max(), value); // Min I32. - reader.Set(Compose(EncodingByte::I32, Integer(-2147483648))); + reader.Set(Compose(EncodingByte::I32, Integer(std::numeric_limits::min()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(-2147483648, value); + EXPECT_EQ(std::numeric_limits::min(), value); // Max I32. - reader.Set(Compose(EncodingByte::I32, Integer(2147483647))); + reader.Set(Compose(EncodingByte::I32, Integer(std::numeric_limits::max()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(2147483647, value); + EXPECT_EQ(std::numeric_limits::max(), value); // TODO(eieio): Test rejection of all other encoding prefix bytes. reader.Set(Compose(EncodingByte::Nil)); @@ -2753,54 +2753,54 @@ TEST(Serializer, int64_t) { writer.clear(); // Min I16. - value = -32768; + value = std::numeric_limits::min(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I16, Integer(-32768)); + expected = Compose(EncodingByte::I16, Integer(std::numeric_limits::min())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Max I16. - value = 32767; + value = std::numeric_limits::max(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I16, Integer(32767)); + expected = Compose(EncodingByte::I16, Integer(std::numeric_limits::max())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Min I32. - value = -2147483648; + value = std::numeric_limits::min(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I32, Integer(-2147483648)); + expected = Compose(EncodingByte::I32, Integer(std::numeric_limits::min())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Max I32. - value = 2147483647; + value = std::numeric_limits::max(); status = serializer.Write(value); ASSERT_TRUE(status); - expected = Compose(EncodingByte::I32, Integer(2147483647)); + expected = Compose(EncodingByte::I32, Integer(std::numeric_limits::max())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Min I64. - value = -9223372036854775807LL - 1; + value = std::numeric_limits::min(); //std::numeric_limits::min(); // Believe it or not, this is actually the correct way to specify the most // negative signed long long. status = serializer.Write(value); ASSERT_TRUE(status); expected = Compose(EncodingByte::I64, - Integer(-9223372036854775807LL - 1)); + Integer(std::numeric_limits::min())); EXPECT_EQ(expected, writer.data()); writer.clear(); // Max I64. - value = 9223372036854775807LL; + value = std::numeric_limits::max(); status = serializer.Write(value); ASSERT_TRUE(status); expected = - Compose(EncodingByte::I64, Integer(9223372036854775807LL)); + Compose(EncodingByte::I64, Integer(std::numeric_limits::max())); EXPECT_EQ(expected, writer.data()); writer.clear(); } @@ -2848,44 +2848,44 @@ TEST(Deserializer, int64_t) { EXPECT_EQ(127, value); // Min I16. - reader.Set(Compose(EncodingByte::I16, Integer(-32768))); + reader.Set(Compose(EncodingByte::I16, Integer(std::numeric_limits::min()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(-32768, value); + EXPECT_EQ(std::numeric_limits::min(), value); // Max I16. - reader.Set(Compose(EncodingByte::I16, Integer(32767))); + reader.Set(Compose(EncodingByte::I16, Integer(std::numeric_limits::max()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(32767, value); + EXPECT_EQ(std::numeric_limits::max(), value); // Min I32. - reader.Set(Compose(EncodingByte::I32, Integer(-2147483648))); + reader.Set(Compose(EncodingByte::I32, Integer(std::numeric_limits::min()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(-2147483648, value); + EXPECT_EQ(std::numeric_limits::min(), value); // Max I32. - reader.Set(Compose(EncodingByte::I32, Integer(2147483647))); + reader.Set(Compose(EncodingByte::I32, Integer(std::numeric_limits::max()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(2147483647, value); + EXPECT_EQ(std::numeric_limits::max(), value); // Min I64. reader.Set(Compose(EncodingByte::I64, - Integer(-9223372036854775807LL - 1))); + Integer(std::numeric_limits::min()))); // Believe it or not, this is actually the correct way to specify the most // negative signed long long. status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(-9223372036854775807LL - 1, value); + EXPECT_EQ(std::numeric_limits::min(), value); // Max I64. reader.Set( - Compose(EncodingByte::I64, Integer(9223372036854775807LL))); + Compose(EncodingByte::I64, Integer(std::numeric_limits::max()))); status = deserializer.Read(&value); ASSERT_TRUE(status); - EXPECT_EQ(9223372036854775807LL, value); + EXPECT_EQ(std::numeric_limits::max(), value); // TODO(eieio): Test rejection of all other encoding prefix bytes. reader.Set(Compose(EncodingByte::Nil)); From 149883367057c02b07abc76608f483adb2147403 Mon Sep 17 00:00:00 2001 From: TheMarpe Date: Mon, 10 Jan 2022 23:29:45 +0100 Subject: [PATCH 3/4] Fixed examples usage --- examples/CMakeLists.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 453b489..c6e6413 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -8,10 +8,10 @@ macro(nop_add_example example_name example_src) endmacro() # Examples -nop_add_example(stream_example interface.cpp) -nop_add_example(simple_protocol_example pipe.cpp) -nop_add_example(interface_example simple_protocol.cpp) -nop_add_example(pipe_example stream.cpp) +nop_add_example(stream_example stream.cpp) +nop_add_example(simple_protocol_example simple_protocol.cpp) +nop_add_example(interface_example interface.cpp) +nop_add_example(pipe_example pipe.cpp) nop_add_example(table_example table.cpp) nop_add_example(variant_example variant.cpp) From 2f19ad3ff3b40a323fa6777cb0b7594202769a72 Mon Sep 17 00:00:00 2001 From: TheMarpe Date: Wed, 12 Jan 2022 00:22:21 +0100 Subject: [PATCH 4/4] Resolved some MSVC differences --- include/nop/structure.h | 9 +++++---- include/nop/types/enum_flags.h | 3 ++- include/nop/utility/compiler.h | 12 ++++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/nop/structure.h b/include/nop/structure.h index 94c66de..f1378ea 100644 --- a/include/nop/structure.h +++ b/include/nop/structure.h @@ -21,6 +21,7 @@ #include #include +#include namespace nop { @@ -79,13 +80,13 @@ namespace nop { }; \ template \ inline _NOP_ENABLE_IF_TYPE_MATCH(T, type, NOP__MEMBER_TRAITS) \ - NOP__GetExternalMemberTraits [[gnu::used]] (T*) { \ + NOP__GetExternalMemberTraits NOP_GNU_USED (T*) { \ return {}; \ } \ template