# Copyright © 2018-2019 Pascal JEAN, All rights reserved. # This file is part of the libmodbuspp Project. # # The libmodbuspp Project is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # The libmodbuspp Project is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with the libmodbuspp Project. If not, see . # modbuspp top-level CMakeLists.txt cmake_minimum_required (VERSION 3.5 FATAL_ERROR) project (MODBUSPP LANGUAGES CXX) set (PROJECT_DESCRIPTION "Much more than a C++ wrapper for the libmodbus library") set (PROJECT_DESCRIPTION_TEXT "\ A C++ wrapper for the libmodbus library, to send/receive data with a device which\n\ respects the Modbus protocol. This library can use a serial port or an\n\ Ethernet connection." ) # library for the Modbus protocol string(TOLOWER ${CMAKE_PROJECT_NAME} PROJECT_NAME) # Appends the cmake/modules path to MAKE_MODULE_PATH variable. set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dev/cmake" "${CMAKE_CURRENT_BINARY_DIR}" ${CMAKE_MODULE_PATH}) # Set a default build type if none was specified 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 for cmake-gui set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo") endif() set (MODBUSPP_WITH_STATIC 0 CACHE BOOL "Enable building static libraries.") set (MODBUSPP_UNIT_TESTS 1 CACHE BOOL "Enable building unit tests.") # Offer the user the choice of overriding the installation directories set(INSTALL_LIB_DIR lib CACHE PATH "Installation directory for libraries") set(INSTALL_BIN_DIR bin CACHE PATH "Installation directory for executables") set(INSTALL_INCLUDE_DIR include CACHE PATH "Installation directory for header files") set(INSTALL_CODELITE_DIR /usr/share/codelite CACHE PATH "Installation directory for codelite templates") option(MODBUSPP_USE_EXTERNAL_JSON "Use an external JSON library" OFF) set(DEF_INSTALL_CMAKE_DIR lib) set(DEF_INSTALL_DOC_DIR share/doc) set(DEF_INSTALL_DATA_DIR share) set(INSTALL_CMAKE_DIR ${DEF_INSTALL_CMAKE_DIR} CACHE PATH "Installation directory for CMake files") set(INSTALL_DOC_DIR ${DEF_INSTALL_DOC_DIR} CACHE PATH "Installation directory for documentation") set(INSTALL_DATA_DIR ${DEF_INSTALL_DATA_DIR} CACHE PATH "Installation directory for data") set (CMAKE_CXX_STANDARD 11) set(CMAKE_THREAD_PREFER_PTHREAD TRUE) set(THREADS_PREFER_PTHREAD_FLAG TRUE) find_package(Threads REQUIRED) set(LIBMODBUS_MIN_VERSION "3.1.6") find_package(PkgConfig REQUIRED) pkg_check_modules (LIBMODBUS libmodbusepsi>=${LIBMODBUS_MIN_VERSION}) if (LIBMODBUS_FOUND) set(LIBMODBUS_NAME modbusepsi) else() pkg_check_modules (LIBMODBUS REQUIRED libmodbus>=${LIBMODBUS_MIN_VERSION}) set(LIBMODBUS_NAME modbus) endif() set(LIBMODBUS_PACKAGE lib${LIBMODBUS_NAME}5) set(LIBMODBUSDEV_PACKAGE lib${LIBMODBUS_NAME}-dev) find_package(Gzip) pkg_check_modules (UNITTESTPP UnitTest++>=2.0.0) if(MODBUSPP_USE_EXTERNAL_JSON) find_package(nlohmann_json 3.2.0 REQUIRED) else() set(JSON_BuildTests OFF CACHE INTERNAL "") set(JSON_Install OFF CACHE INTERNAL "") add_subdirectory(3rdparty/json) endif() set (MODBUSPP_CFLAGS_OTHER ${CMAKE_THREAD_LIBS_INIT} ${LIBMODBUS_CFLAGS}) set (MODBUSPP_LDFLAGS_OTHER ${LIBMODBUS_LDFLAGS} -lpthread) include (GetDate) GetDate(DATE_) include (GitVersion) GetGitVersion(MODBUSPP_VERSION) set(MODBUSPP_VERSION ${MODBUSPP_VERSION_MAJOR}.${MODBUSPP_VERSION_MINOR}.${MODBUSPP_VERSION_PATCH}) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in ${CMAKE_CURRENT_BINARY_DIR}/version.h @ONLY) include(CheckTypeSize) check_type_size(bool SIZEOF_BOOL BUILTIN_TYPES_ONLY LANGUAGE CXX) message(STATUS " size of bool is ${SIZEOF_BOOL}") if (NOT ${SIZEOF_BOOL} EQUAL 1) message(FATAL_ERROR "bool must have a size of 1 byte !") endif() include(CheckSymbolExists) check_symbol_exists(TIOCSRS485 sys/ioctl.h MODBUSPP_HAVE_TIOCRS485) check_symbol_exists(TIOCM_RTS sys/ioctl.h MODBUSPP_HAVE_TIOCM_RTS) list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBMODBUS_NAME}) check_symbol_exists(modbus_rtu_set_recv_filter ${LIBMODBUS_NAME}/modbus-rtu.h MODBUSPP_HAVE_RTU_MULTI_SLAVES) # Make relative paths absolute (needed later on) foreach(p LIB BIN INCLUDE CMAKE DATA DOC CODELITE) set(var INSTALL_${p}_DIR) if(NOT IS_ABSOLUTE "${${var}}") set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") endif() endforeach() set (MODBUSPP_SRC_DIR ${PROJECT_SOURCE_DIR}/src) set (MODBUSPP_INC_DIR ${PROJECT_SOURCE_DIR}/include) set (MODBUSPP_LIB_DIR ${PROJECT_BINARY_DIR}/lib) set (MODBUSPP_INSTALL_CMAKE_DIR "${INSTALL_CMAKE_DIR}/modbuspp/cmake") set (MODBUSPP_INSTALL_DOC_DIR "${INSTALL_DOC_DIR}/modbuspp") set (MODBUSPP_INSTALL_EXAMPLES_DIR "${MODBUSPP_INSTALL_DOC_DIR}/examples") set (MODBUSPP_INSTALL_DATA_DIR "${INSTALL_DATA_DIR}/modbuspp") message (STATUS "Building for ${CMAKE_SYSTEM_PROCESSOR} architecture.") # uninstall target configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) # Suppress GCC warnings # See https://gcc.gnu.org/gcc-7/changes.html # On ARM targets (arm*-*-*), a bug introduced in GCC 5 that affects conformance # to the procedure call standard (AAPCS) has been fixed. The bug affects some # C++ code where class objects are passed by value to functions and could result # in incorrect or inconsistent code being generated. This is an ABI change. # If the option -Wpsabi is enabled (on by default) the compiler will emit a # diagnostic note for code that might be affected. # <<< TODO >>> Fix this problem before compile with GCC 7 ! add_compile_options(-Wno-psabi) include_directories( ${LIBMODBUS_INCLUDE_DIRS} ${MODBUSPP_INC_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) add_subdirectory (dev) add_subdirectory (lib) add_subdirectory (doc) # CMake Package ---------------------------------------------------------------- # Add all targets to the build-tree export set if (MODBUSPP_WITH_STATIC) set (exported_targets modbuspp-shared modbuspp-static) else(MODBUSPP_WITH_STATIC) set (exported_targets modbuspp-shared) endif(MODBUSPP_WITH_STATIC) export(TARGETS ${exported_targets} FILE "${PROJECT_BINARY_DIR}/modbuspp.cmake") # Export the package for use from the build-tree # (this registers the build-tree with a global CMake-registry) export(PACKAGE modbuspp) # Create the modbuspp-config.cmake and modbuspp-config-version files file(RELATIVE_PATH REL_LIB_DIR "${MODBUSPP_INSTALL_CMAKE_DIR}" "${INSTALL_LIB_DIR}") file(RELATIVE_PATH REL_INCLUDE_DIR "${MODBUSPP_INSTALL_CMAKE_DIR}" "${INSTALL_INCLUDE_DIR}") # ... for the build tree set(CONF_INCLUDE_DIRS "${MODBUSPP_INC_DIR}" "${PROJECT_BINARY_DIR}") set(CONF_LIB_DIRS "${PROJECT_BINARY_DIR}/lib") configure_file(modbuspp-config.cmake.in "${PROJECT_BINARY_DIR}/modbuspp-config.cmake" @ONLY) # ... for the install tree set(CONF_INCLUDE_DIRS "\${MODBUSPP_CMAKE_DIR}/${REL_INCLUDE_DIR}") set(CONF_LIB_DIRS "\${MODBUSPP_CMAKE_DIR}/${REL_LIB_DIR}") configure_file(modbuspp-config.cmake.in "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/modbuspp-config.cmake" @ONLY) # ... for both configure_file(modbuspp-config-version.cmake.in "${PROJECT_BINARY_DIR}/modbuspp-config-version.cmake" @ONLY) # Install the modbuspp-config.cmake and modbuspp-config-version.cmake install(FILES "${PROJECT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/modbuspp-config.cmake" "${PROJECT_BINARY_DIR}/modbuspp-config-version.cmake" DESTINATION "${MODBUSPP_INSTALL_CMAKE_DIR}" COMPONENT dev) # Install the export set for use with the install-tree install(EXPORT modbuspp DESTINATION "${MODBUSPP_INSTALL_CMAKE_DIR}" COMPONENT dev) ## pkg-config ------------------------------------------------------------------ foreach(item ${MODBUSPP_CFLAGS_OTHER}) string(APPEND MODBUSPP_CFLAGS_PKGCONFIG "${item} ") endforeach(item MODBUSPP_CFLAGS_OTHER) foreach(item ${MODBUSPP_LDFLAGS_OTHER}) string(APPEND MODBUSPP_LDFLAGS_PKGCONFIG "${item} ") endforeach(item MODBUSPP_LDFLAGS_OTHER) configure_file (${CMAKE_CURRENT_SOURCE_DIR}/modbuspp.pc.in ${CMAKE_CURRENT_BINARY_DIR}/modbuspp.pc @ONLY) install (FILES ${CMAKE_CURRENT_BINARY_DIR}/modbuspp.pc DESTINATION "${INSTALL_LIB_DIR}/pkgconfig" COMPONENT dev) if (UNITTESTPP_FOUND AND MODBUSPP_UNIT_TESTS) include(CTest) enable_testing() add_subdirectory (tests) endif() if (MODBUSPP_WITH_DOXYGEN_DOC) add_dependencies(modbuspp-shared doc) endif() # Install the modbuspp licence files install(FILES "${PROJECT_SOURCE_DIR}/COPYING.LESSER" DESTINATION "${MODBUSPP_INSTALL_DATA_DIR}" COMPONENT lib) install(FILES "${PROJECT_SOURCE_DIR}/README.md" DESTINATION "${MODBUSPP_INSTALL_DOC_DIR}" COMPONENT lib) install ( DIRECTORY "${MODBUSPP_INC_DIR}/" DESTINATION "${INSTALL_INCLUDE_DIR}" COMPONENT dev) install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h ${CMAKE_CURRENT_BINARY_DIR}/version.h DESTINATION "${INSTALL_INCLUDE_DIR}/${PROJECT_NAME}" COMPONENT dev) ### Debian Packages generation ------------------------------------------------- set(CPACK_PACKAGE_NAME ${PROJECT_NAME}) set(CPACK_PACKAGE_VERSION "${MODBUSPP_VERSION_MAJOR}.${MODBUSPP_VERSION_MINOR}.${MODBUSPP_VERSION_PATCH}") set(CPACK_PACKAGE_VERSION_MAJOR "${MODBUSPP_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${MODBUSPP_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${MODBUSPP_VERSION_PATCH}") set(CPACK_PACKAGE_CONTACT "Pascal JEAN ") set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME} - ${PROJECT_DESCRIPTION}") set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING.LESSER") set(CPACK_GENERATOR "DEB") if (CPACK_GENERATOR STREQUAL "DEB") set(CPACK_DEB_PACKAGE_COMPONENT 1) set(CPACK_DEB_COMPONENT_INSTALL 1) set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/epsilonrt/libmodbuspp") find_program(dpkg_query NAMES dpkg-query) find_program(dpkg_cmd NAMES dpkg) if (NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) if (dpkg_cmd) execute_process(COMMAND ${dpkg_cmd} --print-architecture RESULT_VARIABLE ret OUTPUT_VARIABLE arch OUTPUT_STRIP_TRAILING_WHITESPACE) if (ret EQUAL 0) set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${arch}") else (ret EQUAL 0) message(WARNING "Unable to get debian architecture !") endif (ret EQUAL 0) endif (dpkg_cmd) endif (NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) message(STATUS "Debian architecture ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}") set(CPACK_DEBIAN_LIB_PACKAGE_NAME "libmodbuspp") set(CPACK_COMPONENT_LIB_DESCRIPTION "${CPACK_DEBIAN_LIB_PACKAGE_NAME} - ${PROJECT_DESCRIPTION} (library)\n${PROJECT_DESCRIPTION_TEXT}\n This package provides the shared libriairie itself.") set(CPACK_DEBIAN_LIB_FILE_NAME "lib${PROJECT_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") set(CPACK_DEBIAN_LIB_PACKAGE_DEPENDS "libstdc++6,${LIBMODBUS_PACKAGE} (>= ${LIBMODBUS_VERSION})") set(CPACK_DEBIAN_LIB_PACKAGE_SECTION "libs") set(CPACK_DEBIAN_DEV_PACKAGE_NAME "libmodbuspp-dev") set(CPACK_COMPONENT_DEV_DESCRIPTION "${CPACK_DEBIAN_LIB_PACKAGE_NAME} - ${PROJECT_DESCRIPTION} (development files)\n${PROJECT_DESCRIPTION_TEXT}\n This package provides the development files.") set(CPACK_DEBIAN_DEV_FILE_NAME "lib${PROJECT_NAME}-dev_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") set(CPACK_DEBIAN_DEV_PACKAGE_DEPENDS "${CPACK_DEBIAN_LIB_PACKAGE_NAME} (= ${CPACK_PACKAGE_VERSION}),pkg-config,git-core,${LIBMODBUSDEV_PACKAGE} (>= ${LIBMODBUS_VERSION})") set(CPACK_DEBIAN_DEV_PACKAGE_SECTION "libdevel") #set(CPACK_PACKAGE_DESCRIPTION_FILE "${MODBUSPP_SRC_DIR}/doc/README-deb.md") set(CPACK_DEBIAN_DOC_PACKAGE_NAME "libmodbuspp-doc") set(CPACK_COMPONENT_DOC_DESCRIPTION "${CPACK_DEBIAN_LIB_PACKAGE_NAME} - ${PROJECT_DESCRIPTION} (documentation)\n${PROJECT_DESCRIPTION_TEXT}\n This package provides the API documentation.") set(CPACK_DEBIAN_DOC_FILE_NAME "lib${PROJECT_NAME}-doc_${CPACK_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") #set(CPACK_DEBIAN_DOC_PACKAGE_DEPENDS "${CPACK_DEBIAN_DEV_PACKAGE_NAME} (= ${CPACK_PACKAGE_VERSION})") set(CPACK_DEBIAN_DOC_PACKAGE_SECTION "libdevel") endif (CPACK_GENERATOR STREQUAL "DEB") include(CPack)