From 16a403b3cca43e4b211525f4b6c80a43466b5e97 Mon Sep 17 00:00:00 2001 From: "Ivo Stoilov (GitHub)" Date: Fri, 30 Dec 2016 17:47:39 +0200 Subject: Refactor CMake files Merge components refactoring from Windows port barnch - add cmake tools - refactor protocol handler CMakeLists.txt file - refactor interfaces CMakeLists.txt file - refactor smart object CMakeLists.txt file - refactor formatters CMakeLists.txt file - refactor config profile CMakeLists.txt file - refactor policy CMakeLists.txt file - refactor resumption CMakeLists.txt file - refactor connection handler CMakeLists.txt file - refactor application manager CMakeLists.txt file - refactor security manager CMakeLists.txt file - refactor dbus CMakeLists.txt file - refactor hmi message handler CMakeLists.txt file - refactor transport manager CMakeLists.txt file - refactor utils CMakeLists.txt file - refactor components root CMakeLists.txt file - refactor utils CMakeLists.txt file - refactor components root CMakeLists.txt file - refactor media manager CMakeLists.txt file - refactor telemetry monitor CMakeLists.txt file - refactor appmain CMakeLists.txt file - refactor plugins CMakeLists.txt file - refactor 3rd party CMakeLists.txt files - create cmake helper for interface generation - refactor root CMakeLists.txt file Move cmake modules to tools Related taks APPLINK-30588 APPLINK-30972 --- .travis.yml | 10 +- CMakeLists.txt | 446 +-- cmake/Modules/FindGlib-2.0.cmake | 43 - cmake/Modules/FindGstreamer-1.0.cmake | 136 - cmake/Modules/FindLibXML2.cmake | 20 - cmake/Modules/FindQt5Core.cmake | 10 - cmake/Modules/FindQt5DBus.cmake | 10 - cmake/Modules/FindQt5Qml.cmake | 10 - cmake/Modules/FindQt5Quick.cmake | 10 - cmake/Modules/FindSqlite3.cmake | 81 - cmake/Modules/FindUDev.cmake | 53 - cmake/Modules/cotire.cmake | 3917 -------------------- cmake/Modules/sources.cmake | 51 - src/3rd_party-static/CMakeLists.txt | 7 +- src/3rd_party-static/MessageBroker/CMakeLists.txt | 39 - .../MessageBroker/include/CMessageBroker.hpp | 108 - .../include/CMessageBrokerRegistry.hpp | 113 - .../MessageBroker/include/CSender.hpp | 53 - .../MessageBroker/include/MBDebugHelper.h | 40 - .../MessageBroker/include/mb_client.hpp | 135 - .../MessageBroker/include/mb_controller.hpp | 253 -- .../MessageBroker/include/mb_server.hpp | 121 - .../MessageBroker/include/mb_tcpclient.hpp | 58 - .../MessageBroker/include/mb_tcpserver.hpp | 150 - .../MessageBroker/include/networking.h | 139 - .../MessageBroker/include/system.h | 320 -- .../MessageBroker/include/websocket_handler.hpp | 226 -- .../MessageBroker/src/client/mb_client.cpp | 75 - .../MessageBroker/src/client/mb_controller.cpp | 352 -- .../MessageBroker/src/client/mb_tcpclient.cpp | 58 - .../src/example/MessageBrokerControllerAVA.cpp | 59 - .../src/example/MessageBrokerControllerAVA.hpp | 68 - .../src/example/MessageBrokerControllerBackend.cpp | 125 - .../src/example/MessageBrokerControllerBackend.hpp | 96 - .../src/example/MessageBrokerControllerPhone.cpp | 191 - .../src/example/MessageBrokerControllerPhone.hpp | 117 - .../src/example/MessageBrokerServer.cpp | 245 -- .../src/example/MessageBrokerServer.hpp | 19 - .../src/lib_messagebroker/CMessageBroker.cpp | 958 ----- .../lib_messagebroker/CMessageBrokerRegistry.cpp | 191 - .../src/lib_messagebroker/libMBDebugHelper.h | 43 - .../MessageBroker/src/lib_messagebroker/md5.cpp | 373 -- .../MessageBroker/src/lib_messagebroker/md5.h | 93 - .../MessageBroker/src/lib_messagebroker/system.cpp | 267 -- .../src/lib_messagebroker/websocket_handler.cpp | 667 ---- .../MessageBroker/src/server/mb_server.cpp | 46 - .../MessageBroker/src/server/mb_tcpserver.cpp | 331 -- .../MessageBroker/src/server/networking.cpp | 189 - src/3rd_party-static/encryption/CMakeLists.txt | 39 +- src/3rd_party-static/jsoncpp/CMakeLists.txt | 44 +- src/3rd_party-static/message_broker/CMakeLists.txt | 78 + .../message_broker/include/CMessageBroker.hpp | 108 + .../include/CMessageBrokerRegistry.hpp | 113 + .../message_broker/include/CSender.hpp | 53 + .../message_broker/include/MBDebugHelper.h | 40 + .../message_broker/include/mb_client.hpp | 135 + .../message_broker/include/mb_controller.hpp | 253 ++ .../message_broker/include/mb_server.hpp | 121 + .../message_broker/include/mb_tcpclient.hpp | 58 + .../message_broker/include/mb_tcpserver.hpp | 150 + .../message_broker/include/networking.h | 139 + .../message_broker/include/system.h | 320 ++ .../message_broker/include/websocket_handler.hpp | 226 ++ .../message_broker/src/client/mb_client.cpp | 75 + .../message_broker/src/client/mb_controller.cpp | 352 ++ .../message_broker/src/client/mb_tcpclient.cpp | 58 + .../src/example/MessageBrokerControllerAVA.cpp | 59 + .../src/example/MessageBrokerControllerAVA.hpp | 68 + .../src/example/MessageBrokerControllerBackend.cpp | 125 + .../src/example/MessageBrokerControllerBackend.hpp | 96 + .../src/example/MessageBrokerControllerPhone.cpp | 191 + .../src/example/MessageBrokerControllerPhone.hpp | 117 + .../src/example/MessageBrokerServer.cpp | 245 ++ .../src/example/MessageBrokerServer.hpp | 19 + .../src/lib_messagebroker/CMessageBroker.cpp | 958 +++++ .../lib_messagebroker/CMessageBrokerRegistry.cpp | 191 + .../src/lib_messagebroker/libMBDebugHelper.h | 43 + .../message_broker/src/lib_messagebroker/md5.cpp | 373 ++ .../message_broker/src/lib_messagebroker/md5.h | 93 + .../src/lib_messagebroker/system.cpp | 267 ++ .../src/lib_messagebroker/websocket_handler.cpp | 667 ++++ .../message_broker/src/server/mb_server.cpp | 46 + .../message_broker/src/server/mb_tcpserver.cpp | 331 ++ .../message_broker/src/server/networking.cpp | 189 + src/3rd_party-static/test/CMakeLists.txt | 15 +- src/3rd_party/CMakeLists.txt | 205 +- src/3rd_party/apache-log4cxx-cmake/CMakeLists.txt | 2 +- src/3rd_party/iap.armv7-qnx.runtime.tar.bz2 | Bin 21769 -> 0 bytes src/3rd_party/iap.build.tar.bz2 | Bin 19659 -> 0 bytes src/appMain/CMakeLists.txt | 111 +- src/components/CMakeLists.txt | 48 +- src/components/HMI/IVSU/PROPRIETARY_REQUEST~ | 0 src/components/application_manager/CMakeLists.txt | 117 +- .../application_manager/test/CMakeLists.txt | 190 +- .../test/commands/CMakeLists.txt | 2 +- .../test/commands/mobile/alert_request_test.cc | 2 +- .../test/commands/mobile/read_did_request_test.cc | 2 +- .../test/message_helper/CMakeLists.txt.user | 189 - .../test/resumption/resume_ctrl_test.cc | 10 +- src/components/config_profile/CMakeLists.txt | 16 +- src/components/config_profile/test/CMakeLists.txt | 16 +- src/components/connection_handler/CMakeLists.txt | 19 +- .../connection_handler/test/CMakeLists.txt | 20 +- src/components/dbus/CMakeLists.txt | 19 +- src/components/dbus/test/CMakeLists.txt | 19 +- src/components/formatters/CMakeLists.txt | 24 +- src/components/formatters/test/CMakeLists.txt | 24 +- src/components/hmi_message_handler/CMakeLists.txt | 37 +- .../hmi_message_handler/test/CMakeLists.txt | 35 +- .../include/utils/threads/CMakeLists.txt | 5 - src/components/interfaces/CMakeLists.txt | 66 +- src/components/media_manager/CMakeLists.txt | 119 +- src/components/media_manager/test/CMakeLists.txt | 10 +- src/components/policy/CMakeLists.txt | 94 +- src/components/policy/test/CMakeLists.txt | 23 +- src/components/protocol/CMakeLists.txt | 18 +- src/components/protocol_handler/CMakeLists.txt | 13 +- .../protocol_handler/test/CMakeLists.txt | 20 +- src/components/qt_hmi/test/CMakeLists.txt | 3 - src/components/resumption/CMakeLists.txt | 9 +- src/components/resumption/test/CMakeLists.txt | 17 +- src/components/rpc_base/CMakeLists.txt | 28 +- src/components/rpc_base/test/CMakeLists.txt | 31 +- src/components/security_manager/CMakeLists.txt | 25 +- .../security_manager/test/CMakeLists.txt | 24 +- src/components/smart_objects/CMakeLists.txt | 30 +- src/components/smart_objects/test/CMakeLists.txt | 27 +- src/components/telemetry_monitor/CMakeLists.txt | 21 +- .../telemetry_monitor/test/CMakeLists.txt | 24 +- src/components/transport_manager/CMakeLists.txt | 102 +- .../transport_manager/test/CMakeLists.txt | 27 +- .../transport_manager/test/raw_message_matcher.cc | 2 +- src/components/utils/CMakeLists.txt | 107 +- .../utils/src/qdb_wrapper/CMakeLists.txt | 54 - src/components/utils/src/signals_linux.cc | 83 - src/components/utils/src/signals_posix.cc | 83 + src/components/utils/src/threads/posix_thread.cc | 306 -- src/components/utils/src/threads/thread_posix.cc | 306 ++ src/components/utils/test/CMakeLists.txt | 90 +- .../utils/test/test_generator/CMakeLists.txt | 35 +- src/plugins/CMakeLists.txt | 2 +- src/plugins/appenders/CMakeLists.txt | 20 +- tools/cmake/helpers/cotire.cmake | 3917 ++++++++++++++++++++ tools/cmake/helpers/generators.cmake | 62 + tools/cmake/helpers/platform.cmake | 96 + tools/cmake/helpers/sources.cmake | 166 + tools/cmake/modules/FindGlib-2.0.cmake | 43 + tools/cmake/modules/FindGstreamer-1.0.cmake | 136 + tools/cmake/modules/FindLibXML2.cmake | 20 + tools/cmake/modules/FindQt5Core.cmake | 10 + tools/cmake/modules/FindQt5DBus.cmake | 10 + tools/cmake/modules/FindQt5Qml.cmake | 10 + tools/cmake/modules/FindQt5Quick.cmake | 10 + tools/cmake/modules/FindSDLGstreamer.cmake | 42 + tools/cmake/modules/FindSDLLibUSB.cmake | 19 + tools/cmake/modules/FindSDLOpenSSL.cmake | 18 + tools/cmake/modules/FindSDLSqlite3.cmake | 15 + tools/cmake/modules/FindSqlite3.cmake | 81 + tools/cmake/modules/FindUDev.cmake | 53 + tools/intergen/test/CMakeLists.txt | 4 +- 160 files changed, 12622 insertions(+), 12598 deletions(-) delete mode 100644 cmake/Modules/FindGlib-2.0.cmake delete mode 100644 cmake/Modules/FindGstreamer-1.0.cmake delete mode 100644 cmake/Modules/FindLibXML2.cmake delete mode 100644 cmake/Modules/FindQt5Core.cmake delete mode 100644 cmake/Modules/FindQt5DBus.cmake delete mode 100644 cmake/Modules/FindQt5Qml.cmake delete mode 100644 cmake/Modules/FindQt5Quick.cmake delete mode 100644 cmake/Modules/FindSqlite3.cmake delete mode 100644 cmake/Modules/FindUDev.cmake delete mode 100644 cmake/Modules/cotire.cmake delete mode 100644 cmake/Modules/sources.cmake delete mode 100644 src/3rd_party-static/MessageBroker/CMakeLists.txt delete mode 100644 src/3rd_party-static/MessageBroker/include/CMessageBroker.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/CMessageBrokerRegistry.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/CSender.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/MBDebugHelper.h delete mode 100644 src/3rd_party-static/MessageBroker/include/mb_client.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/mb_controller.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/mb_server.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/mb_tcpclient.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/mb_tcpserver.hpp delete mode 100644 src/3rd_party-static/MessageBroker/include/networking.h delete mode 100644 src/3rd_party-static/MessageBroker/include/system.h delete mode 100644 src/3rd_party-static/MessageBroker/include/websocket_handler.hpp delete mode 100644 src/3rd_party-static/MessageBroker/src/client/mb_client.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/client/mb_controller.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/client/mb_tcpclient.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.hpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.hpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.hpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.hpp delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBroker.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBrokerRegistry.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/libMBDebugHelper.h delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.h delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/system.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/lib_messagebroker/websocket_handler.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/server/mb_server.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/server/mb_tcpserver.cpp delete mode 100644 src/3rd_party-static/MessageBroker/src/server/networking.cpp create mode 100644 src/3rd_party-static/message_broker/CMakeLists.txt create mode 100644 src/3rd_party-static/message_broker/include/CMessageBroker.hpp create mode 100644 src/3rd_party-static/message_broker/include/CMessageBrokerRegistry.hpp create mode 100644 src/3rd_party-static/message_broker/include/CSender.hpp create mode 100644 src/3rd_party-static/message_broker/include/MBDebugHelper.h create mode 100644 src/3rd_party-static/message_broker/include/mb_client.hpp create mode 100644 src/3rd_party-static/message_broker/include/mb_controller.hpp create mode 100644 src/3rd_party-static/message_broker/include/mb_server.hpp create mode 100644 src/3rd_party-static/message_broker/include/mb_tcpclient.hpp create mode 100644 src/3rd_party-static/message_broker/include/mb_tcpserver.hpp create mode 100644 src/3rd_party-static/message_broker/include/networking.h create mode 100644 src/3rd_party-static/message_broker/include/system.h create mode 100644 src/3rd_party-static/message_broker/include/websocket_handler.hpp create mode 100644 src/3rd_party-static/message_broker/src/client/mb_client.cpp create mode 100644 src/3rd_party-static/message_broker/src/client/mb_controller.cpp create mode 100644 src/3rd_party-static/message_broker/src/client/mb_tcpclient.cpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.cpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.hpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.cpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.hpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.cpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.hpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerServer.cpp create mode 100644 src/3rd_party-static/message_broker/src/example/MessageBrokerServer.hpp create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBroker.cpp create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBrokerRegistry.cpp create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/libMBDebugHelper.h create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/md5.cpp create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/md5.h create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp create mode 100644 src/3rd_party-static/message_broker/src/lib_messagebroker/websocket_handler.cpp create mode 100644 src/3rd_party-static/message_broker/src/server/mb_server.cpp create mode 100644 src/3rd_party-static/message_broker/src/server/mb_tcpserver.cpp create mode 100644 src/3rd_party-static/message_broker/src/server/networking.cpp delete mode 100644 src/3rd_party/iap.armv7-qnx.runtime.tar.bz2 delete mode 100644 src/3rd_party/iap.build.tar.bz2 delete mode 100644 src/components/HMI/IVSU/PROPRIETARY_REQUEST~ delete mode 100755 src/components/application_manager/test/message_helper/CMakeLists.txt.user delete mode 100644 src/components/include/utils/threads/CMakeLists.txt delete mode 100644 src/components/utils/src/qdb_wrapper/CMakeLists.txt delete mode 100644 src/components/utils/src/signals_linux.cc create mode 100644 src/components/utils/src/signals_posix.cc delete mode 100644 src/components/utils/src/threads/posix_thread.cc create mode 100644 src/components/utils/src/threads/thread_posix.cc create mode 100644 tools/cmake/helpers/cotire.cmake create mode 100644 tools/cmake/helpers/generators.cmake create mode 100644 tools/cmake/helpers/platform.cmake create mode 100644 tools/cmake/helpers/sources.cmake create mode 100644 tools/cmake/modules/FindGlib-2.0.cmake create mode 100644 tools/cmake/modules/FindGstreamer-1.0.cmake create mode 100644 tools/cmake/modules/FindLibXML2.cmake create mode 100644 tools/cmake/modules/FindQt5Core.cmake create mode 100644 tools/cmake/modules/FindQt5DBus.cmake create mode 100644 tools/cmake/modules/FindQt5Qml.cmake create mode 100644 tools/cmake/modules/FindQt5Quick.cmake create mode 100644 tools/cmake/modules/FindSDLGstreamer.cmake create mode 100644 tools/cmake/modules/FindSDLLibUSB.cmake create mode 100644 tools/cmake/modules/FindSDLOpenSSL.cmake create mode 100644 tools/cmake/modules/FindSDLSqlite3.cmake create mode 100644 tools/cmake/modules/FindSqlite3.cmake create mode 100644 tools/cmake/modules/FindUDev.cmake diff --git a/.travis.yml b/.travis.yml index b8b82df3fc..5c118102fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,6 @@ only: - \/feature\/.+ - \/fix\/.+ - \/hotfix\/.+ - - \/release\/.+ addons: apt: @@ -20,10 +19,10 @@ addons: - libbluetooth3 - libbluetooth-dev - libudev-dev + - libusb-1.0 - cmake - html2text - clang-format-3.6 - - binutils before_install: - sudo apt-get -qq update - sudo apt-get -q -y install libavahi-client-dev bluez-tools sqlite3 libsqlite3-dev automake1.11 @@ -34,7 +33,8 @@ script: - bash -e tools/infrastructure/check_style.sh - mkdir build && cd build && cmake ../ -DBUILD_TESTS=ON -DENABLE_GCOV=ON && make install - sudo ldconfig - - make test + - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:`pwd`/bin/lib ; make test + - bash ../tools/infrastructure/show_disabled.sh - bash -ex ../tools/infrastructure/collect_coverage.sh ./ env: global: @@ -56,6 +56,10 @@ deploy: notifications: email: - AKutsan@luxoft.com + - AByzhynar@luxoft.com - NSnitsar@luxoft.com + - RMalynovskyi@luxoft.com - MGhiumiusliu@luxoft.com + - AGaliuzov@luxoft.com + - ANosach@luxoft.com diff --git a/CMakeLists.txt b/CMakeLists.txt index 3252f7071d..2a4ae6509a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2015, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,9 +28,13 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -cmake_minimum_required(VERSION 2.8.0) +cmake_minimum_required(VERSION 2.8.11) set (PROJECT smartDeviceLinkCore) +project (${PROJECT}) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/tools/cmake/modules/") + +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) #Jenkins integration section #dont modify this section if you dont know details about integration with Jenkins!!! @@ -40,9 +44,9 @@ option(EXTENDED_MEDIA_MODE "Turn on and off extended Madia Manager features rela option(BUILD_SHARED_LIBS "Build all libraries as shared (if ON) or static (if OFF)" OFF) option(BUILD_BT_SUPPORT "Bluetooth support" ON) option(BUILD_USB_SUPPORT "libusb support" ON) -option(BUILD_BACKTRACE_SUPPORT "backtrace support" ON) -option(BUILD_TESTS "Possibility to build and run tests" OFF) -option(TELEMETRY_MONITOR "Enable profiling time test util" ON) +option(BUILD_BACKTRACE_SUPPORT "backtrace support" OFF) +option(BUILD_TESTS "Possibility to build and run tests" ON) +option(TELEMETRY_MONITOR "Enable profiling time test util" OFF) option(ENABLE_LOG "Logging feature" ON) option(ENABLE_GCOV "gcov code coverage feature" OFF) option(ENABLE_SANITIZE "Sanitize tool" OFF) @@ -67,9 +71,9 @@ set(POLICY_OPTION "$ENV{POLICY_TYPE}") set(SECURITY_OPTION "$ENV{SECURITY_MODE}") set(COMPONENTS_DIR ${CMAKE_SOURCE_DIR}/src/components) set(SNAPSHOT_TAG "$ENV{SNAPSHOT_TAG}") - set(CMAKE_CXX_COMPILER $ENV{CMAKE_CXX_COMPILER}) set(CMAKE_C_COMPILER $ENV{CMAKE_C_COMPILER}) +set(BUILDDIR "$ENV{BUILDDIR}") if (ARCH_TYPE_OPTION) if (NOT (${ARCH_TYPE_OPTION} STREQUAL "x86") AND NOT (${ARCH_TYPE_OPTION} STREQUAL "armv7")) @@ -173,13 +177,6 @@ add_custom_target(genivi-tarball COMMAND tar -cz -C /tmp/GENIVI -f ${CMAKE_BINARY_DIR}/genivi.tar.gz . ) - -project (${PROJECT}) - -#ADD_DEPENDENCIES(${PROJECT} Policy) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") - # Please do not change compiler/linker flags if You do not know how particular # flag is handled by CMake set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_BINARY_DIR}) @@ -231,14 +228,26 @@ endif(USE_DISTCC) if(ENABLE_SANITIZE) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") + message(STATUS "Sanitizing enabled") endif() + if(ENABLE_GCOV) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") add_definitions(-DGCOV_ENABLED) + message(STATUS "GCOV enabled") endif() + set(CMAKE_CXX_FLAGS_RELEASE " -DNDEBUG -s -O2") set(CMAKE_CXX_FLAGS_DEBUG " -DDEBUG -g3 -ggdb3") +if(QT_PORT) + set(CMAKE_AUTOMOC ON) + find_package(Qt5 REQUIRED Core Network) + include_directories( + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Network_INCLUDE_DIRS}) +endif () + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") add_definitions(-DOS_LINUX) elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") @@ -248,137 +257,74 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") SET(EXTENDED_MEDIA_MODE OFF) endif() - if (BUILD_USB_SUPPORT) add_definitions(-DUSB_SUPPORT) find_package(UDev REQUIRED) - message(STATUS "USB support is enabled") + message(STATUS "USB support enabled") endif() - if (BUILD_BT_SUPPORT) add_definitions(-DBLUETOOTH_SUPPORT) - message(STATUS "Bluetooth support is enabled") + message(STATUS "Bluetooth support enabled") endif() if (BUILD_BACKTRACE_SUPPORT) add_definitions(-DBACKTRACE_SUPPORT) + message(STATUS "Backtrace support enabled") endif() if(ENABLE_LOG) add_definitions(-DENABLE_LOG) set(install-3rd_party_logger "install-3rd_party_logger") + message(STATUS "Logger enabled") endif() if (TELEMETRY_MONITOR) - add_definitions(-DTELEMETRY_MONITOR) + add_definitions(-DTELEMETRY_MONITOR) + message(STATUS "Telemetry monitor enabled") endif() if (ENABLE_EXTENDED_POLICY) - add_definitions(-DEXTENDED_POLICY) + add_definitions(-DEXTENDED_POLICY) + message(STATUS "Extended policy enabled") endif() # TODO(AK): check current OS here add_definitions(-DOS_POSIX) if (EXTENDED_MEDIA_MODE) -add_definitions(-DEXTENDED_MEDIA_MODE) -# required to find 'glibconfig.h' -find_package(PkgConfig) -pkg_check_modules(GLIB2 REQUIRED glib-2.0) -add_definitions(${GLIB2_CFLAGS}) + add_definitions(-DEXTENDED_MEDIA_MODE) + message(STATUS "Extended media mode enabled") + # required to find 'glibconfig.h' + find_package(PkgConfig) + pkg_check_modules(GLIB2 REQUIRED glib-2.0) + add_definitions(${GLIB2_CFLAGS}) endif() - -# --- Interface generator - -find_package(PythonInterp) -if(NOT PYTHONINTERP_FOUND) - message(STATUS "Python interpreter is not found") - message(STATUS "To install it type in the command line:") - message(STATUS "sudo apt-get install python") - message(FATAL_ERROR "Exiting!") -endif(NOT PYTHONINTERP_FOUND) - -if (HMI STREQUAL "qt") - cmake_minimum_required(VERSION 2.8.11) - if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - set(qt_version "4.8.5") - else () - set(qt_version "5.1.0") - endif () - - execute_process( - COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} - OUTPUT_VARIABLE qt_bin_dir - ) - message(STATUS "Binary directory Qt ${qt_version} is ${qt_bin_dir}") - set(ENV{PATH} ${qt_bin_dir}:$ENV{PATH}) - - if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - find_package(Qt4 ${qt_version} REQUIRED QtCore QtGui QtDBus QtDeclarative) - else () - find_package(Qt5Core REQUIRED) - find_package(Qt5DBus REQUIRED) - find_package(Qt5Qml REQUIRED) - find_package(Qt5Quick REQUIRED) - set(qmlplugindump_binary ${qt_bin_dir}/qmlplugindump) - endif () -endif() - -set(INTEFRACE_GENERATOR "${PROJECT_SOURCE_DIR}/tools/InterfaceGenerator/Generator.py") -set(INTEFRACE_GENERATOR_CMD ${PYTHON_EXECUTABLE} -B ${INTEFRACE_GENERATOR}) -file(GLOB_RECURSE INTERFACE_GENERATOR_DEPENDENCIES "${PROJECT_SOURCE_DIR}/tools/InterfaceGenerator/*.*") - -macro (GenerateInterface arg_xml_name arg_namespace parser_type) - string(REGEX MATCH "^[a-zA-Z_0-9]*[^.]" file_name ${arg_xml_name}) # TODO: make expression more robust - - set(hpp_file - "${CMAKE_CURRENT_BINARY_DIR}/${file_name}.h" - "${CMAKE_CURRENT_BINARY_DIR}/${file_name}_schema.h" - ) - - set(cpp_file "${CMAKE_CURRENT_BINARY_DIR}/${file_name}_schema.cc") - set(full_xml_name "${CMAKE_CURRENT_SOURCE_DIR}/${arg_xml_name}") - - add_custom_command( OUTPUT ${hpp_file} ${cpp_file} - COMMAND ${INTEFRACE_GENERATOR_CMD} ${full_xml_name} ${arg_namespace} ${CMAKE_CURRENT_BINARY_DIR} "--parser-type" "${parser_type}" - DEPENDS ${INTERFACE_GENERATOR_DEPENDENCIES} ${full_xml_name} - COMMENT "Generating files:\n ${hpp_file}\n ${cpp_file}\nfrom:\n ${arg_xml_name} ..." - VERBATIM - ) - - include_directories ( - ${COMPONENTS_DIR}/smart_objects/include - ${COMPONENTS_DIR}/formatters/include/ - ${CMAKE_BINARY_DIR} - ) - - add_library("${file_name}" ${cpp_file}) -endmacro(GenerateInterface) - -# --- Useful macro -macro(create_test NAME SOURCES LIBS) - add_executable("${NAME}" ${CMAKE_SOURCE_DIR}/src/components/test_main.cc ${SOURCES}) - target_link_libraries("${NAME}" ${LIBS}) - target_link_libraries("${NAME}" Utils) +if(HMI STREQUAL "qt") if(CMAKE_SYSTEM_NAME STREQUAL "QNX") - add_test(${NAME} ${CMAKE_SOURCE_DIR}/qnx/remote_run_test.sh ${NAME}) - elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") - add_test(NAME ${NAME} - COMMAND ${NAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/) + set(qt_version "4.8.5") else() - add_test(${NAME} ${NAME}) + set(qt_version "5.1.0") endif() -endmacro(create_test) -# --replace in list macro -macro(LIST_REPLACE LIST INDEX NEWVALUE) - list(INSERT ${LIST} ${INDEX} ${NEWVALUE}) - MATH(EXPR __INDEX "${INDEX} + 1") - list (REMOVE_AT ${LIST} ${__INDEX}) -endmacro(LIST_REPLACE) + execute_process( + COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} + OUTPUT_VARIABLE qt_bin_dir + ) + message(STATUS "Binary directory Qt ${qt_version} is ${qt_bin_dir}") + set(ENV{PATH} ${qt_bin_dir}:$ENV{PATH}) + if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + find_package(Qt4 ${qt_version} REQUIRED QtCore QtGui QtDBus QtDeclarative) + else () + find_package(Qt5Core REQUIRED) + find_package(Qt5DBus REQUIRED) + find_package(Qt5Qml REQUIRED) + find_package(Qt5Quick REQUIRED) + set(qmlplugindump_binary ${qt_bin_dir}/qmlplugindump) + endif() +endif() # Building application @@ -417,243 +363,9 @@ endif() include_directories( ${COMPONENTS_DIR}/include ${COMPONENTS_DIR}/protocol/include -if (BUILD_TESTS) - ${COMPONENTS_DIR}/include/test endif () ) -# --- 3rd party libs -INCLUDE(${CMAKE_CURRENT_SOURCE_DIR}/src/3rd_party/set_3rd_party_paths.cmake) - -set(3RD_PARTY_SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/3rd_party) -set(3RD_PARTY_BINARY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src/3rd_party) - -set (install-3rd_party_logger_var "") -set (install-3rd_party_dbus_var "") - -if(NO_REBUILD_3RD_PARTY) - set(NO_REBUILD_3RD_PARTY_LOGGER ON) - set(NO_REBUILD_3RD_PARTY_DBUS ON) -endif() - -if(FORCE_3RD_PARTY) - if(NO_REBUILD_3RD_PARTY) - message(FATAL_ERROR "Please don't turn on both FORCE_3RD_PARTY and NO_REBUILD_3RD_PARTY at the same time.") - else() - set(FORCE_3RD_PARTY_LOGGER ON) - set(FORCE_3RD_PARTY_DBUS ON) - endif() -endif() - -if(ENABLE_LOG) - if(NO_REBUILD_3RD_PARTY_LOGGER) - message(STATUS "Not rebuilding logger.") - else() - if(FORCE_3RD_PARTY_LOGGER) - message(STATUS "Force to rebuild logger.") - - #build logger - add_custom_target(3rd_party_logger - make - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - - #install logger - #install either to default place with sudo or non-default plase without sudo. - #to install with sudo to non-default place use manual installation - add_custom_target(install-3rd_party_logger - COMMAND /bin/bash -c \"USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; - if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then - sudo -k \; - sudo make install\; - else - make install\; - fi\" - DEPENDS 3rd_party_logger - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - else() - #build logger - add_custom_target(3rd_party_logger - COMMAND /bin/bash -c \"cd ${CMAKE_CURRENT_SOURCE_DIR} && - grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]\; then - VAR1=\\$$\( readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 2>/dev/null\)\; - VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; - VAR2=-1\; - cd ${CMAKE_CURRENT_SOURCE_DIR}\; - git log . 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]; then - VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/apache-log4cxx-0.10.0\)\; - fi\; - if [ \\$$VAR1 != \\$$VAR2 ]\; then - echo " Need to rebuild logger. " \; - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make\; - else - echo " Logger is actual. " \; - fi\; - else - echo " Need to build logger. " \; - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make\; - fi\" - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - - #install logger - #install either to default place with sudo or non-default plase without sudo. - #to install with sudo to non-default place use manual installation - add_custom_target(install-3rd_party_logger - COMMAND /bin/bash -c \"cd ${CMAKE_CURRENT_SOURCE_DIR} && - grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]\; then - VAR1=\\$$\( readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 2>/dev/null\)\; - VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; - VAR2=-1\; - cd ${CMAKE_CURRENT_SOURCE_DIR}\; - git log . 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]; then - VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/apache-log4cxx-0.10.0\)\; - fi\; - if [ \\$$VAR1 != \\$$VAR2 ]\; then - USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; - if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - sudo -k \; - sudo make install\; - else - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make install\; - fi\; - fi\; - else - USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; - if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - sudo -k \; - sudo make install\; - else - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make install\; - fi\; - fi\" - DEPENDS 3rd_party_logger - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - endif() - - set (install-3rd_party_logger_var "install-3rd_party_logger") - endif() -endif() - -if (HMIADAPTER STREQUAL "dbus") - if(NO_REBUILD_3RD_PARTY_DBUS) - message(STATUS "Not rebuilding D-Bus.") - else() - if(FORCE_3RD_PARTY_DBUS) - message(STATUS "Force to rebuild D-Bus.") - - #build d-bus - add_custom_target(3rd_party_dbus - make - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - - #install d-bus - #install either to default place with sudo or non-default plase without sudo. - #to install with sudo to non-default place use manual installation - add_custom_target(install-3rd_party_dbus - COMMAND /bin/bash -c \"USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; - if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then - sudo -k \; - sudo make install\; - else - make install\; - fi\" - DEPENDS 3rd_party_dbus - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - else() - #build d-bus - add_custom_target(3rd_party_dbus - COMMAND /bin/bash -c \"grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]\; then - VAR1=\\$$\(readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 2>/dev/null\)\; - VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; - VAR2=-1\; - cd ${CMAKE_CURRENT_SOURCE_DIR}\; - git log . 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]; then - VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/dbus-1.7.8\)\; - fi\; - if [ \\$$VAR1 != \\$$VAR2 ]\; then - echo " Need to rebuild D-Bus. " \; - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make\; - else - echo " D-Bus is actual. " \; - fi\; - else - echo " Need to build D-Bus. " \; - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make\; - fi\" - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - - #install d-bus - #install either to default place with sudo or non-default plase without sudo. - #to install with sudo to non-default place use manual installation - add_custom_target(install-3rd_party_dbus - COMMAND /bin/bash -c \"grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]\; then - VAR1=\\$$\(readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 2>/dev/null\)\; - VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; - VAR2=-1\; - cd ${CMAKE_CURRENT_SOURCE_DIR}\; - git log . 1>/dev/null 2>&1\; - if [ \\$$? == 0 ]; then - VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/dbus-1.7.8\)\; - fi\; - if [ \\$$VAR1 != \\$$VAR2 ]\; then - USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; - if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - sudo -k \; - sudo make install\; - else - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make install\; - fi\; - fi\; - else - USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; - if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - sudo -k \; - sudo make install\; - else - cd ${3RD_PARTY_BINARY_DIRECTORY}\; - make install\; - fi\; - fi\" - DEPENDS 3rd_party_dbus - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} - ) - endif() - - set (install-3rd_party_dbus_var "install-3rd_party_dbus") - endif() -endif() - -add_subdirectory(${3RD_PARTY_SOURCE_DIRECTORY} ${3RD_PARTY_BINARY_DIRECTORY} EXCLUDE_FROM_ALL) -add_custom_target(install-3rd_party - DEPENDS ${install-3rd_party_logger_var} - DEPENDS ${install-3rd_party_dbus_var} - WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} -) - find_package(OpenSSL REQUIRED) if(ENABLE_LOG) include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) @@ -664,34 +376,38 @@ if(ENABLE_SECURITY) set(SecurityManagerLibrary SecurityManager) set(SecurityManagerIncludeDir ${COMPONENTS_DIR}/security_manager/include) #set(SecurityManagerTestIncludeDir ${CMAKE_SOURCE_DIR}/test/components/security_manager/include) + message(STATUS "Security enabled") endif() if(ENABLE_HMI_PTU_DECRYPTION) - MESSAGE("USE DHMI_PTU_PARSER") add_definitions(-DUSE_HMI_PTU_DECRYPTION) + message(STATUS "HMI PTU decription enabled") endif() set(RTLIB rt) if(CMAKE_SYSTEM_NAME STREQUAL "QNX") -set(RTLIB ) + set(RTLIB ) endif() # Building tests if(BUILD_TESTS) enable_testing() add_definitions(-DBUILD_TESTS) - # Framework GoogleTest is also integrated together gmock - # and must not be added separately - add_subdirectory(./src/3rd_party-static/gmock-1.7.0) + include_directories( + ${COMPONENTS_DIR}/include/test + ) + message(STATUS "Tests enabled") endif() +# --- 3rd party libs +add_subdirectory(./src/3rd_party EXCLUDE_FROM_ALL) + # --- 3rd party libs (static) add_subdirectory(./src/3rd_party-static) # --- Tools add_subdirectory(./tools) - # --- Components add_subdirectory(./src/components) @@ -701,35 +417,31 @@ add_subdirectory(./src/appMain) # --- Plugins add_subdirectory(./src/plugins) - -# Building tests -if(BUILD_TESTS) - # Directory test is deprecated. Use src/components//test - include(Dart) - #add_subdirectory(./test) -endif() +add_dependencies(${PROJECT} Policy) +add_dependencies(${PROJECT} copy_policy_library) # Building documentation # At first creating directory for generated documentation. Unfortunately doxygen # cannot generate it byself -FIND_PACKAGE(Doxygen) - IF(DOXYGEN_FOUND) +find_package(Doxygen) + if(DOXYGEN_FOUND) option(DOXYGEN_ENABLE_DIAGRAMS "Enable graphical diagram generation" ON) + message(STATUS "Doxygen found. Documentation will be generated") if(DOXYGEN_ENABLE_DIAGRAMS) set(DOXYGEN_ENABLE_DIAGRAMS_PARAM "YES") - else(DOXYGEN_ENABLE_DIAGRAMS) + else() set(DOXYGEN_ENABLE_DIAGRAMS_PARAM "NO") endif() configure_file("${PROJECT_SOURCE_DIR}/Doxyfile" "${PROJECT_BINARY_DIR}/Doxyfile") file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/doc/doxygen") - ADD_CUSTOM_TARGET(doxygen COMMAND ${DOXYGEN_EXECUTABLE} "${PROJECT_BINARY_DIR}/Doxyfile") - ELSE(DOXYGEN_FOUND) - MESSAGE(STATUS "Doxygen not found. Documentation will not be generated") - MESSAGE(STATUS "To enable documentation generation please install doxygen and graphviz packages") - MESSAGE(STATUS "sudo apt-get install doxygen graphviz") - MESSAGE(STATUS "To enable processing of MscGen comments please install mscgen") - MESSAGE(STATUS "sudo apt-get install mscgen") -ENDIF(DOXYGEN_FOUND) + add_custom_target(doxygen COMMAND ${DOXYGEN_EXECUTABLE} "${PROJECT_BINARY_DIR}/Doxyfile") + else() + message(STATUS "Doxygen not found. Documentation will not be generated") + message(STATUS "To enable documentation generation please install doxygen and graphviz packages") + message(STATUS "sudo apt-get install doxygen graphviz") + message(STATUS "To enable processing of MscGen comments please install mscgen") + message(STATUS "sudo apt-get install mscgen") +endif() diff --git a/cmake/Modules/FindGlib-2.0.cmake b/cmake/Modules/FindGlib-2.0.cmake deleted file mode 100644 index b39da141c9..0000000000 --- a/cmake/Modules/FindGlib-2.0.cmake +++ /dev/null @@ -1,43 +0,0 @@ -FILE(TO_CMAKE_PATH "$ENV{GLIB2_DIR}" TRY1_DIR) -FILE(TO_CMAKE_PATH "${GLIB2_DIR}" TRY2_DIR) -FILE(GLOB GLIB2_DIR ${TRY1_DIR} ${TRY2_DIR}) - -FIND_PATH(GLIB_glib_2_INCLUDE_DIR glib.h - PATHS ${GLIB2_DIR}/include ${GLIB2_DIR}/include/glib-2.0 /usr/local/include/glib-2.0 /usr/include/glib-2.0 /usr/lib/glib-2.0/include/ - ENV INCLUDE DOC "Directory containing glib.h include file") - -FIND_PATH(GLIB_glibconfig_2_INCLUDE_DIR glibconfig.h - PATHS ${GLIB2_DIR}/include ${GLIB2_DIR}/include/glib-2.0 ${GLIB2_DIR}/lib/include ${GLIB2_DIR}/lib/glib-2.0/include /usr/local/include/glib-2.0 /usr/include/glib-2.0 /usr/lib/glib-2.0/include /usr/local/lib/glib-2.0/include - ENV INCLUDE DOC "Directory containing glibconfig.h include file") - -FIND_LIBRARY(GLIB_glib_2_LIBRARY NAMES glib-2.0 - PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "glib library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GLIB_gmodule_2_LIBRARY NAMES gmodule-2.0 - PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gmodule library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GLIB_gobject_2_LIBRARY NAMES gobject-2.0 - PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gobject library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GLIB_gthread_2_LIBRARY NAMES gthread-2.0 - PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gthread library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -IF (GLIB_glib_2_INCLUDE_DIR AND GLIB_glibconfig_2_INCLUDE_DIR AND GLIB_glib_2_LIBRARY AND GLIB_gmodule_2_LIBRARY AND GLIB_gobject_2_LIBRARY AND GLIB_gthread_2_LIBRARY) - SET(GLIB2_INCLUDE_DIR ${GLIB_glib_2_INCLUDE_DIR} ${GLIB_glibconfig_2_INCLUDE_DIR}) - list(REMOVE_DUPLICATES GLIB2_INCLUDE_DIR) - SET(GLIB2_LIBRARIES ${GLIB_glib_2_LIBRARY} ${GLIB_gmodule_2_LIBRARY} ${GLIB_gobject_2_LIBRARY} ${GLIB_gthread_2_LIBRARY}) - list(REMOVE_DUPLICATES GLIB2_LIBRARIES) - SET(GLIB2_FOUND TRUE) -ENDIF (GLIB_glib_2_INCLUDE_DIR AND GLIB_glibconfig_2_INCLUDE_DIR AND GLIB_glib_2_LIBRARY AND GLIB_gmodule_2_LIBRARY AND GLIB_gobject_2_LIBRARY AND GLIB_gthread_2_LIBRARY) diff --git a/cmake/Modules/FindGstreamer-1.0.cmake b/cmake/Modules/FindGstreamer-1.0.cmake deleted file mode 100644 index 8f1d69d01b..0000000000 --- a/cmake/Modules/FindGstreamer-1.0.cmake +++ /dev/null @@ -1,136 +0,0 @@ -FILE(TO_CMAKE_PATH "$ENV{GSTREAMER_DIR}" TRY1_DIR) -FILE(TO_CMAKE_PATH "${GSTREAMER_DIR}" TRY2_DIR) -FILE(GLOB GSTREAMER_DIR ${TRY1_DIR} ${TRY2_DIR}) - -FIND_PATH(GSTREAMER_gst_INCLUDE_DIR gst/gst.h - PATHS ${GSTREAMER_DIR}/include /usr/local/include/gstreamer-1.0 /usr/include/gstreamer-1.0 - ENV INCLUDE DOC "Directory containing gst/gst.h include file") - -FIND_PATH(GSTREAMER_gstconfig_INCLUDE_DIR gst/gstconfig.h - PATHS ${GSTREAMER_DIR}/include ${GSTREAMER_DIR}/lib/include /usr/local/include/gstreamer-1.0 /usr/include/gstreamer-1.0 /usr/local/lib/include/gstreamer-1.0 /usr/lib/include/gstreamer-1.0 - ENV INCLUDE DOC "Directory containing gst/gstconfig.h include file") - -FIND_LIBRARY(GSTREAMER_gstaudio_LIBRARY NAMES gstaudio-1.0 libgstaudio-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstaudio library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstapp_LIBRARY NAMES gstapp-1.0 libgstapp-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstapp library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstbase_LIBRARY NAMES gstbase-1.0 libgstbase-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstbase library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GLIB_gstcdda_LIBRARY NAMES gstcdda-1.0 libgstcdda-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstcdda library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstcontroller_LIBRARY NAMES gstcontroller-1.0 libgstcontroller-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstcontroller library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstdataprotocol_LIBRARY NAMES gstdataprotocol-1.0 libgstdataprotocol-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstdataprotocol library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstinterfaces_LIBRARY NAMES gstinterfaces-1.0 libgstinterfaces-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstinterfaces library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstnet_LIBRARY NAMES gstnet-1.0 libgstnet-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstnet library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstnetbuffer_LIBRARY NAMES gstnetbuffer-1.0 libgstnetbuffer-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstnetbuffer library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstpbutils_LIBRARY NAMES gstpbutils-1.0 libgstpbutils-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstpbutils library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstreamer_LIBRARY NAMES gstreamer-1.0 libgstreamer-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstreamer library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstriff_LIBRARY NAMES gstriff-1.0 libgstriff-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstriff library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstrtp_LIBRARY NAMES gstrtp-1.0 libgstrtp-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstrtp library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstrtsp_LIBRARY NAMES gstrtsp-1.0 libgstrtsp-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstrtsp library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstsdp_LIBRARY NAMES gstsdp-1.0 libgstsdp-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstsdp library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gsttag_LIBRARY NAMES gsttag-1.0 libgsttag-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gsttag library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - -FIND_LIBRARY(GSTREAMER_gstvideo_LIBRARY NAMES gstvideo-1.0 libgstvideo-1.0 - PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib - ENV LIB - DOC "gstvideo library to link with" - NO_SYSTEM_ENVIRONMENT_PATH) - - -IF (GSTREAMER_gst_INCLUDE_DIR AND GSTREAMER_gstconfig_INCLUDE_DIR AND - GSTREAMER_gstaudio_LIBRARY AND GSTREAMER_gstbase_LIBRARY AND GSTREAMER_gstcontroller_LIBRARY AND - GSTREAMER_gstdataprotocol_LIBRARY AND GSTREAMER_gstinterfaces_LIBRARY AND GSTREAMER_gstnet_LIBRARY AND - GSTREAMER_gstnetbuffer_LIBRARY AND GSTREAMER_gstpbutils_LIBRARY AND GSTREAMER_gstreamer_LIBRARY AND - GSTREAMER_gstriff_LIBRARY AND GSTREAMER_gstrtp_LIBRARY AND GSTREAMER_gstrtsp_LIBRARY AND GSTREAMER_gstsdp_LIBRARY AND - GSTREAMER_gsttag_LIBRARY AND GSTREAMER_gstvideo_LIBRARY) - SET(GSTREAMER_INCLUDE_DIR ${GSTREAMER_gst_INCLUDE_DIR} ${GSTREAMER_gstconfig_INCLUDE_DIR}) - list(REMOVE_DUPLICATES GSTREAMER_INCLUDE_DIR) - SET(GSTREAMER_LIBRARIES ${GSTREAMER_gstaudio_LIBRARY} ${GSTREAMER_gstbase_LIBRARY} - ${GSTREAMER_gstcontroller_LIBRARY} ${GSTREAMER_gstdataprotocol_LIBRARY} ${GSTREAMER_gstinterfaces_LIBRARY} - ${GSTREAMER_gstnet_LIBRARY} ${GSTREAMER_gstnetbuffer_LIBRARY} ${GSTREAMER_gstpbutils_LIBRARY} - ${GSTREAMER_gstreamer_LIBRARY} ${GSTREAMER_gstriff_LIBRARY} ${GSTREAMER_gstrtp_LIBRARY} - ${GSTREAMER_gstrtsp_LIBRARY} ${GSTREAMER_gstsdp_LIBRARY} ${GSTREAMER_gsttag_LIBRARY} ${GSTREAMER_gstvideo_LIBRARY}) - list(REMOVE_DUPLICATES GSTREAMER_LIBRARIES) - SET(GSTREAMER_FOUND TRUE) -ENDIF (GSTREAMER_gst_INCLUDE_DIR AND GSTREAMER_gstconfig_INCLUDE_DIR AND - GSTREAMER_gstaudio_LIBRARY AND GSTREAMER_gstbase_LIBRARY AND GSTREAMER_gstcontroller_LIBRARY AND - GSTREAMER_gstdataprotocol_LIBRARY AND GSTREAMER_gstinterfaces_LIBRARY AND GSTREAMER_gstnet_LIBRARY AND - GSTREAMER_gstnetbuffer_LIBRARY AND GSTREAMER_gstpbutils_LIBRARY AND GSTREAMER_gstreamer_LIBRARY AND - GSTREAMER_gstriff_LIBRARY AND GSTREAMER_gstrtp_LIBRARY AND GSTREAMER_gstrtsp_LIBRARY AND GSTREAMER_gstsdp_LIBRARY AND - GSTREAMER_gsttag_LIBRARY AND GSTREAMER_gstvideo_LIBRARY) diff --git a/cmake/Modules/FindLibXML2.cmake b/cmake/Modules/FindLibXML2.cmake deleted file mode 100644 index 1daaeb07b7..0000000000 --- a/cmake/Modules/FindLibXML2.cmake +++ /dev/null @@ -1,20 +0,0 @@ -find_path(LibXML2_ROOT_DIR NAMES include/libxml2/libxml/xpath.h) -find_library(LibXML2_LIBRARIES - NAMES xml2 - HINTS ${LibXML2_ROOT_DIR}/lib -) -find_path(LibXML2_INCLUDE_DIR - NAMES libxml/tree.h - HINTS ${LibXML2_ROOT_DIR}/include/libxml2 -) -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LibXML2 DEFAULT_MSG - LibXML2_LIBRARIES - LibXML2_INCLUDE_DIR -) - -mark_as_advanced( - LibXML2_ROOT_DIR - LibXML2_LIBRARIES - LibXML2_INCLUDE_DIR -) \ No newline at end of file diff --git a/cmake/Modules/FindQt5Core.cmake b/cmake/Modules/FindQt5Core.cmake deleted file mode 100644 index 1a2ad84842..0000000000 --- a/cmake/Modules/FindQt5Core.cmake +++ /dev/null @@ -1,10 +0,0 @@ -execute_process( - COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5CoreConfig.cmake - OUTPUT_VARIABLE config_file -) - -if(config_file STREQUAL "") - message(FATAL_ERROR "Qt5 Core module not found") -endif(config_file STREQUAL "") - -include(${config_file}) diff --git a/cmake/Modules/FindQt5DBus.cmake b/cmake/Modules/FindQt5DBus.cmake deleted file mode 100644 index d850010e97..0000000000 --- a/cmake/Modules/FindQt5DBus.cmake +++ /dev/null @@ -1,10 +0,0 @@ -execute_process( - COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5DBusConfig.cmake - OUTPUT_VARIABLE config_file -) - -if(config_file STREQUAL "") - message(FATAL_ERROR "Qt5 DBus module not found") -endif(config_file STREQUAL "") - -include(${config_file}) diff --git a/cmake/Modules/FindQt5Qml.cmake b/cmake/Modules/FindQt5Qml.cmake deleted file mode 100644 index f4bdaa8f71..0000000000 --- a/cmake/Modules/FindQt5Qml.cmake +++ /dev/null @@ -1,10 +0,0 @@ -execute_process( - COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5QmlConfig.cmake - OUTPUT_VARIABLE config_file -) - -if(config_file STREQUAL "") - message(FATAL_ERROR "Qt5 Qml module not found") -endif(config_file STREQUAL "") - -include(${config_file}) diff --git a/cmake/Modules/FindQt5Quick.cmake b/cmake/Modules/FindQt5Quick.cmake deleted file mode 100644 index 1e16340c2e..0000000000 --- a/cmake/Modules/FindQt5Quick.cmake +++ /dev/null @@ -1,10 +0,0 @@ -execute_process( - COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5QuickConfig.cmake - OUTPUT_VARIABLE config_file -) - -if(config_file STREQUAL "") - message(FATAL_ERROR "Qt5 Quick module not found") -endif(config_file STREQUAL "") - -include(${config_file}) diff --git a/cmake/Modules/FindSqlite3.cmake b/cmake/Modules/FindSqlite3.cmake deleted file mode 100644 index 514ff0b7f9..0000000000 --- a/cmake/Modules/FindSqlite3.cmake +++ /dev/null @@ -1,81 +0,0 @@ -# - Try to find Sqlite3 -# Once done this will define -# -# SQLITE3_FOUND - system has Sqlite3 -# SQLITE3_INCLUDE_DIRS - the Sqlite3 include directory -# SQLITE3_LIBRARIES - Link these to use Sqlite3 -# SQLITE3_DEFINITIONS - Compiler switches required for using Sqlite3 -# -# Copyright (c) 2008 Andreas Schneider -# -# Redistribution and use is allowed according to the terms of the New -# BSD license. -# For details see the accompanying COPYING-CMAKE-SCRIPTS file. -# - - -if (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS) - set(SQLITE3_FOUND TRUE) -else (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS) - find_package(PkgConfig) - if (PKG_CONFIG_FOUND) - pkg_check_modules(_SQLITE3 REQUIRED sqlite3>=3.7.11) - else (PKG_CONFIG_FOUND) - message(WARNING "PkgConfig isn't installed. You need to sure sqlite3>=3.7.11") - endif (PKG_CONFIG_FOUND) - - find_path(SQLITE3_INCLUDE_DIR - NAMES - sqlite3.h - PATHS - ${_SQLITE3_INCLUDEDIR} - /usr/include - /usr/local/include - /opt/local/include - /sw/include - ) - - find_library(SQLITE3_LIBRARY - NAMES - sqlite3 - PATHS - ${_SQLITE3_LIBDIR} - /usr/lib - /usr/local/lib - /opt/local/lib - /sw/lib - ) - - if (SQLITE3_LIBRARY) - set(SQLITE3_FOUND TRUE) - endif (SQLITE3_LIBRARY) - - set(SQLITE3_INCLUDE_DIRS - ${SQLITE3_INCLUDE_DIR} - ) - - if (SQLITE3_FOUND) - set(SQLITE3_LIBRARIES - ${SQLITE3_LIBRARIES} - ${SQLITE3_LIBRARY} - ) - endif (SQLITE3_FOUND) - - if (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES) - set(SQLITE3_FOUND TRUE) - endif (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES) - - if (SQLITE3_FOUND) - if (NOT Sqlite3_FIND_QUIETLY) - message(STATUS "Found Sqlite3: ${SQLITE3_LIBRARIES}") - endif (NOT Sqlite3_FIND_QUIETLY) - else (SQLITE3_FOUND) - if (Sqlite3_FIND_REQUIRED) - message(FATAL_ERROR "Could not find Sqlite3") - endif (Sqlite3_FIND_REQUIRED) - endif (SQLITE3_FOUND) - - # show the SQLITE3_INCLUDE_DIRS and SQLITE3_LIBRARIES variables only in the advanced view - mark_as_advanced(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) - -endif (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS) \ No newline at end of file diff --git a/cmake/Modules/FindUDev.cmake b/cmake/Modules/FindUDev.cmake deleted file mode 100644 index cdc8743777..0000000000 --- a/cmake/Modules/FindUDev.cmake +++ /dev/null @@ -1,53 +0,0 @@ -# razor-de: Configure libudev environment -# -# UDEV_FOUND - system has a libudev -# UDEV_INCLUDE_DIR - where to find header files -# UDEV_LIBRARIES - the libraries to link against udev -# UDEV_STABLE - it's true when is the version greater or equals to 143 - version when the libudev was stabilized in its API -# -# copyright (c) 2011 Petr Vanek -# Redistribution and use is allowed according to the terms of the BSD license. -# - -FIND_PATH( - UDEV_INCLUDE_DIR - libudev.h - /usr/include - /usr/local/include - ${UDEV_PATH_INCLUDES} -) - -FIND_LIBRARY( - UDEV_LIBRARIES - NAMES udev libudev - PATHS - /usr/lib${LIB_SUFFIX} - /usr/local/lib${LIB_SUFFIX} - ${UDEV_PATH_LIB} -) - -IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR) - SET(UDEV_FOUND "YES") - execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE) - # retvale is 0 of the condition is "true" so we need to negate the value... - if (UDEV_STABLE) -set(UDEV_STABLE 0) - else (UDEV_STABLE) -set(UDEV_STABLE 1) - endif (UDEV_STABLE) - message(STATUS "libudev stable: ${UDEV_STABLE}") -ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR) - -IF (UDEV_FOUND) - MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}") - MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}") -ELSE (UDEV_FOUND) - MESSAGE(STATUS "UDev not found.") - MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include") - MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}") - MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib") - MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}") - IF (UDev_FIND_REQUIRED) - MESSAGE(FATAL_ERROR "Could not find UDev library") - ENDIF (UDev_FIND_REQUIRED) -ENDIF (UDEV_FOUND) \ No newline at end of file diff --git a/cmake/Modules/cotire.cmake b/cmake/Modules/cotire.cmake deleted file mode 100644 index 741d6901f1..0000000000 --- a/cmake/Modules/cotire.cmake +++ /dev/null @@ -1,3917 +0,0 @@ -# - cotire (compile time reducer) -# -# See the cotire manual for usage hints. -# -#============================================================================= -# Copyright 2012-2016 Sascha Kratky -# -# Permission is hereby granted, free of charge, to any person -# obtaining a copy of this software and associated documentation -# files (the "Software"), to deal in the Software without -# restriction, including without limitation the rights to use, -# copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the -# Software is furnished to do so, subject to the following -# conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -# OTHER DEALINGS IN THE SOFTWARE. -#============================================================================= - -if(__COTIRE_INCLUDED) - return() -endif() -set(__COTIRE_INCLUDED TRUE) - -# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode -# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid -if (NOT CMAKE_SCRIPT_MODE_FILE) - cmake_policy(PUSH) -endif() -cmake_minimum_required(VERSION 2.8.12) -if (NOT CMAKE_SCRIPT_MODE_FILE) - cmake_policy(POP) -endif() - -set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") -set (COTIRE_CMAKE_MODULE_VERSION "1.7.8") - -# activate select policies -if (POLICY CMP0025) - # Compiler id for Apple Clang is now AppleClang - cmake_policy(SET CMP0025 NEW) -endif() - -if (POLICY CMP0026) - # disallow use of the LOCATION target property - cmake_policy(SET CMP0026 NEW) -endif() - -if (POLICY CMP0038) - # targets may not link directly to themselves - cmake_policy(SET CMP0038 NEW) -endif() - -if (POLICY CMP0039) - # utility targets may not have link dependencies - cmake_policy(SET CMP0039 NEW) -endif() - -if (POLICY CMP0040) - # target in the TARGET signature of add_custom_command() must exist - cmake_policy(SET CMP0040 NEW) -endif() - -if (POLICY CMP0045) - # error on non-existent target in get_target_property - cmake_policy(SET CMP0045 NEW) -endif() - -if (POLICY CMP0046) - # error on non-existent dependency in add_dependencies - cmake_policy(SET CMP0046 NEW) -endif() - -if (POLICY CMP0049) - # do not expand variables in target source entries - cmake_policy(SET CMP0049 NEW) -endif() - -if (POLICY CMP0050) - # disallow add_custom_command SOURCE signatures - cmake_policy(SET CMP0050 NEW) -endif() - -if (POLICY CMP0051) - # include TARGET_OBJECTS expressions in a target's SOURCES property - cmake_policy(SET CMP0051 NEW) -endif() - -if (POLICY CMP0053) - # simplify variable reference and escape sequence evaluation - cmake_policy(SET CMP0053 NEW) -endif() - -if (POLICY CMP0054) - # only interpret if() arguments as variables or keywords when unquoted - cmake_policy(SET CMP0054 NEW) -endif() - -include(CMakeParseArguments) -include(ProcessorCount) - -function (cotire_get_configuration_types _configsVar) - set (_configs "") - if (CMAKE_CONFIGURATION_TYPES) - list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) - endif() - if (CMAKE_BUILD_TYPE) - list (APPEND _configs "${CMAKE_BUILD_TYPE}") - endif() - if (_configs) - list (REMOVE_DUPLICATES _configs) - set (${_configsVar} ${_configs} PARENT_SCOPE) - else() - set (${_configsVar} "None" PARENT_SCOPE) - endif() -endfunction() - -function (cotire_get_source_file_extension _sourceFile _extVar) - # get_filename_component returns extension from first occurrence of . in file name - # this function computes the extension from last occurrence of . in file name - string (FIND "${_sourceFile}" "." _index REVERSE) - if (_index GREATER -1) - math (EXPR _index "${_index} + 1") - string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) - else() - set (_sourceExt "") - endif() - set (${_extVar} "${_sourceExt}" PARENT_SCOPE) -endfunction() - -macro (cotire_check_is_path_relative_to _path _isRelativeVar) - set (${_isRelativeVar} FALSE) - if (IS_ABSOLUTE "${_path}") - foreach (_dir ${ARGN}) - file (RELATIVE_PATH _relPath "${_dir}" "${_path}") - if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) - set (${_isRelativeVar} TRUE) - break() - endif() - endforeach() - endif() -endmacro() - -function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) - if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) - set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") - else() - set (_languageExtensions "") - endif() - if (CMAKE_${_language}_IGNORE_EXTENSIONS) - set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") - else() - set (_ignoreExtensions "") - endif() - if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) - set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") - else() - set (_excludeExtensions "") - endif() - if (COTIRE_DEBUG AND _languageExtensions) - message (STATUS "${_language} source file extensions: ${_languageExtensions}") - endif() - if (COTIRE_DEBUG AND _ignoreExtensions) - message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") - endif() - if (COTIRE_DEBUG AND _excludeExtensions) - message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") - endif() - if (CMAKE_VERSION VERSION_LESS "3.1.0") - set (_allSourceFiles ${ARGN}) - else() - # as of CMake 3.1 target sources may contain generator expressions - # since we cannot obtain required property information about source files added - # through generator expressions at configure time, we filter them out - string (GENEX_STRIP "${ARGN}" _allSourceFiles) - endif() - set (_filteredSourceFiles "") - set (_excludedSourceFiles "") - foreach (_sourceFile ${_allSourceFiles}) - get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) - get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) - get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) - if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) - cotire_get_source_file_extension("${_sourceFile}" _sourceExt) - if (_sourceExt) - list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) - if (_ignoreIndex LESS 0) - list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) - if (_excludeIndex GREATER -1) - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) - if (_sourceIndex GREATER -1) - # consider source file unless it is excluded explicitly - get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) - if (_sourceIsExcluded) - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - list (APPEND _filteredSourceFiles "${_sourceFile}") - endif() - else() - get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) - if ("${_sourceLanguage}" STREQUAL "${_language}") - # add to excluded sources, if file is not ignored and has correct language without having the correct extension - list (APPEND _excludedSourceFiles "${_sourceFile}") - endif() - endif() - endif() - endif() - endif() - endif() - endforeach() - # separate filtered source files from already cotired ones - # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire - set (_sourceFiles "") - set (_cotiredSourceFiles "") - foreach (_sourceFile ${_filteredSourceFiles}) - get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) - if (_sourceIsCotired) - list (APPEND _cotiredSourceFiles "${_sourceFile}") - else() - get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) - if (_sourceCompileFlags) - # add to excluded sources, if file has custom compile flags - list (APPEND _excludedSourceFiles "${_sourceFile}") - else() - list (APPEND _sourceFiles "${_sourceFile}") - endif() - endif() - endforeach() - if (COTIRE_DEBUG) - if (_sourceFiles) - message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}") - endif() - if (_excludedSourceFiles) - message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}") - endif() - if (_cotiredSourceFiles) - message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}") - endif() - endif() - set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) - set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) - set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) -endfunction() - -function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) - set (_filteredObjects "") - foreach (_object ${ARGN}) - get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) - if (_isSet) - get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) - if (_propertyValue) - list (APPEND _filteredObjects "${_object}") - endif() - endif() - endforeach() - set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) -endfunction() - -function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) - set (_filteredObjects "") - foreach (_object ${ARGN}) - get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) - if (_isSet) - get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) - if (NOT _propertyValue) - list (APPEND _filteredObjects "${_object}") - endif() - endif() - endforeach() - set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_file_property_values _valuesVar _property) - set (_values "") - foreach (_sourceFile ${ARGN}) - get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) - if (_propertyValue) - list (APPEND _values "${_propertyValue}") - endif() - endforeach() - set (${_valuesVar} ${_values} PARENT_SCOPE) -endfunction() - -function (cotire_resolve_config_properites _configurations _propertiesVar) - set (_properties "") - foreach (_property ${ARGN}) - if ("${_property}" MATCHES "") - foreach (_config ${_configurations}) - string (TOUPPER "${_config}" _upperConfig) - string (REPLACE "" "${_upperConfig}" _configProperty "${_property}") - list (APPEND _properties ${_configProperty}) - endforeach() - else() - list (APPEND _properties ${_property}) - endif() - endforeach() - set (${_propertiesVar} ${_properties} PARENT_SCOPE) -endfunction() - -function (cotire_copy_set_properites _configurations _type _source _target) - cotire_resolve_config_properites("${_configurations}" _properties ${ARGN}) - foreach (_property ${_properties}) - get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) - if (_isSet) - get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) - set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") - endif() - endforeach() -endfunction() - -function (cotire_get_target_usage_requirements _target _targetRequirementsVar) - set (_targetRequirements "") - get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) - while (_librariesToProcess) - # remove from head - list (GET _librariesToProcess 0 _library) - list (REMOVE_AT _librariesToProcess 0) - if (TARGET ${_library}) - list (FIND _targetRequirements ${_library} _index) - if (_index LESS 0) - list (APPEND _targetRequirements ${_library}) - # BFS traversal of transitive libraries - get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) - if (_libraries) - list (APPEND _librariesToProcess ${_libraries}) - list (REMOVE_DUPLICATES _librariesToProcess) - endif() - endif() - endif() - endwhile() - set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE) -endfunction() - -function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - set (_flagPrefix "[/-]") - else() - set (_flagPrefix "--?") - endif() - set (_optionFlag "") - set (_matchedOptions "") - set (_unmatchedOptions "") - foreach (_compileFlag ${ARGN}) - if (_compileFlag) - if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") - # option with separate argument - list (APPEND _matchedOptions "${_compileFlag}") - set (_optionFlag "") - elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") - # remember option - set (_optionFlag "${CMAKE_MATCH_2}") - elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") - # option with joined argument - list (APPEND _matchedOptions "${CMAKE_MATCH_3}") - set (_optionFlag "") - else() - # flush remembered option - if (_optionFlag) - list (APPEND _matchedOptions "${_optionFlag}") - set (_optionFlag "") - endif() - # add to unfiltered options - list (APPEND _unmatchedOptions "${_compileFlag}") - endif() - endif() - endforeach() - if (_optionFlag) - list (APPEND _matchedOptions "${_optionFlag}") - endif() - if (COTIRE_DEBUG AND _matchedOptions) - message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}") - endif() - if (COTIRE_DEBUG AND _unmatchedOptions) - message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}") - endif() - set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) - set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) -endfunction() - -function (cotire_is_target_supported _target _isSupportedVar) - if (NOT TARGET "${_target}") - set (${_isSupportedVar} FALSE PARENT_SCOPE) - return() - endif() - get_target_property(_imported ${_target} IMPORTED) - if (_imported) - set (${_isSupportedVar} FALSE PARENT_SCOPE) - return() - endif() - get_target_property(_targetType ${_target} TYPE) - if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - set (${_isSupportedVar} FALSE PARENT_SCOPE) - return() - endif() - set (${_isSupportedVar} TRUE PARENT_SCOPE) -endfunction() - -function (cotire_get_target_compile_flags _config _language _target _flagsVar) - string (TOUPPER "${_config}" _upperConfig) - # collect options from CMake language variables - set (_compileFlags "") - if (CMAKE_${_language}_FLAGS) - set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") - endif() - if (CMAKE_${_language}_FLAGS_${_upperConfig}) - set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") - endif() - if (_target) - # add target compile flags - get_target_property(_targetflags ${_target} COMPILE_FLAGS) - if (_targetflags) - set (_compileFlags "${_compileFlags} ${_targetflags}") - endif() - endif() - if (UNIX) - separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") - elseif(WIN32) - separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") - else() - separate_arguments(_compileFlags) - endif() - # target compile options - if (_target) - get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) - if (_targetOptions) - list (APPEND _compileFlags ${_targetOptions}) - endif() - endif() - # interface compile options from linked library targets - if (_target) - set (_linkedTargets "") - cotire_get_target_usage_requirements(${_target} _linkedTargets) - foreach (_linkedTarget ${_linkedTargets}) - get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS) - if (_targetOptions) - list (APPEND _compileFlags ${_targetOptions}) - endif() - endforeach() - endif() - # handle language standard properties - if (_target) - get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD) - get_target_property(_targetLanguageExtensions ${_target} ${_language}_EXTENSIONS) - get_target_property(_targetLanguageStandardRequired ${_target} ${_language}_STANDARD_REQUIRED) - if (_targetLanguageExtensions) - if (CMAKE_${_language}${_targetLanguageExtensions}_EXTENSION_COMPILE_OPTION) - list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageExtensions}_EXTENSION_COMPILE_OPTION}") - endif() - elseif (_targetLanguageStandard) - if (_targetLanguageStandardRequired) - if (CMAKE_${_language}${_targetLanguageStandard}_STANDARD_COMPILE_OPTION) - list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_STANDARD_COMPILE_OPTION}") - endif() - else() - if (CMAKE_${_language}${_targetLanguageStandard}_EXTENSION_COMPILE_OPTION) - list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_EXTENSION_COMPILE_OPTION}") - endif() - endif() - endif() - endif() - # handle the POSITION_INDEPENDENT_CODE target property - if (_target) - get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) - if (_targetPIC) - get_target_property(_targetType ${_target} TYPE) - if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") - elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") - endif() - endif() - endif() - # handle visibility target properties - if (_target) - get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET) - if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}") - endif() - get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN) - if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) - list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}") - endif() - endif() - # platform specific flags - if (APPLE) - get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) - if (NOT _architectures) - get_target_property(_architectures ${_target} OSX_ARCHITECTURES) - endif() - if (_architectures) - foreach (_arch ${_architectures}) - list (APPEND _compileFlags "-arch" "${_arch}") - endforeach() - endif() - if (CMAKE_OSX_SYSROOT) - if (CMAKE_${_language}_SYSROOT_FLAG) - list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") - else() - list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") - endif() - endif() - if (CMAKE_OSX_DEPLOYMENT_TARGET) - if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) - list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") - else() - list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - endif() - endif() - endif() - if (COTIRE_DEBUG AND _compileFlags) - message (STATUS "Target ${_target} compile flags: ${_compileFlags}") - endif() - set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar) - set (_includeDirs "") - set (_systemIncludeDirs "") - # default include dirs - if (CMAKE_INCLUDE_CURRENT_DIR) - list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}") - list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}") - endif() - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - # parse additional include directories from target compile flags - if (CMAKE_INCLUDE_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_dirs "") - cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) - if (_dirs) - list (APPEND _includeDirs ${_dirs}) - endif() - endif() - endif() - # parse additional system include directories from target compile flags - if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_dirs "") - cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) - if (_dirs) - list (APPEND _systemIncludeDirs ${_dirs}) - endif() - endif() - endif() - # target include directories - get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES) - if (_target) - get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _systemIncludeDirs ${_targetDirs}) - endif() - endif() - # interface include directories from linked library targets - if (_target) - set (_linkedTargets "") - cotire_get_target_usage_requirements(${_target} _linkedTargets) - foreach (_linkedTarget ${_linkedTargets}) - get_target_property(_linkedTargetType ${_linkedTarget} TYPE) - if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND - _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR - # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR - # which are only available with CMake 3.4 or later. - get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - endif() - get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _dirs ${_targetDirs}) - endif() - get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) - if (_targetDirs) - list (APPEND _systemIncludeDirs ${_targetDirs}) - endif() - endforeach() - endif() - if (dirs) - list (REMOVE_DUPLICATES _dirs) - endif() - list (LENGTH _includeDirs _projectInsertIndex) - foreach (_dir ${_dirs}) - if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) - cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") - if (_isRelative) - list (LENGTH _includeDirs _len) - if (_len EQUAL _projectInsertIndex) - list (APPEND _includeDirs "${_dir}") - else() - list (INSERT _includeDirs _projectInsertIndex "${_dir}") - endif() - math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") - else() - list (APPEND _includeDirs "${_dir}") - endif() - else() - list (APPEND _includeDirs "${_dir}") - endif() - endforeach() - list (REMOVE_DUPLICATES _includeDirs) - list (REMOVE_DUPLICATES _systemIncludeDirs) - if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) - list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) - endif() - if (COTIRE_DEBUG AND _includeDirs) - message (STATUS "Target ${_target} include dirs: ${_includeDirs}") - endif() - set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) - if (COTIRE_DEBUG AND _systemIncludeDirs) - message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}") - endif() - set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_export_symbol _target _exportSymbolVar) - set (_exportSymbol "") - get_target_property(_targetType ${_target} TYPE) - get_target_property(_enableExports ${_target} ENABLE_EXPORTS) - if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR - (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) - get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) - if (NOT _exportSymbol) - set (_exportSymbol "${_target}_EXPORTS") - endif() - string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol) - endif() - set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_compile_definitions _config _language _target _definitionsVar) - string (TOUPPER "${_config}" _upperConfig) - set (_configDefinitions "") - # CMAKE_INTDIR for multi-configuration build systems - if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") - list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") - endif() - # target export define symbol - cotire_get_target_export_symbol("${_target}" _defineSymbol) - if (_defineSymbol) - list (APPEND _configDefinitions "${_defineSymbol}") - endif() - # directory compile definitions - get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig}) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - # target compile definitions - get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - # interface compile definitions from linked library targets - set (_linkedTargets "") - cotire_get_target_usage_requirements(${_target} _linkedTargets) - foreach (_linkedTarget ${_linkedTargets}) - get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - endforeach() - # parse additional compile definitions from target compile flags - # and don't look at directory compile definitions, which we already handled - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) - if (_definitions) - list (APPEND _configDefinitions ${_definitions}) - endif() - list (REMOVE_DUPLICATES _configDefinitions) - if (COTIRE_DEBUG AND _configDefinitions) - message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}") - endif() - set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) -endfunction() - -function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar) - # parse target compile flags omitting compile definitions and include directives - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - set (_flagFilter "D") - if (CMAKE_INCLUDE_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_flagFilter "${_flagFilter}|${_includeFlag}") - endif() - endif() - if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) - string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) - string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") - if (_includeFlag) - set (_flagFilter "${_flagFilter}|${_includeFlag}") - endif() - endif() - set (_compilerFlags "") - cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags}) - if (COTIRE_DEBUG AND _compilerFlags) - message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}") - endif() - set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) -endfunction() - -function (cotire_add_sys_root_paths _pathsVar) - if (APPLE) - if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) - foreach (_path IN LISTS ${_pathsVar}) - if (IS_ABSOLUTE "${_path}") - get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) - if (EXISTS "${_path}") - list (APPEND ${_pathsVar} "${_path}") - endif() - endif() - endforeach() - endif() - endif() - set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) - set (_extraProperties ${ARGN}) - set (_result "") - if (_extraProperties) - list (FIND _extraProperties "${_sourceFile}" _index) - if (_index GREATER -1) - math (EXPR _index "${_index} + 1") - list (LENGTH _extraProperties _len) - math (EXPR _len "${_len} - 1") - foreach (_index RANGE ${_index} ${_len}) - list (GET _extraProperties ${_index} _value) - if (_value MATCHES "${_pattern}") - list (APPEND _result "${_value}") - else() - break() - endif() - endforeach() - endif() - endif() - set (${_resultVar} ${_result} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) - set (_compileDefinitions "") - if (NOT CMAKE_SCRIPT_MODE_FILE) - string (TOUPPER "${_config}" _upperConfig) - get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) - if (_definitions) - list (APPEND _compileDefinitions ${_definitions}) - endif() - get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) - if (_definitions) - list (APPEND _compileDefinitions ${_definitions}) - endif() - endif() - cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) - if (_definitions) - list (APPEND _compileDefinitions ${_definitions}) - endif() - if (COTIRE_DEBUG AND _compileDefinitions) - message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}") - endif() - set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) - set (_configDefinitions "") - foreach (_sourceFile ${ARGN}) - cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) - if (_sourceDefinitions) - list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") - endif() - endforeach() - set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) - set (_sourceUndefs "") - if (NOT CMAKE_SCRIPT_MODE_FILE) - get_source_file_property(_undefs "${_sourceFile}" ${_property}) - if (_undefs) - list (APPEND _sourceUndefs ${_undefs}) - endif() - endif() - cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) - if (_undefs) - list (APPEND _sourceUndefs ${_undefs}) - endif() - if (COTIRE_DEBUG AND _sourceUndefs) - message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}") - endif() - set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) -endfunction() - -function (cotire_get_source_files_undefs _property _sourceUndefsVar) - set (_sourceUndefs "") - foreach (_sourceFile ${ARGN}) - cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) - if (_undefs) - list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") - endif() - endforeach() - set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) -endfunction() - -macro (cotire_set_cmd_to_prologue _cmdVar) - set (${_cmdVar} "${CMAKE_COMMAND}") - if (COTIRE_DEBUG) - list (APPEND ${_cmdVar} "--warn-uninitialized") - endif() - list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") - if (COTIRE_VERBOSE) - list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") - elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") - list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") - endif() -endmacro() - -function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1) - if (NOT _compilerLauncher) - set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER}) - endif() - if (NOT _compilerExe) - set (_compilerExe "${CMAKE_${_language}_COMPILER}") - endif() - if (NOT _compilerArg1) - set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) - endif() - string (STRIP "${_compilerArg1}" _compilerArg1) - if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # compiler launcher is only supported for Makefile and Ninja - set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) - else() - set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) - endif() -endfunction() - -macro (cotire_add_definitions_to_cmd _cmdVar _language) - foreach (_definition ${ARGN}) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - list (APPEND ${_cmdVar} "/D${_definition}") - else() - list (APPEND ${_cmdVar} "-D${_definition}") - endif() - endforeach() -endmacro() - -function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar) - set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}}) - if (_includeDirs) - list (REMOVE_DUPLICATES _includeDirs) - foreach (_include ${_includeDirs}) - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - file (TO_NATIVE_PATH "${_include}" _include) - list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_${_language}_SEP}${_include}") - else() - set (_index -1) - if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+") - list (FIND ${_systemIncludesVar} "${_include}" _index) - endif() - if (_index GREATER -1) - list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${_include}") - else() - list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_${_language}_SEP}${_include}") - endif() - endif() - endforeach() - endif() - set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) -endfunction() - -function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar) - if (APPLE) - set (_frameworkDirs "") - foreach (_include ${${_includesVar}}) - if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") - get_filename_component(_frameworkDir "${_include}" DIRECTORY) - list (APPEND _frameworkDirs "${_frameworkDir}") - endif() - endforeach() - set (_systemFrameworkDirs "") - foreach (_include ${${_systemIncludesVar}}) - if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") - get_filename_component(_frameworkDir "${_include}" DIRECTORY) - list (APPEND _systemFrameworkDirs "${_frameworkDir}") - endif() - endforeach() - if (_systemFrameworkDirs) - list (APPEND _frameworkDirs ${_systemFrameworkDirs}) - endif() - if (_frameworkDirs) - list (REMOVE_DUPLICATES _frameworkDirs) - foreach (_frameworkDir ${_frameworkDirs}) - set (_index -1) - if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+") - list (FIND _systemFrameworkDirs "${_frameworkDir}" _index) - endif() - if (_index GREATER -1) - list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") - else() - list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") - endif() - endforeach() - endif() - endif() - set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) -endfunction() - -macro (cotire_add_compile_flags_to_cmd _cmdVar) - foreach (_flag ${ARGN}) - list (APPEND ${_cmdVar} "${_flag}") - endforeach() -endmacro() - -function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) - if (EXISTS "${_file}") - set (_triggerFile "") - foreach (_dependencyFile ${ARGN}) - if (EXISTS "${_dependencyFile}") - # IS_NEWER_THAN returns TRUE if both files have the same timestamp - # thus we do the comparison in both directions to exclude ties - if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND - NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}") - set (_triggerFile "${_dependencyFile}") - break() - endif() - endif() - endforeach() - if (_triggerFile) - if (COTIRE_VERBOSE) - get_filename_component(_fileName "${_file}" NAME) - message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") - endif() - set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) - else() - if (COTIRE_VERBOSE) - get_filename_component(_fileName "${_file}" NAME) - message (STATUS "${_fileName} is up-to-date.") - endif() - set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) - endif() - else() - if (COTIRE_VERBOSE) - get_filename_component(_fileName "${_file}" NAME) - message (STATUS "${_fileName} does not exist yet.") - endif() - set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) - endif() -endfunction() - -macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) - set (${_relPathVar} "") - foreach (_includeDir ${_includeDirs}) - if (IS_DIRECTORY "${_includeDir}") - file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") - if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") - string (LENGTH "${${_relPathVar}}" _closestLen) - string (LENGTH "${_relPath}" _relLen) - if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) - set (${_relPathVar} "${_relPath}") - endif() - endif() - elseif ("${_includeDir}" STREQUAL "${_headerFile}") - # if path matches exactly, return short non-empty string - set (${_relPathVar} "1") - break() - endif() - endforeach() -endmacro() - -macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside) - # check header path against ignored and honored include directories - cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath) - if (_insideRelPath) - # header is inside, but could be become outside if there is a shorter outside match - cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath) - if (_outsideRelPath) - string (LENGTH "${_insideRelPath}" _insideRelPathLen) - string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) - if (_outsideRelPathLen LESS _insideRelPathLen) - set (${_headerIsInside} FALSE) - else() - set (${_headerIsInside} TRUE) - endif() - else() - set (${_headerIsInside} TRUE) - endif() - else() - # header is outside - set (${_headerIsInside} FALSE) - endif() -endmacro() - -macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) - if (NOT EXISTS "${_headerFile}") - set (${_headerIsIgnoredVar} TRUE) - elseif (IS_DIRECTORY "${_headerFile}") - set (${_headerIsIgnoredVar} TRUE) - elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") - # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path - # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation - # with the error message "error: no include path in which to search for header.h" - set (${_headerIsIgnoredVar} TRUE) - else() - set (${_headerIsIgnoredVar} FALSE) - endif() -endmacro() - -macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) - # check header file extension - cotire_get_source_file_extension("${_headerFile}" _headerFileExt) - set (${_headerIsIgnoredVar} FALSE) - if (_headerFileExt) - list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) - if (_index GREATER -1) - set (${_headerIsIgnoredVar} TRUE) - endif() - endif() -endmacro() - -macro (cotire_parse_line _line _headerFileVar _headerDepthVar) - if (MSVC) - # cl.exe /showIncludes output looks different depending on the language pack used, e.g.: - # English: "Note: including file: C:\directory\file" - # German: "Hinweis: Einlesen der Datei: C:\directory\file" - # We use a very general regular expression, relying on the presence of the : characters - if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") - # Visual Studio compiler output - string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) - get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) - else() - set (${_headerFileVar} "") - set (${_headerDepthVar} 0) - endif() - else() - if (_line MATCHES "^(\\.+) (.*)$") - # GCC like output - string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) - if (IS_ABSOLUTE "${CMAKE_MATCH_2}") - set (${_headerFileVar} "${CMAKE_MATCH_2}") - else() - get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) - endif() - else() - set (${_headerFileVar} "") - set (${_headerDepthVar} 0) - endif() - endif() -endmacro() - -function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) - if (WIN32) - # prevent CMake macro invocation errors due to backslash characters in Windows paths - string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") - endif() - # canonize slashes - string (REPLACE "//" "/" _scanOutput "${_scanOutput}") - # prevent semicolon from being interpreted as a line separator - string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") - # then separate lines - string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") - list (LENGTH _scanOutput _len) - # remove duplicate lines to speed up parsing - list (REMOVE_DUPLICATES _scanOutput) - list (LENGTH _scanOutput _uniqueLen) - if (COTIRE_VERBOSE OR COTIRE_DEBUG) - message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") - if (_ignoredExtensions) - message (STATUS "Ignored extensions: ${_ignoredExtensions}") - endif() - if (_ignoredIncludeDirs) - message (STATUS "Ignored paths: ${_ignoredIncludeDirs}") - endif() - if (_honoredIncludeDirs) - message (STATUS "Included paths: ${_honoredIncludeDirs}") - endif() - endif() - set (_sourceFiles ${ARGN}) - set (_selectedIncludes "") - set (_unparsedLines "") - # stack keeps track of inside/outside project status of processed header files - set (_headerIsInsideStack "") - foreach (_line IN LISTS _scanOutput) - if (_line) - cotire_parse_line("${_line}" _headerFile _headerDepth) - if (_headerFile) - cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside) - if (COTIRE_DEBUG) - message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") - endif() - # update stack - list (LENGTH _headerIsInsideStack _stackLen) - if (_headerDepth GREATER _stackLen) - math (EXPR _stackLen "${_stackLen} + 1") - foreach (_index RANGE ${_stackLen} ${_headerDepth}) - list (APPEND _headerIsInsideStack ${_headerIsInside}) - endforeach() - else() - foreach (_index RANGE ${_headerDepth} ${_stackLen}) - list (REMOVE_AT _headerIsInsideStack -1) - endforeach() - list (APPEND _headerIsInsideStack ${_headerIsInside}) - endif() - if (COTIRE_DEBUG) - message (STATUS "${_headerIsInsideStack}") - endif() - # header is a candidate if it is outside project - if (NOT _headerIsInside) - # get parent header file's inside/outside status - if (_headerDepth GREATER 1) - math (EXPR _index "${_headerDepth} - 2") - list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) - else() - set (_parentHeaderIsInside TRUE) - endif() - # select header file if parent header file is inside project - # (e.g., a project header file that includes a standard header file) - if (_parentHeaderIsInside) - cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) - if (NOT _headerIsIgnored) - cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) - if (NOT _headerIsIgnored) - list (APPEND _selectedIncludes "${_headerFile}") - else() - # fix header's inside status on stack, it is ignored by extension now - list (REMOVE_AT _headerIsInsideStack -1) - list (APPEND _headerIsInsideStack TRUE) - endif() - endif() - if (COTIRE_DEBUG) - message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") - endif() - endif() - endif() - else() - if (MSVC) - # for cl.exe do not keep unparsed lines which solely consist of a source file name - string (FIND "${_sourceFiles}" "${_line}" _index) - if (_index LESS 0) - list (APPEND _unparsedLines "${_line}") - endif() - else() - list (APPEND _unparsedLines "${_line}") - endif() - endif() - endif() - endforeach() - list (REMOVE_DUPLICATES _selectedIncludes) - set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) - set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) -endfunction() - -function (cotire_scan_includes _includesVar) - set(_options "") - set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES - IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) - if (NOT _option_LANGUAGE) - set (_option_LANGUAGE "CXX") - endif() - if (NOT _option_COMPILER_ID) - set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") - endif() - if (NOT _option_COMPILER_VERSION) - set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") - endif() - cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") - cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) - cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) - # only consider existing source files for scanning - set (_existingSourceFiles "") - foreach (_sourceFile ${_sourceFiles}) - if (EXISTS "${_sourceFile}") - list (APPEND _existingSourceFiles "${_sourceFile}") - endif() - endforeach() - if (NOT _existingSourceFiles) - set (${_includesVar} "" PARENT_SCOPE) - return() - endif() - list (APPEND _cmd ${_existingSourceFiles}) - if (COTIRE_VERBOSE) - message (STATUS "execute_process: ${_cmd}") - endif() - if (_option_COMPILER_ID MATCHES "MSVC") - # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared - unset (ENV{VS_UNICODE_OUTPUT}) - endif() - execute_process( - COMMAND ${_cmd} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE _result - OUTPUT_QUIET - ERROR_VARIABLE _output) - if (_result) - message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") - endif() - cotire_parse_includes( - "${_option_LANGUAGE}" "${_output}" - "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" - "${_option_IGNORE_EXTENSIONS}" - _includes _unparsedLines - ${_sourceFiles}) - if (_option_INCLUDE_PRIORITY_PATH) - set (_sortedIncludes "") - foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH}) - foreach (_include ${_includes}) - string (FIND ${_include} ${_priorityPath} _position) - if (_position GREATER -1) - list (APPEND _sortedIncludes ${_include}) - endif() - endforeach() - endforeach() - if (_sortedIncludes) - list (INSERT _includes 0 ${_sortedIncludes}) - list (REMOVE_DUPLICATES _includes) - endif() - endif() - set (${_includesVar} ${_includes} PARENT_SCOPE) - if (_option_UNPARSED_LINES) - set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) - endif() -endfunction() - -macro (cotire_append_undefs _contentsVar) - set (_undefs ${ARGN}) - if (_undefs) - list (REMOVE_DUPLICATES _undefs) - foreach (_definition ${_undefs}) - list (APPEND ${_contentsVar} "#undef ${_definition}") - endforeach() - endif() -endmacro() - -macro (cotire_comment_str _language _commentText _commentVar) - if ("${_language}" STREQUAL "CMAKE") - set (${_commentVar} "# ${_commentText}") - else() - set (${_commentVar} "/* ${_commentText} */") - endif() -endmacro() - -function (cotire_write_file _language _file _contents _force) - get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) - cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) - cotire_comment_str("${_language}" "${_file}" _header2) - set (_contents "${_header1}\n${_header2}\n${_contents}") - if (COTIRE_DEBUG) - message (STATUS "${_contents}") - endif() - if (_force OR NOT EXISTS "${_file}") - file (WRITE "${_file}" "${_contents}") - else() - file (READ "${_file}" _oldContents) - if (NOT "${_oldContents}" STREQUAL "${_contents}") - file (WRITE "${_file}" "${_contents}") - else() - if (COTIRE_DEBUG) - message (STATUS "${_file} unchanged") - endif() - endif() - endif() -endfunction() - -function (cotire_generate_unity_source _unityFile) - set(_options "") - set(_oneValueArgs LANGUAGE) - set(_multiValueArgs - DEPENDS SOURCES_COMPILE_DEFINITIONS - PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (_option_DEPENDS) - cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) - if (_unityFileIsUpToDate) - return() - endif() - endif() - set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) - if (NOT _option_PRE_UNDEFS) - set (_option_PRE_UNDEFS "") - endif() - if (NOT _option_SOURCES_PRE_UNDEFS) - set (_option_SOURCES_PRE_UNDEFS "") - endif() - if (NOT _option_POST_UNDEFS) - set (_option_POST_UNDEFS "") - endif() - if (NOT _option_SOURCES_POST_UNDEFS) - set (_option_SOURCES_POST_UNDEFS "") - endif() - set (_contents "") - if (_option_PROLOGUE) - list (APPEND _contents ${_option_PROLOGUE}) - endif() - if (_option_LANGUAGE AND _sourceFiles) - if ("${_option_LANGUAGE}" STREQUAL "CXX") - list (APPEND _contents "#ifdef __cplusplus") - elseif ("${_option_LANGUAGE}" STREQUAL "C") - list (APPEND _contents "#ifndef __cplusplus") - endif() - endif() - set (_compileUndefinitions "") - foreach (_sourceFile ${_sourceFiles}) - cotire_get_source_compile_definitions( - "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions - ${_option_SOURCES_COMPILE_DEFINITIONS}) - cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) - cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) - if (_option_PRE_UNDEFS) - list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) - endif() - if (_sourcePreUndefs) - list (APPEND _compileUndefinitions ${_sourcePreUndefs}) - endif() - if (_compileUndefinitions) - cotire_append_undefs(_contents ${_compileUndefinitions}) - set (_compileUndefinitions "") - endif() - if (_sourcePostUndefs) - list (APPEND _compileUndefinitions ${_sourcePostUndefs}) - endif() - if (_option_POST_UNDEFS) - list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) - endif() - foreach (_definition ${_compileDefinitions}) - if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") - list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") - list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") - else() - list (APPEND _contents "#define ${_definition}") - list (INSERT _compileUndefinitions 0 "${_definition}") - endif() - endforeach() - # use absolute path as source file location - get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) - if (WIN32) - file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) - endif() - list (APPEND _contents "#include \"${_sourceFileLocation}\"") - endforeach() - if (_compileUndefinitions) - cotire_append_undefs(_contents ${_compileUndefinitions}) - set (_compileUndefinitions "") - endif() - if (_option_LANGUAGE AND _sourceFiles) - list (APPEND _contents "#endif") - endif() - if (_option_EPILOGUE) - list (APPEND _contents ${_option_EPILOGUE}) - endif() - list (APPEND _contents "") - string (REPLACE ";" "\n" _contents "${_contents}") - if (COTIRE_VERBOSE) - message ("${_contents}") - endif() - cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) -endfunction() - -function (cotire_generate_prefix_header _prefixFile) - set(_options "") - set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION) - set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS - INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH - IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_COMPILER_ID) - set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") - endif() - if (NOT _option_COMPILER_VERSION) - set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") - endif() - if (_option_DEPENDS) - cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) - if (_prefixFileIsUpToDate) - # create empty log file - set (_unparsedLinesFile "${_prefixFile}.log") - file (WRITE "${_unparsedLinesFile}" "") - return() - endif() - endif() - set (_prologue "") - set (_epilogue "") - if (_option_COMPILER_ID MATCHES "Clang") - set (_prologue "#pragma clang system_header") - elseif (_option_COMPILER_ID MATCHES "GNU") - set (_prologue "#pragma GCC system_header") - elseif (_option_COMPILER_ID MATCHES "MSVC") - set (_prologue "#pragma warning(push, 0)") - set (_epilogue "#pragma warning(pop)") - elseif (_option_COMPILER_ID MATCHES "Intel") - # Intel compiler requires hdrstop pragma to stop generating PCH file - set (_epilogue "#pragma hdrstop") - endif() - set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) - cotire_scan_includes(_selectedHeaders ${_sourceFiles} - LANGUAGE "${_option_LANGUAGE}" - COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}" - COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" - COMPILER_ARG1 "${_option_COMPILER_ARG1}" - COMPILER_ID "${_option_COMPILER_ID}" - COMPILER_VERSION "${_option_COMPILER_VERSION}" - COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} - COMPILE_FLAGS ${_option_COMPILE_FLAGS} - INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} - SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} - IGNORE_PATH ${_option_IGNORE_PATH} - INCLUDE_PATH ${_option_INCLUDE_PATH} - IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} - INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH} - UNPARSED_LINES _unparsedLines) - cotire_generate_unity_source("${_prefixFile}" - PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) - set (_unparsedLinesFile "${_prefixFile}.log") - if (_unparsedLines) - if (COTIRE_VERBOSE OR NOT _selectedHeaders) - list (LENGTH _unparsedLines _skippedLineCount) - message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFile}") - endif() - string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") - endif() - file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}") -endfunction() - -function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) - set (_flags ${${_flagsVar}}) - if (_compilerID MATCHES "MSVC") - # cl.exe options used - # /nologo suppresses display of sign-on banner - # /TC treat all files named on the command line as C source files - # /TP treat all files named on the command line as C++ source files - # /EP preprocess to stdout without #line directives - # /showIncludes list include files - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) - else() - # return as a flag string - set (_flags "${_sourceFileType${_language}} /EP /showIncludes") - endif() - elseif (_compilerID MATCHES "GNU") - # GCC options used - # -H print the name of each header file used - # -E invoke preprocessor - # -fdirectives-only do not expand macros, requires GCC >= 4.3 - if (_flags) - # append to list - list (APPEND _flags -H -E) - if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") - list (APPEND _flags "-fdirectives-only") - endif() - else() - # return as a flag string - set (_flags "-H -E") - if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") - set (_flags "${_flags} -fdirectives-only") - endif() - endif() - elseif (_compilerID MATCHES "Clang") - # Clang options used - # -H print the name of each header file used - # -E invoke preprocessor - # -fno-color-diagnostics don't prints diagnostics in color - if (_flags) - # append to list - list (APPEND _flags -H -E -fno-color-diagnostics) - else() - # return as a flag string - set (_flags "-H -E -fno-color-diagnostics") - endif() - elseif (_compilerID MATCHES "Intel") - if (WIN32) - # Windows Intel options used - # /nologo do not display compiler version information - # /QH display the include file order - # /EP preprocess to stdout, omitting #line directives - # /TC process all source or unrecognized file types as C source files - # /TP process all source or unrecognized file types as C++ source files - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) - else() - # return as a flag string - set (_flags "${_sourceFileType${_language}} /EP /QH") - endif() - else() - # Linux / Mac OS X Intel options used - # -H print the name of each header file used - # -EP preprocess to stdout, omitting #line directives - # -Kc++ process all source or unrecognized file types as C++ source files - if (_flags) - # append to list - if ("${_language}" STREQUAL "CXX") - list (APPEND _flags -Kc++) - endif() - list (APPEND _flags -H -EP) - else() - # return as a flag string - if ("${_language}" STREQUAL "CXX") - set (_flags "-Kc++ ") - endif() - set (_flags "${_flags}-H -EP") - endif() - endif() - else() - message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") - endif() - set (${_flagsVar} ${_flags} PARENT_SCOPE) -endfunction() - -function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) - set (_flags ${${_flagsVar}}) - if (_compilerID MATCHES "MSVC") - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) - # cl.exe options used - # /Yc creates a precompiled header file - # /Fp specifies precompiled header binary file name - # /FI forces inclusion of file - # /TC treat all files named on the command line as C source files - # /TP treat all files named on the command line as C++ source files - # /Zs syntax check only - # /Zm precompiled header memory allocation scaling factor - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" - "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - else() - # return as a flag string - set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - endif() - elseif (_compilerID MATCHES "GNU|Clang") - # GCC / Clang options used - # -x specify the source language - # -c compile but do not link - # -o place output in file - # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may - # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) - set (_xLanguage_C "c-header") - set (_xLanguage_CXX "c++-header") - if (_flags) - # append to list - list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") - else() - # return as a flag string - set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") - endif() - elseif (_compilerID MATCHES "Intel") - if (WIN32) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) - # Windows Intel options used - # /nologo do not display compiler version information - # /Yc create a precompiled header (PCH) file - # /Fp specify a path or file name for precompiled header files - # /FI tells the preprocessor to include a specified file name as the header file - # /TC process all source or unrecognized file types as C source files - # /TP process all source or unrecognized file types as C++ source files - # /Zs syntax check only - # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - set (_sourceFileTypeC "/TC") - set (_sourceFileTypeCXX "/TP") - if (_flags) - # append to list - list (APPEND _flags /nologo "${_sourceFileType${_language}}" - "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "/Wpch-messages") - endif() - else() - # return as a flag string - set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} /Wpch-messages") - endif() - endif() - else() - # Linux / Mac OS X Intel options used - # -pch-dir location for precompiled header files - # -pch-create name of the precompiled header (PCH) to create - # -Kc++ process all source or unrecognized file types as C++ source files - # -fsyntax-only check only for correct syntax - # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - get_filename_component(_pchDir "${_pchFile}" DIRECTORY) - get_filename_component(_pchName "${_pchFile}" NAME) - set (_xLanguage_C "c-header") - set (_xLanguage_CXX "c++-header") - if (_flags) - # append to list - if ("${_language}" STREQUAL "CXX") - list (APPEND _flags -Kc++) - endif() - list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "-Wpch-messages") - endif() - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} -Wpch-messages") - endif() - endif() - endif() - else() - message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") - endif() - set (${_flagsVar} ${_flags} PARENT_SCOPE) -endfunction() - -function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) - set (_flags ${${_flagsVar}}) - if (_compilerID MATCHES "MSVC") - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - # cl.exe options used - # /Yu uses a precompiled header file during build - # /Fp specifies precompiled header binary file name - # /FI forces inclusion of file - # /Zm precompiled header memory allocation scaling factor - if (_pchFile) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - if (_flags) - # append to list - list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - else() - # return as a flag string - set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (COTIRE_PCH_MEMORY_SCALING_FACTOR) - set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") - endif() - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags "/FI${_prefixFileNative}") - else() - # return as a flag string - set (_flags "/FI\"${_prefixFileNative}\"") - endif() - endif() - elseif (_compilerID MATCHES "GNU") - # GCC options used - # -include process include file as the first line of the primary source file - # -Winvalid-pch warns if precompiled header is found but cannot be used - # note: ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") - else() - # return as a flag string - set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") - endif() - elseif (_compilerID MATCHES "Clang") - # Clang options used - # -include process include file as the first line of the primary source file - # -include-pch include precompiled header file - # -Qunused-arguments don't emit warning for unused driver arguments - # note: ccache requires the -include flag to be used in order to process precompiled header correctly - if (_flags) - # append to list - list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") - else() - # return as a flag string - set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") - endif() - elseif (_compilerID MATCHES "Intel") - if (WIN32) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) - # Windows Intel options used - # /Yu use a precompiled header (PCH) file - # /Fp specify a path or file name for precompiled header files - # /FI tells the preprocessor to include a specified file name as the header file - # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - if (_pchFile) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) - if (_flags) - # append to list - list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "/Wpch-messages") - endif() - else() - # return as a flag string - set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} /Wpch-messages") - endif() - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags "/FI${_prefixFileNative}") - else() - # return as a flag string - set (_flags "/FI\"${_prefixFileNative}\"") - endif() - endif() - else() - # Linux / Mac OS X Intel options used - # -pch-dir location for precompiled header files - # -pch-use name of the precompiled header (PCH) to use - # -include process include file as the first line of the primary source file - # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) - if (_pchFile) - get_filename_component(_pchDir "${_pchFile}" DIRECTORY) - get_filename_component(_pchName "${_pchFile}" NAME) - if (_flags) - # append to list - list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - list (APPEND _flags "-Wpch-messages") - endif() - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") - if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") - set (_flags "${_flags} -Wpch-messages") - endif() - endif() - else() - # no precompiled header, force inclusion of prefix header - if (_flags) - # append to list - list (APPEND _flags "-include" "${_prefixFile}") - else() - # return as a flag string - set (_flags "-include \"${_prefixFile}\"") - endif() - endif() - endif() - else() - message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") - endif() - set (${_flagsVar} ${_flags} PARENT_SCOPE) -endfunction() - -function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) - set(_options "") - set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE) - set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_LANGUAGE) - set (_option_LANGUAGE "CXX") - endif() - if (NOT _option_COMPILER_ID) - set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") - endif() - if (NOT _option_COMPILER_VERSION) - set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") - endif() - cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") - cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) - cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) - cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) - cotire_add_pch_compilation_flags( - "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) - if (COTIRE_VERBOSE) - message (STATUS "execute_process: ${_cmd}") - endif() - if (_option_COMPILER_ID MATCHES "MSVC") - # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared - unset (ENV{VS_UNICODE_OUTPUT}) - endif() - execute_process( - COMMAND ${_cmd} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - RESULT_VARIABLE _result) - if (_result) - message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") - endif() -endfunction() - -function (cotire_check_precompiled_header_support _language _target _msgVar) - set (_unsupportedCompiler - "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") - # supported since Visual Studio C++ 6.0 - # and CMake does not support an earlier version - set (${_msgVar} "" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") - # GCC PCH support requires version >= 3.4 - if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") - set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) - else() - set (${_msgVar} "" PARENT_SCOPE) - endif() - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") - # all Clang versions have PCH support - set (${_msgVar} "" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") - # Intel PCH support requires version >= 8.0.0 - if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") - set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) - else() - set (${_msgVar} "" PARENT_SCOPE) - endif() - else() - set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) - endif() - get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER) - if (CMAKE_${_language}_COMPILER MATCHES "ccache" OR _launcher MATCHES "ccache") - if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros|pch_defines") - set (${_msgVar} - "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." - PARENT_SCOPE) - endif() - endif() - if (APPLE) - # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) - cotire_get_configuration_types(_configs) - foreach (_config ${_configs}) - set (_targetFlags "") - cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) - cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) - list (LENGTH _architectures _numberOfArchitectures) - if (_numberOfArchitectures GREATER 1) - string (REPLACE ";" ", " _architectureStr "${_architectures}") - set (${_msgVar} - "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." - PARENT_SCOPE) - break() - endif() - endforeach() - endif() -endfunction() - -macro (cotire_get_intermediate_dir _cotireDir) - # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types - get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) -endmacro() - -macro (cotire_setup_file_extension_variables) - set (_unityFileExt_C ".c") - set (_unityFileExt_CXX ".cxx") - set (_prefixFileExt_C ".h") - set (_prefixFileExt_CXX ".hxx") - set (_prefixSourceFileExt_C ".c") - set (_prefixSourceFileExt_CXX ".cxx") -endmacro() - -function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _unityFileExt_${_language}) - set (${_unityFileVar} "" PARENT_SCOPE) - return() - endif() - set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") - set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") - cotire_get_intermediate_dir(_baseDir) - set (_unityFile "${_baseDir}/${_unityFileName}") - set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) -endfunction() - -function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _unityFileExt_${_language}) - set (${_unityFileVar} "" PARENT_SCOPE) - return() - endif() - set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") - cotire_get_intermediate_dir(_baseDir) - set (_startIndex 0) - set (_index 0) - set (_unityFiles "") - set (_sourceFiles ${ARGN}) - foreach (_sourceFile ${_sourceFiles}) - get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) - math (EXPR _unityFileCount "${_index} - ${_startIndex}") - if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) - if (_index GREATER 0) - # start new unity file segment - math (EXPR _endIndex "${_index} - 1") - set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") - list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") - endif() - set (_startIndex ${_index}) - endif() - math (EXPR _index "${_index} + 1") - endforeach() - list (LENGTH _sourceFiles _numberOfSources) - if (_startIndex EQUAL 0) - # there is only a single unity file - cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) - elseif (_startIndex LESS _numberOfSources) - # end with final unity file segment - math (EXPR _endIndex "${_index} - 1") - set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") - list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") - endif() - set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) - if (COTIRE_DEBUG AND _unityFiles) - message (STATUS "unity files: ${_unityFiles}") - endif() -endfunction() - -function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _unityFileExt_${_language}) - set (${_prefixFileVar} "" PARENT_SCOPE) - return() - endif() - set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") - set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") - string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") - string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") - set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) -endfunction() - -function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) - cotire_setup_file_extension_variables() - if (NOT DEFINED _prefixSourceFileExt_${_language}) - set (${_prefixSourceFileVar} "" PARENT_SCOPE) - return() - endif() - string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") - set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) -endfunction() - -function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) - cotire_setup_file_extension_variables() - if (NOT _language) - set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") - set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") - elseif (DEFINED _prefixFileExt_${_language}) - set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") - set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") - else() - set (_prefixFileBaseName "") - set (_prefixFileName "") - endif() - set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) - set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) -endfunction() - -function (cotire_make_prefix_file_path _language _target _prefixFileVar) - cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) - set (${_prefixFileVar} "" PARENT_SCOPE) - if (_prefixFileName) - if (NOT _language) - set (_language "C") - endif() - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC") - cotire_get_intermediate_dir(_baseDir) - set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) - endif() - endif() -endfunction() - -function (cotire_make_pch_file_path _language _target _pchFileVar) - cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) - set (${_pchFileVar} "" PARENT_SCOPE) - if (_prefixFileBaseName AND _prefixFileName) - cotire_check_precompiled_header_support("${_language}" "${_target}" _msg) - if (NOT _msg) - if (XCODE) - # For Xcode, we completely hand off the compilation of the prefix header to the IDE - return() - endif() - cotire_get_intermediate_dir(_baseDir) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") - # MSVC uses the extension .pch added to the prefix header base name - set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") - # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended - set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") - # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended - set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) - elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") - # Intel uses the extension .pchi added to the prefix header base name - set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - -function (cotire_select_unity_source_files _unityFile _sourcesVar) - set (_sourceFiles ${ARGN}) - if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") - set (_startIndex ${CMAKE_MATCH_1}) - set (_endIndex ${CMAKE_MATCH_2}) - list (LENGTH _sourceFiles _numberOfSources) - if (NOT _startIndex LESS _numberOfSources) - math (EXPR _startIndex "${_numberOfSources} - 1") - endif() - if (NOT _endIndex LESS _numberOfSources) - math (EXPR _endIndex "${_numberOfSources} - 1") - endif() - set (_files "") - foreach (_index RANGE ${_startIndex} ${_endIndex}) - list (GET _sourceFiles ${_index} _file) - list (APPEND _files "${_file}") - endforeach() - else() - set (_files ${_sourceFiles}) - endif() - set (${_sourcesVar} ${_files} PARENT_SCOPE) -endfunction() - -function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) - set (_dependencySources "") - # depend on target's generated source files - get_target_property(_targetSourceFiles ${_target} SOURCES) - cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) - if (_generatedSources) - # but omit all generated source files that have the COTIRE_EXCLUDED property set to true - cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) - if (_excludedGeneratedSources) - list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) - endif() - # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly - cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) - if (_excludedNonDependencySources) - list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) - endif() - if (_generatedSources) - list (APPEND _dependencySources ${_generatedSources}) - endif() - endif() - if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}") - endif() - set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) -endfunction() - -function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) - set (_dependencySources "") - # depend on target source files marked with custom COTIRE_DEPENDENCY property - get_target_property(_targetSourceFiles ${_target} SOURCES) - cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles}) - if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}") - endif() - set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) -endfunction() - -function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar) - set (_targetSources ${ARGN}) - cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources}) - cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources}) - # set up variables to be configured - set (COTIRE_TARGET_LANGUAGE "${_language}") - get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) - cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) - get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) - cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) - get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) - get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) - get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) - get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH) - cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources}) - cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources}) - set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") - foreach (_config ${_configurations}) - string (TOUPPER "${_config}" _upperConfig) - cotire_get_target_include_directories( - "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) - cotire_get_target_compile_definitions( - "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) - cotire_get_target_compiler_flags( - "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) - cotire_get_source_files_compile_definitions( - "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources}) - endforeach() - get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER) - # set up COTIRE_TARGET_SOURCES - set (COTIRE_TARGET_SOURCES "") - foreach (_sourceFile ${_targetSources}) - get_source_file_property(_generated "${_sourceFile}" GENERATED) - if (_generated) - # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation - get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) - list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}") - else() - list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}") - endif() - endforeach() - # copy variable definitions to cotire target script - get_cmake_property(_vars VARIABLES) - string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") - # omit COTIRE_*_INIT variables - string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}") - if (_initVars) - list (REMOVE_ITEM _matchVars ${_initVars}) - endif() - # omit COTIRE_VERBOSE which is passed as a CMake define on command line - list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) - set (_contents "") - set (_contentsHasGeneratorExpressions FALSE) - foreach (_var IN LISTS _matchVars ITEMS - XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES - CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION - CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 - CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_${_language}_SEP - CMAKE_INCLUDE_SYSTEM_FLAG_${_language} - CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG - CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG - CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) - if (DEFINED ${_var}) - string (REPLACE "\"" "\\\"" _value "${${_var}}") - set (_contents "${_contents}set (${_var} \"${_value}\")\n") - if (NOT _contentsHasGeneratorExpressions) - if ("${_value}" MATCHES "\\$<.*>") - set (_contentsHasGeneratorExpressions TRUE) - endif() - endif() - endif() - endforeach() - # generate target script file - get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) - set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") - cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) - if (_contentsHasGeneratorExpressions) - # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time - set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") - set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") - file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") - else() - set (_targetCotireConfigScript "${_targetCotireScript}") - endif() - set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) - set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) -endfunction() - -function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) - set (_sourceFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # for Visual Studio and Intel, we attach the precompiled header compilation to the host file - # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion - if (_sourceFiles) - set (_flags "") - cotire_add_pch_compilation_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) - set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") - # make object file generated from host file depend on prefix header - set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") - # mark host file as cotired to prevent it from being used in another cotired target - set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") - endif() - elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # for makefile based generator, we add a custom command to precompile the prefix header - if (_targetScript) - cotire_set_cmd_to_prologue(_cmds) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath) - else() - file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}") - endif() - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") - endif() - set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) - add_custom_command( - OUTPUT "${_pchFile}" - COMMAND ${_cmds} - DEPENDS "${_prefixFile}" - IMPLICIT_DEPENDS ${_language} "${_prefixFile}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}" - VERBATIM) - endif() - endif() -endfunction() - -function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) - if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # for Visual Studio and Intel, we include the precompiled header in all but the host file - # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation - set (_sourceFiles ${ARGN}) - list (LENGTH _sourceFiles _numberOfSourceFiles) - if (_numberOfSourceFiles GREATER 0) - # mark sources as cotired to prevent them from being used in another cotired target - set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - set (_flags "") - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # make object files generated from source files depend on precompiled header - set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") - endif() - elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - set (_sourceFiles ${_hostFile} ${ARGN}) - if (NOT _wholeTarget) - # for makefile based generator, we force the inclusion of the prefix header for a subset - # of the source files, if this is a multi-language target or has excluded files - set (_flags "") - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # mark sources as cotired to prevent them from being used in another cotired target - set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - endif() - # make object files generated from source files depend on precompiled header - set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") - endif() -endfunction() - -function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) - set (_sourceFiles ${ARGN}) - # force the inclusion of the prefix header for the given source files - set (_flags "") - set (_pchFile "") - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _flags) - set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") - # mark sources as cotired to prevent them from being used in another cotired target - set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") - # make object files generated from source files depend on prefix header - set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") -endfunction() - -function (cotire_get_first_set_property_value _propertyValueVar _type _object) - set (_properties ${ARGN}) - foreach (_property ${_properties}) - get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) - if (_propertyValue) - set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) - return() - endif() - endforeach() - set (${_propertyValueVar} "" PARENT_SCOPE) -endfunction() - -function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar) - set (_files ${ARGN}) - set (_filesPaths "") - foreach (_file ${_files}) - get_filename_component(_filePath "${_file}" ABSOLUTE) - list (APPEND _filesPaths "${_filePath}") - endforeach() - cotire_set_cmd_to_prologue(_prefixCmd) - list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") - if (_targetScript) - list (APPEND _prefixCmd "${_targetScript}") - endif() - list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") - endif() - set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath) - else() - file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") - endif() - get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) - get_filename_component(_joinedFileExt "${_joinedFile}" EXT) - if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") - set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}") - elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") - if (_joinedFileExt MATCHES "^\\.c") - set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}") - else() - set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}") - endif() - else() - set (_comment "Generating ${_joinedFileLogPath}") - endif() - add_custom_command( - OUTPUT "${_joinedFile}" - COMMAND ${_prefixCmd} - DEPENDS ${_files} - COMMENT "${_comment}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - VERBATIM) - list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_target_pch_usage _languages _target _wholeTarget) - if (XCODE) - # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers - set (_prefixFiles "") - foreach (_language ${_languages}) - get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - if (_prefixFile) - list (APPEND _prefixFiles "${_prefixFile}") - endif() - endforeach() - set (_cmds ${ARGN}) - list (LENGTH _prefixFiles _numberOfPrefixFiles) - if (_numberOfPrefixFiles GREATER 1) - # we also generate a generic, single prefix header which includes all language specific prefix headers - set (_language "") - set (_targetScript "") - cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader) - cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles}) - else() - set (_prefixHeader "${_prefixFiles}") - endif() - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") - endif() - # because CMake PRE_BUILD command does not support dependencies, - # we check dependencies explicity in cotire script mode when the pre-build action is run - add_custom_command( - TARGET "${_target}" - PRE_BUILD ${_cmds} - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - COMMENT "Updating target ${_target} prefix headers" - VERBATIM) - # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ - set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") - set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") - elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # for makefile based generator, we force inclusion of the prefix header for all target source files - # if this is a single-language target without any excluded files - if (_wholeTarget) - set (_language "${_languages}") - # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level - # see cotire_setup_pch_file_inclusion - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - if (_prefixFile) - get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) - set (_options COMPILE_OPTIONS) - cotire_add_prefix_pch_inclusion_flags( - "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" - "${_prefixFile}" "${_pchFile}" _options) - set_property(TARGET ${_target} APPEND PROPERTY ${_options}) - endif() - endif() - endif() - endif() -endfunction() - -function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar) - set (_dependencySources "") - cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) - foreach (_unityFile ${_unityFiles}) - set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) - # set up compiled unity source dependencies via OBJECT_DEPENDS - # this ensures that missing source files are generated before the unity file is compiled - if (COTIRE_DEBUG AND _dependencySources) - message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") - endif() - if (_dependencySources) - # the OBJECT_DEPENDS property requires a list of full paths - set (_objectDependsPaths "") - foreach (_sourceFile ${_dependencySources}) - get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) - list (APPEND _objectDependsPaths "${_sourceLocation}") - endforeach() - set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) - endif() - if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel - set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") - endif() - cotire_set_cmd_to_prologue(_unityCmd) - list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") - if (CMAKE_VERSION VERSION_LESS "3.1.0") - set (_unityCmdDepends "${_targetScript}") - else() - # CMake 3.1.0 supports generator expressions in arguments to DEPENDS - set (_unityCmdDepends "${_targetConfigScript}") - endif() - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath) - else() - file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}") - endif() - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") - endif() - add_custom_command( - OUTPUT "${_unityFile}" - COMMAND ${_unityCmd} - DEPENDS ${_unityCmdDepends} - COMMENT "Generating ${_language} unity source ${_unityFileLogPath}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - VERBATIM) - list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) - endforeach() - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) - set (_sourceFiles ${ARGN}) - set (_dependencySources "") - cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) - cotire_set_cmd_to_prologue(_prefixCmd) - list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles}) - set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) - if (COTIRE_DEBUG) - message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources}") - endif() - if (MSVC_IDE) - file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath) - else() - file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") - endif() - get_filename_component(_prefixFileExt "${_prefixFile}" EXT) - if (_prefixFileExt MATCHES "^\\.c") - set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}") - else() - set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}") - endif() - # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist - # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence - # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files - set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre") - if (TARGET ${_preTargetName}) - # custom helper target has already been generated while processing a different language - list (APPEND _dependencySources ${_preTargetName}) - else() - get_target_property(_targetSourceFiles ${_target} SOURCES) - cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) - if (_generatedSources) - add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources}) - cotire_init_target("${_preTargetName}") - list (APPEND _dependencySources ${_preTargetName}) - endif() - endif() - add_custom_command( - OUTPUT "${_prefixFile}" "${_prefixFile}.log" - COMMAND ${_prefixCmd} - DEPENDS ${_unityFiles} ${_dependencySources} - COMMENT "${_comment}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - VERBATIM) - list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) - set (_sourceFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma - cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) - else() - set (_prefixSourceFile "${_prefixFile}") - endif() - cotire_setup_prefix_generation_command( - ${_language} ${_target} "${_targetScript}" - "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # set up generation of a prefix source file which includes the prefix header - cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) - endif() - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar) - set (_prefixHeaderFiles ${ARGN}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma - cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) - else() - set (_prefixSourceFile "${_prefixFile}") - endif() - cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) - if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") - # set up generation of a prefix source file which includes the prefix header - cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) - endif() - set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) -endfunction() - -function (cotire_init_cotire_target_properties _target) - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") - cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") - if (NOT _isRelative) - set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") - endif() - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) - if (NOT _isSet) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY") - endif() - get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) - if (NOT _isSet) - if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") - else() - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") - endif() - endif() -endfunction() - -function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) - string (REPLACE ";" " " _languagesStr "${_languages}") - math (EXPR _numberOfExcludedFiles "${ARGC} - 4") - if (_numberOfExcludedFiles EQUAL 0) - set (_excludedStr "") - elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) - string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") - else() - set (_excludedStr "excluding ${_numberOfExcludedFiles} files") - endif() - set (_targetMsg "") - if (NOT _languages) - set (_targetMsg "Target ${_target} cannot be cotired.") - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - elseif (NOT _targetUsePCH AND NOT _targetAddSCU) - set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - elseif (NOT _targetUsePCH) - if (_excludedStr) - set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") - else() - set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") - endif() - if (_disableMsg) - set (_targetMsg "${_targetMsg} ${_disableMsg}") - endif() - elseif (NOT _targetAddSCU) - if (_excludedStr) - set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") - else() - set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") - endif() - else() - if (_excludedStr) - set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") - else() - set (_targetMsg "${_languagesStr} target ${_target} cotired.") - endif() - endif() - set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) -endfunction() - -function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar) - set (_languages ${ARGN}) - set (_allSourceFiles "") - set (_allExcludedSourceFiles "") - set (_allCotiredSourceFiles "") - set (_targetLanguages "") - set (_pchEligibleTargetLanguages "") - get_target_property(_targetType ${_target} TYPE) - get_target_property(_targetSourceFiles ${_target} SOURCES) - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) - set (_disableMsg "") - foreach (_language ${_languages}) - get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) - get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) - if (_prefixHeader OR _unityBuildFile) - message (STATUS "cotire: target ${_target} has already been cotired.") - set (${_targetLanguagesVar} "" PARENT_SCOPE) - return() - endif() - if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND NOT "${CMAKE_${_language}_COMPILER_ID}" STREQUAL "") - cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg) - if (_disableMsg) - set (_targetUsePCH FALSE) - endif() - endif() - set (_sourceFiles "") - set (_excludedSources "") - set (_cotiredSources "") - cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) - if (_sourceFiles OR _excludedSources OR _cotiredSources) - list (APPEND _targetLanguages ${_language}) - endif() - if (_sourceFiles) - list (APPEND _allSourceFiles ${_sourceFiles}) - endif() - list (LENGTH _sourceFiles _numberOfSources) - if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - list (APPEND _pchEligibleTargetLanguages ${_language}) - endif() - if (_excludedSources) - list (APPEND _allExcludedSourceFiles ${_excludedSources}) - endif() - if (_cotiredSources) - list (APPEND _allCotiredSourceFiles ${_cotiredSources}) - endif() - endforeach() - set (_targetMsgLevel STATUS) - if (NOT _targetLanguages) - string (REPLACE ";" " or " _languagesStr "${_languages}") - set (_disableMsg "No ${_languagesStr} source files.") - set (_targetUsePCH FALSE) - set (_targetAddSCU FALSE) - endif() - if (_targetUsePCH) - if (_allCotiredSourceFiles) - cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) - list (REMOVE_DUPLICATES _cotireTargets) - string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") - set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") - set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") - set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") - set (_targetMsgLevel SEND_ERROR) - set (_targetUsePCH FALSE) - elseif (NOT _pchEligibleTargetLanguages) - set (_disableMsg "Too few applicable sources.") - set (_targetUsePCH FALSE) - elseif (XCODE AND _allExcludedSourceFiles) - # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target - set (_disableMsg "Exclusion of source files not supported for generator Xcode.") - set (_targetUsePCH FALSE) - elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") - # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target - set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") - set (_targetUsePCH FALSE) - endif() - endif() - set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) - set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) - cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) - if (_targetMsg) - if (NOT DEFINED COTIREMSG_${_target}) - set (COTIREMSG_${_target} "") - endif() - if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR - NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") - # cache message to avoid redundant messages on re-configure - set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") - message (${_targetMsgLevel} "${_targetMsg}") - endif() - endif() - list (LENGTH _targetLanguages _numberOfLanguages) - if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) - set (${_wholeTargetVar} FALSE PARENT_SCOPE) - else() - set (${_wholeTargetVar} TRUE PARENT_SCOPE) - endif() - set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) -endfunction() - -function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) - set (_sourceFiles ${ARGN}) - get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) - if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") - set (_numberOfThreads "${CMAKE_MATCH_2}") - if (NOT _numberOfThreads) - # use all available cores - ProcessorCount(_numberOfThreads) - endif() - list (LENGTH _sourceFiles _numberOfSources) - math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") - elseif (NOT _maxIncludes MATCHES "[0-9]+") - set (_maxIncludes 0) - endif() - if (COTIRE_DEBUG) - message (STATUS "${_target} unity source max includes: ${_maxIncludes}") - endif() - set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) -endfunction() - -function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar) - set (${_cmdsVar} "" PARENT_SCOPE) - get_target_property(_targetSourceFiles ${_target} SOURCES) - set (_sourceFiles "") - set (_excludedSources "") - set (_cotiredSources "") - cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) - if (NOT _sourceFiles AND NOT _cotiredSources) - return() - endif() - set (_cmds "") - # check for user provided unity source file list - get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) - if (NOT _unitySourceFiles) - set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) - endif() - cotire_generate_target_script( - ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) - # set up unity files for parallel compilation - cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) - cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) - list (LENGTH _unityFiles _numberOfUnityFiles) - if (_numberOfUnityFiles EQUAL 0) - return() - elseif (_numberOfUnityFiles GREATER 1) - cotire_setup_unity_generation_commands( - ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) - endif() - # set up single unity file for prefix header generation - cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) - cotire_setup_unity_generation_commands( - ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles}) - cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) - # set up prefix header - if (_prefixFile) - # check for user provided prefix header files - get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) - if (_prefixHeaderFiles) - cotire_setup_prefix_generation_from_provided_command( - ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) - else() - cotire_setup_prefix_generation_from_unity_command( - ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles}) - endif() - # check if selected language has enough sources at all - list (LENGTH _sourceFiles _numberOfSources) - if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) - set (_targetUsePCH FALSE) - else() - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - endif() - if (_targetUsePCH) - cotire_make_pch_file_path(${_language} ${_target} _pchFile) - if (_pchFile) - # first file in _sourceFiles is passed as the host file - cotire_setup_pch_file_compilation( - ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) - cotire_setup_pch_file_inclusion( - ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) - endif() - elseif (_prefixHeaderFiles) - # user provided prefix header must be included unconditionally - cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) - endif() - endif() - # mark target as cotired for language - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") - if (_prefixFile) - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") - if (_targetUsePCH AND _pchFile) - set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") - endif() - endif() - set (${_cmdsVar} ${_cmds} PARENT_SCOPE) -endfunction() - -function (cotire_setup_clean_target _target) - set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") - if (NOT TARGET "${_cleanTargetName}") - cotire_set_cmd_to_prologue(_cmds) - get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") - add_custom_target(${_cleanTargetName} - COMMAND ${_cmds} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Cleaning up target ${_target} cotire generated files" - VERBATIM) - cotire_init_target("${_cleanTargetName}") - endif() -endfunction() - -function (cotire_setup_pch_target _languages _configurations _target) - if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") - # for makefile based generators, we add a custom target to trigger the generation of the cotire related files - set (_dependsFiles "") - foreach (_language ${_languages}) - set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) - if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") - # Visual Studio and Intel only create precompiled header as a side effect - list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) - endif() - cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) - if (_dependsFile) - list (APPEND _dependsFiles "${_dependsFile}") - endif() - endforeach() - if (_dependsFiles) - set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") - add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) - cotire_init_target("${_pchTargetName}") - cotire_add_to_pch_all_target(${_pchTargetName}) - endif() - else() - # for other generators, we add the "clean all" target to clean up the precompiled header - cotire_setup_clean_all_target() - endif() -endfunction() - -function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar) - get_target_property(_targetSourceFiles ${_target} SOURCES) - set (_unityTargetSources ${_targetSourceFiles}) - foreach (_language ${_languages}) - get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) - if (_unityFiles) - # remove source files that are included in the unity source - set (_sourceFiles "") - set (_excludedSources "") - set (_cotiredSources "") - cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) - if (_sourceFiles OR _cotiredSources) - list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) - endif() - # add unity source files instead - list (APPEND _unityTargetSources ${_unityFiles}) - endif() - endforeach() - set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE) -endfunction() - -function (cotire_setup_unity_target_pch_usage _languages _target) - foreach (_language ${_languages}) - get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) - if (_unityFiles) - get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) - get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) - if (_userPrefixFile AND _prefixFile) - # user provided prefix header must be included unconditionally by unity sources - cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles}) - endif() - endif() - endforeach() -endfunction() - -function (cotire_setup_unity_build_target _languages _configurations _target) - get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) - if (NOT _unityTargetName) - set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") - endif() - # determine unity target sub type - get_target_property(_targetType ${_target} TYPE) - if ("${_targetType}" STREQUAL "EXECUTABLE") - set (_unityTargetSubType "") - elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") - set (_unityTargetSubType "${CMAKE_MATCH_1}") - else() - message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") - return() - endif() - # determine unity target sources - set (_unityTargetSources "") - cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources) - # handle automatic Qt processing - get_target_property(_targetAutoMoc ${_target} AUTOMOC) - get_target_property(_targetAutoUic ${_target} AUTOUIC) - get_target_property(_targetAutoRcc ${_target} AUTORCC) - if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) - # if the original target sources are subject to CMake's automatic Qt processing, - # also include implicitly generated _automoc.cpp file - list (APPEND _unityTargetSources "${_target}_automoc.cpp") - set_property (SOURCE "${_target}_automoc.cpp" PROPERTY GENERATED TRUE) - endif() - # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created - set (CMAKE_AUTOMOC OFF) - set (CMAKE_AUTOUIC OFF) - set (CMAKE_AUTORCC OFF) - if (COTIRE_DEBUG) - message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") - endif() - # generate unity target - if ("${_targetType}" STREQUAL "EXECUTABLE") - add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) - else() - add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) - endif() - if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) - # depend on the original target's implicity generated _automoc target - add_dependencies(${_unityTargetName} ${_target}_automoc) - endif() - # copy output location properties - set (_outputDirProperties - ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ - LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ - RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) - if (COTIRE_UNITY_OUTPUT_DIRECTORY) - set (_setDefaultOutputDir TRUE) - if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") - set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") - else() - # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) - cotire_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties}) - foreach (_property ${_properties}) - get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) - if (_outputDir) - get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) - set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") - set (_setDefaultOutputDir FALSE) - endif() - endforeach() - if (_setDefaultOutputDir) - get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) - endif() - endif() - if (_setDefaultOutputDir) - set_target_properties(${_unityTargetName} PROPERTIES - ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" - LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" - RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") - endif() - else() - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - ${_outputDirProperties}) - endif() - # copy output name - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ - LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ - OUTPUT_NAME OUTPUT_NAME_ - RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ - PREFIX _POSTFIX SUFFIX - IMPORT_PREFIX IMPORT_SUFFIX) - # copy compile stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ - COMPILE_FLAGS COMPILE_OPTIONS - Fortran_FORMAT Fortran_MODULE_DIRECTORY - INCLUDE_DIRECTORIES - INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ - POSITION_INDEPENDENT_CODE - C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER - C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE - C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN) - # copy compile features - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED - CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED - COMPILE_FEATURES) - # copy interface stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN - COMPATIBLE_INTERFACE_STRING - INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS - INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES - INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES - INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED) - # copy link stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH - LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED - LINK_FLAGS LINK_FLAGS_ - LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ - LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ - LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC - STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ - NO_SONAME SOVERSION VERSION) - # copy cmake stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) - # copy Apple platform specific stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR - MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH - OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST - IOS_INSTALL_COMBINED) - # copy Windows platform specific stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - GNUtoMS - COMPILE_PDB_NAME COMPILE_PDB_NAME_ - COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_ - PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ - VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION - VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE - VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK - VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION - VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER - VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION - VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES - WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS) - # copy Android platform specific stuff - cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} - ANDROID_API ANDROID_API_MIN ANDROID_GUI - ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES - ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR - ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES - ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH - ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE) - # use output name from original target - get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) - if (NOT _targetOutputName) - set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") - endif() - # use export symbol from original target - cotire_get_target_export_symbol("${_target}" _defineSymbol) - if (_defineSymbol) - set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") - if ("${_targetType}" STREQUAL "EXECUTABLE") - set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) - endif() - endif() - cotire_init_target(${_unityTargetName}) - cotire_add_to_unity_all_target(${_unityTargetName}) - set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") -endfunction(cotire_setup_unity_build_target) - -function (cotire_target _target) - set(_options "") - set(_oneValueArgs "") - set(_multiValueArgs LANGUAGES CONFIGURATIONS) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - if (NOT _option_LANGUAGES) - get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) - endif() - if (NOT _option_CONFIGURATIONS) - cotire_get_configuration_types(_option_CONFIGURATIONS) - endif() - # check if cotire can be applied to target at all - cotire_is_target_supported(${_target} _isSupported) - if (NOT _isSupported) - get_target_property(_imported ${_target} IMPORTED) - get_target_property(_targetType ${_target} TYPE) - if (_imported) - message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.") - else() - message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.") - endif() - return() - endif() - # resolve alias - get_target_property(_aliasName ${_target} ALIASED_TARGET) - if (_aliasName) - if (COTIRE_DEBUG) - message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") - endif() - set (_target ${_aliasName}) - endif() - # check if target needs to be cotired for build type - # when using configuration types, the test is performed at build time - cotire_init_cotire_target_properties(${_target}) - if (NOT CMAKE_CONFIGURATION_TYPES) - if (CMAKE_BUILD_TYPE) - list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) - else() - list (FIND _option_CONFIGURATIONS "None" _index) - endif() - if (_index EQUAL -1) - if (COTIRE_DEBUG) - message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") - endif() - return() - endif() - endif() - # when not using configuration types, immediately create cotire intermediate dir - if (NOT CMAKE_CONFIGURATION_TYPES) - cotire_get_intermediate_dir(_baseDir) - file (MAKE_DIRECTORY "${_baseDir}") - endif() - # choose languages that apply to the target - cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) - if (NOT _targetLanguages) - return() - endif() - set (_cmds "") - foreach (_language ${_targetLanguages}) - cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd) - if (_cmd) - list (APPEND _cmds ${_cmd}) - endif() - endforeach() - get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) - if (_targetAddSCU) - cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) - endif() - get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) - if (_targetUsePCH) - cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds}) - cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) - if (_targetAddSCU) - cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target}) - endif() - endif() - get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) - if (_targetAddCleanTarget) - cotire_setup_clean_target(${_target}) - endif() -endfunction(cotire_target) - -function (cotire_map_libraries _strategy _mappedLibrariesVar) - set (_mappedLibraries "") - foreach (_library ${ARGN}) - if (_library MATCHES "^\\$$") - set (_libraryName "${CMAKE_MATCH_1}") - set (_linkOnly TRUE) - else() - set (_libraryName "${_library}") - set (_linkOnly FALSE) - endif() - if ("${_strategy}" MATCHES "COPY_UNITY") - cotire_is_target_supported(${_libraryName} _isSupported) - if (_isSupported) - # use target's corresponding unity target, if available - get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME) - if (TARGET "${_libraryUnityTargetName}") - if (_linkOnly) - list (APPEND _mappedLibraries "$") - else() - list (APPEND _mappedLibraries "${_libraryUnityTargetName}") - endif() - else() - list (APPEND _mappedLibraries "${_library}") - endif() - else() - list (APPEND _mappedLibraries "${_library}") - endif() - else() - list (APPEND _mappedLibraries "${_library}") - endif() - endforeach() - list (REMOVE_DUPLICATES _mappedLibraries) - set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) -endfunction() - -function (cotire_target_link_libraries _target) - cotire_is_target_supported(${_target} _isSupported) - if (NOT _isSupported) - return() - endif() - get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) - if (TARGET "${_unityTargetName}") - get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) - if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") - endif() - if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") - get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) - if (_linkLibraries) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries}) - set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}") - if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}") - endif() - endif() - get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) - if (_interfaceLinkLibraries) - cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries}) - set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}") - if (COTIRE_DEBUG) - message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}") - endif() - endif() - endif() - endif() -endfunction(cotire_target_link_libraries) - -function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) - if (_targetName) - file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") - else() - file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") - endif() - # filter files in intermediate directory - set (_filesToRemove "") - foreach (_file ${_cotireFiles}) - get_filename_component(_dir "${_file}" DIRECTORY) - get_filename_component(_dirName "${_dir}" NAME) - if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") - list (APPEND _filesToRemove "${_file}") - endif() - endforeach() - if (_filesToRemove) - if (COTIRE_VERBOSE) - message (STATUS "cleaning up ${_filesToRemove}") - endif() - file (REMOVE ${_filesToRemove}) - endif() -endfunction() - -function (cotire_init_target _targetName) - if (COTIRE_TARGETS_FOLDER) - set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") - endif() - set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE) - if (MSVC_IDE) - set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) - endif() -endfunction() - -function (cotire_add_to_pch_all_target _pchTargetName) - set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") - if (NOT TARGET "${_targetName}") - add_custom_target("${_targetName}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - VERBATIM) - cotire_init_target("${_targetName}") - endif() - cotire_setup_clean_all_target() - add_dependencies(${_targetName} ${_pchTargetName}) -endfunction() - -function (cotire_add_to_unity_all_target _unityTargetName) - set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") - if (NOT TARGET "${_targetName}") - add_custom_target("${_targetName}" - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - VERBATIM) - cotire_init_target("${_targetName}") - endif() - cotire_setup_clean_all_target() - add_dependencies(${_targetName} ${_unityTargetName}) -endfunction() - -function (cotire_setup_clean_all_target) - set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") - if (NOT TARGET "${_targetName}") - cotire_set_cmd_to_prologue(_cmds) - list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") - add_custom_target(${_targetName} - COMMAND ${_cmds} - WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" - COMMENT "Cleaning up all cotire generated files" - VERBATIM) - cotire_init_target("${_targetName}") - endif() -endfunction() - -function (cotire) - set(_options "") - set(_oneValueArgs "") - set(_multiValueArgs LANGUAGES CONFIGURATIONS) - cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) - set (_targets ${_option_UNPARSED_ARGUMENTS}) - foreach (_target ${_targets}) - if (TARGET ${_target}) - cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}) - else() - message (WARNING "cotire: ${_target} is not a target.") - endif() - endforeach() - foreach (_target ${_targets}) - if (TARGET ${_target}) - cotire_target_link_libraries(${_target}) - endif() - endforeach() -endfunction() - -if (CMAKE_SCRIPT_MODE_FILE) - - # cotire is being run in script mode - # locate -P on command args - set (COTIRE_ARGC -1) - foreach (_index RANGE ${CMAKE_ARGC}) - if (COTIRE_ARGC GREATER -1) - set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") - math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") - elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") - set (COTIRE_ARGC 0) - endif() - endforeach() - - # include target script if available - if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") - # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) - include("${COTIRE_ARGV2}") - endif() - - if (COTIRE_DEBUG) - message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") - endif() - - if (NOT COTIRE_BUILD_TYPE) - set (COTIRE_BUILD_TYPE "None") - endif() - string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) - set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) - set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) - set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) - set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) - # check if target has been cotired for actual build type COTIRE_BUILD_TYPE - list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) - if (_index GREATER -1) - set (_sources ${COTIRE_TARGET_SOURCES}) - set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) - else() - if (COTIRE_DEBUG) - message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") - endif() - set (_sources "") - set (_sourcesDefinitions "") - endif() - set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) - set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) - set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) - set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) - - if ("${COTIRE_ARGV1}" STREQUAL "unity") - - if (XCODE) - # executing pre-build action under Xcode, check dependency on target script - set (_dependsOption DEPENDS "${COTIRE_ARGV2}") - else() - # executing custom command, no need to re-check for dependencies - set (_dependsOption "") - endif() - - cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) - - cotire_generate_unity_source( - "${COTIRE_ARGV3}" ${_sources} - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} - PRE_UNDEFS ${_targetPreUndefs} - POST_UNDEFS ${_targetPostUndefs} - SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} - SOURCES_POST_UNDEFS ${_sourcesPostUndefs} - ${_dependsOption}) - - elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") - - if (XCODE) - # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies - set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) - else() - # executing custom command, no need to re-check for dependencies - set (_dependsOption "") - endif() - - set (_files "") - foreach (_index RANGE 4 ${COTIRE_ARGC}) - if (COTIRE_ARGV${_index}) - list (APPEND _files "${COTIRE_ARGV${_index}}") - endif() - endforeach() - - cotire_generate_prefix_header( - "${COTIRE_ARGV3}" ${_files} - COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" - COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" - COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} - COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" - COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" - INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} - IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" - INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH} - INCLUDE_DIRECTORIES ${_includeDirs} - SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} - COMPILE_DEFINITIONS ${_compileDefinitions} - COMPILE_FLAGS ${_compileFlags} - ${_dependsOption}) - - elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") - - set (_files "") - foreach (_index RANGE 5 ${COTIRE_ARGC}) - if (COTIRE_ARGV${_index}) - list (APPEND _files "${COTIRE_ARGV${_index}}") - endif() - endforeach() - - cotire_precompile_prefix_header( - "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" - COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" - COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" - COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} - COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" - COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - INCLUDE_DIRECTORIES ${_includeDirs} - SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} - COMPILE_DEFINITIONS ${_compileDefinitions} - COMPILE_FLAGS ${_compileFlags}) - - elseif ("${COTIRE_ARGV1}" STREQUAL "combine") - - if (COTIRE_TARGET_LANGUAGE) - set (_combinedFile "${COTIRE_ARGV3}") - set (_startIndex 4) - else() - set (_combinedFile "${COTIRE_ARGV2}") - set (_startIndex 3) - endif() - set (_files "") - foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) - if (COTIRE_ARGV${_index}) - list (APPEND _files "${COTIRE_ARGV${_index}}") - endif() - endforeach() - - if (XCODE) - # executing pre-build action under Xcode, check dependency on files to be combined - set (_dependsOption DEPENDS ${_files}) - else() - # executing custom command, no need to re-check for dependencies - set (_dependsOption "") - endif() - - if (COTIRE_TARGET_LANGUAGE) - cotire_generate_unity_source( - "${_combinedFile}" ${_files} - LANGUAGE "${COTIRE_TARGET_LANGUAGE}" - ${_dependsOption}) - else() - cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption}) - endif() - - elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") - - cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") - - else() - message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") - endif() - -else() - - # cotire is being run in include mode - # set up all variable and property definitions - - if (NOT DEFINED COTIRE_DEBUG_INIT) - if (DEFINED COTIRE_DEBUG) - set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) - else() - set (COTIRE_DEBUG_INIT FALSE) - endif() - endif() - option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) - - if (NOT DEFINED COTIRE_VERBOSE_INIT) - if (DEFINED COTIRE_VERBOSE) - set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) - else() - set (COTIRE_VERBOSE_INIT FALSE) - endif() - endif() - option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) - - set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING - "Ignore headers with the listed file extensions from the generated prefix header.") - - set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING - "Ignore headers from these directories when generating the prefix header.") - - set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING - "Ignore sources with the listed file extensions from the generated unity source.") - - set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING - "Minimum number of sources in target required to enable use of precompiled header.") - - if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) - if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) - elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") - # enable parallelization for generators that run multiple jobs by default - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") - else() - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") - endif() - endif() - set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING - "Maximum number of source files to include in a single unity source file.") - - if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) - set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") - endif() - if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) - set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") - endif() - if (NOT COTIRE_INTDIR) - set (COTIRE_INTDIR "cotire") - endif() - if (NOT COTIRE_PCH_ALL_TARGET_NAME) - set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") - endif() - if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) - set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") - endif() - if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) - set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") - endif() - if (NOT COTIRE_CLEAN_TARGET_SUFFIX) - set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") - endif() - if (NOT COTIRE_PCH_TARGET_SUFFIX) - set (COTIRE_PCH_TARGET_SUFFIX "_pch") - endif() - if (MSVC) - # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code - # use a bigger default factor of 170 percent (128 MB) - if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR) - set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170") - endif() - endif() - if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) - set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") - endif() - if (NOT DEFINED COTIRE_TARGETS_FOLDER) - set (COTIRE_TARGETS_FOLDER "cotire") - endif() - if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) - if ("${CMAKE_GENERATOR}" MATCHES "Ninja") - # generated Ninja build files do not work if the unity target produces the same output file as the cotired target - set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") - else() - set (COTIRE_UNITY_OUTPUT_DIRECTORY "") - endif() - endif() - - # define cotire cache variables - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" - BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." - FULL_DOCS - "The variable can be set to a semicolon separated list of include directories." - "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." - "If not defined, defaults to empty list." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" - BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." - FULL_DOCS - "The variable can be set to a semicolon separated list of file extensions." - "If a header file extension matches one in the list, it will be excluded from the generated prefix header." - "Includes with an extension in CMAKE__SOURCE_FILE_EXTENSIONS are always ignored." - "If not defined, defaults to inc;inl;ipp." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" - BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." - FULL_DOCS - "The variable can be set to a semicolon separated list of file extensions." - "If a source file extension matches one in the list, it will be excluded from the generated unity source file." - "Source files with an extension in CMAKE__IGNORE_EXTENSIONS are always excluded." - "If not defined, defaults to m;mm." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" - BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." - FULL_DOCS - "The variable can be set to an integer > 0." - "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." - "If not defined, defaults to 3." - ) - - define_property( - CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" - BRIEF_DOCS "Maximum number of source files to include in a single unity source file." - FULL_DOCS - "This may be set to an integer >= 0." - "If 0, cotire will only create a single unity source file." - "If a target contains more than that number of source files, cotire will create multiple unity source files for it." - "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." - "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." - "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." - "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." - ) - - # define cotire directory properties - - define_property( - DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" - BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." - FULL_DOCS - "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" - BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." - FULL_DOCS - "See target property COTIRE_ADD_UNITY_BUILD." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" - BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." - FULL_DOCS - "See target property COTIRE_ADD_CLEAN." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" - BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." - FULL_DOCS - "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" - BRIEF_DOCS "Honor headers from these directories when generating the prefix header." - FULL_DOCS - "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" - BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header." - FULL_DOCS - "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." - FULL_DOCS - "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." - FULL_DOCS - "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" - BRIEF_DOCS "Maximum number of source files to include in a single unity source file." - FULL_DOCS - "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." - ) - - define_property( - DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" - BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." - FULL_DOCS - "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." - ) - - # define cotire target properties - - define_property( - TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED - BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." - FULL_DOCS - "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." - "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." - "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." - "The target name will be set to this target's name with the suffix _pch appended." - "Inherited from directory." - "Defaults to TRUE." - ) - - define_property( - TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED - BRIEF_DOCS "Add a new target that performs a unity build for this target." - FULL_DOCS - "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." - "Most of the relevant target properties will be copied from this target to the new unity build target." - "Target dependencies and linked libraries have to be manually set up for the new unity build target." - "The unity target name will be set to this target's name with the suffix _unity appended." - "Inherited from directory." - "Defaults to TRUE." - ) - - define_property( - TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED - BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." - FULL_DOCS - "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." - "The clean target name will be set to this target's name with the suffix _clean_cotire appended." - "Inherited from directory." - "Defaults to FALSE." - ) - - define_property( - TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED - BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." - FULL_DOCS - "The property can be set to a list of directories." - "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." - "Inherited from directory." - "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." - ) - - define_property( - TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED - BRIEF_DOCS "Honor headers from these directories when generating the prefix header." - FULL_DOCS - "The property can be set to a list of directories." - "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." - "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," - "the option which yields the closer relative path match wins." - "Inherited from directory." - "If not set, this property is initialized to the empty list." - ) - - define_property( - TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED - BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header." - FULL_DOCS - "The property can be set to a list of directories." - "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header." - "Header files are sorted according to the order of the directories in the property." - "If not set, this property is initialized to the empty list." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file before each target source file." - "Inherited from directory." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file after each target source file." - "Inherited from directory." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED - BRIEF_DOCS "Maximum number of source files to include in a single unity source file." - FULL_DOCS - "This may be set to an integer > 0." - "If a target contains more than that number of source files, cotire will create multiple unity build files for it." - "If not set, cotire will only create a single unity source file." - "Inherited from directory." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE__UNITY_SOURCE_INIT" - BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." - FULL_DOCS - "If set, cotire will only add the given file(s) to the generated unity source file." - "If not set, cotire will add all the target source files to the generated unity source file." - "The property can be set to a user provided unity source file." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE__PREFIX_HEADER_INIT" - BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." - FULL_DOCS - "If set, cotire will add the given header file(s) to the generated prefix header file." - "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." - "The property can be set to a user provided prefix header file (e.g., stdafx.h)." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED - BRIEF_DOCS "Define strategy for setting up unity target's link libraries." - FULL_DOCS - "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually." - "If this property is set to COPY, the unity target's link libraries will be copied from this target." - "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." - "Inherited from directory." - "Defaults to empty." - ) - - define_property( - TARGET PROPERTY "COTIRE__UNITY_SOURCE" - BRIEF_DOCS "Read-only property. The generated unity source file(s)." - FULL_DOCS - "cotire sets this property to the path of the generated single computation unit source file for the target." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE__PREFIX_HEADER" - BRIEF_DOCS "Read-only property. The generated prefix header file." - FULL_DOCS - "cotire sets this property to the full path of the generated language prefix header for the target." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE__PRECOMPILED_HEADER" - BRIEF_DOCS "Read-only property. The generated precompiled header file." - FULL_DOCS - "cotire sets this property to the full path of the generated language precompiled header binary for the target." - "Defaults to empty string." - ) - - define_property( - TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" - BRIEF_DOCS "The name of the generated unity build target corresponding to this target." - FULL_DOCS - "This property can be set to the desired name of the unity target that will be created by cotire." - "If not set, the unity target name will be set to this target's name with the suffix _unity appended." - "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." - "Defaults to empty string." - ) - - # define cotire source properties - - define_property( - SOURCE PROPERTY "COTIRE_EXCLUDED" - BRIEF_DOCS "Do not modify source file's build command." - FULL_DOCS - "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." - "The source file will also be excluded from the generated unity source file." - "Source files that have their COMPILE_FLAGS property set will be excluded by default." - "Defaults to FALSE." - ) - - define_property( - SOURCE PROPERTY "COTIRE_DEPENDENCY" - BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." - FULL_DOCS - "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." - "If the file is modified, cotire will re-generate the prefix header source upon build." - "Defaults to FALSE." - ) - - define_property( - SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file before this file is included." - "Defaults to empty string." - ) - - define_property( - SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" - BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." - FULL_DOCS - "This may be set to a semicolon-separated list of preprocessor symbols." - "cotire will add corresponding #undef directives to the generated unit source file after this file is included." - "Defaults to empty string." - ) - - define_property( - SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" - BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." - FULL_DOCS - "If this property is set to TRUE, cotire will complete the current unity file and start a new one." - "The new unity source file will include this source file as the first one." - "This property essentially works as a separator for unity source files." - "Defaults to FALSE." - ) - - define_property( - SOURCE PROPERTY "COTIRE_TARGET" - BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." - FULL_DOCS - "cotire sets this property to the name of target, that the source file's build command has been altered for." - "Defaults to empty string." - ) - - message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") - -endif() diff --git a/cmake/Modules/sources.cmake b/cmake/Modules/sources.cmake deleted file mode 100644 index 1414a33809..0000000000 --- a/cmake/Modules/sources.cmake +++ /dev/null @@ -1,51 +0,0 @@ -# Copyright (c) 2016, Ford Motor Company -# 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 name of the Ford Motor Company nor the names of its 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. - -function(create_cotired_test NAME SOURCES LIBS) - add_executable( - ${NAME} - EXCLUDE_FROM_ALL - ${CMAKE_SOURCE_DIR}/src/components/test_main.cc - ${SOURCES} - ) - if(${USE_COTIRE}) - include(cotire) - cotire(${NAME}) - set(NAME "${NAME}_unity") - endif() - target_link_libraries(${NAME} ${LIBS}) - set_target_properties( - ${NAME} - PROPERTIES - EXCLUDE_FROM_ALL 0 - ) - add_test(NAME ${NAME} - COMMAND ${NAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/) -endfunction() diff --git a/src/3rd_party-static/CMakeLists.txt b/src/3rd_party-static/CMakeLists.txt index 8dfcf6595a..2acd7be27c 100644 --- a/src/3rd_party-static/CMakeLists.txt +++ b/src/3rd_party-static/CMakeLists.txt @@ -32,8 +32,8 @@ add_subdirectory(./jsoncpp) set(JSONCPP_INCLUDE_DIRECTORY ${JSONCPP_INCLUDE_DIRECTORY} PARENT_SCOPE) -# --- MessageBroker -add_subdirectory(./MessageBroker) +# --- Message Broker +add_subdirectory(./message_broker) set(MESSAGE_BROKER_INCLUDE_DIRECTORY ${MESSAGE_BROKER_INCLUDE_DIRECTORY} PARENT_SCOPE) # --- encryption @@ -48,6 +48,9 @@ if (BUILD_USB_SUPPORT) endif() endif() +# --- gmock if(BUILD_TESTS) + add_subdirectory(./gmock-1.7.0) + set(GMOCK_INCLUDE_DIRECTORY ${GMOCK_INCLUDE_DIRECTORY} PARENT_SCOPE) add_subdirectory(test) endif() diff --git a/src/3rd_party-static/MessageBroker/CMakeLists.txt b/src/3rd_party-static/MessageBroker/CMakeLists.txt deleted file mode 100644 index 87a0fe2a2a..0000000000 --- a/src/3rd_party-static/MessageBroker/CMakeLists.txt +++ /dev/null @@ -1,39 +0,0 @@ -set(MESSAGE_BROKER_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include) -set(MESSAGE_BROKER_INCLUDE_DIRECTORY ${MESSAGE_BROKER_INCLUDE_DIRECTORY} PARENT_SCOPE) - -include_directories ( - ./include/ - ../jsoncpp/include - ../../components/utils/include - -) - -set (MESSAGE_BROKER_SOURCES - ./src/lib_messagebroker/CMessageBroker.cpp - ./src/lib_messagebroker/CMessageBrokerRegistry.cpp - ./src/lib_messagebroker/md5.cpp - ./src/lib_messagebroker/system.cpp - ./src/lib_messagebroker/websocket_handler.cpp -) - -set (MESSAGE_BROKER_CLIENT_SOURCES - ./src/client/mb_client.cpp - ./src/client/mb_tcpclient.cpp - ./src/client/mb_controller.cpp -) - -set (MESSAGE_BROKER_SERVER_SOURCES - ./src/server/mb_server.cpp - ./src/server/mb_tcpserver.cpp - ./src/server/networking.cpp -) - -add_library("MessageBroker" ${MESSAGE_BROKER_SOURCES}) -target_link_libraries(MessageBroker Utils) - - -add_library("MessageBrokerClient" ${MESSAGE_BROKER_CLIENT_SOURCES}) -target_link_libraries("MessageBrokerClient" "MessageBroker") - -add_library("MessageBrokerServer" ${MESSAGE_BROKER_SERVER_SOURCES}) -target_link_libraries("MessageBrokerServer" "MessageBroker") diff --git a/src/3rd_party-static/MessageBroker/include/CMessageBroker.hpp b/src/3rd_party-static/MessageBroker/include/CMessageBroker.hpp deleted file mode 100644 index c542043796..0000000000 --- a/src/3rd_party-static/MessageBroker/include/CMessageBroker.hpp +++ /dev/null @@ -1,108 +0,0 @@ -/** - * \file CMessageBroker.hpp - * \brief CMessageBroker singletone class header. - * \author AKara - */ - -#ifndef CMESSAGEBROKER_H -#define CMESSAGEBROKER_H - -#include - -#include "CSender.hpp" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \enum ErrorCode - * \brief MessageBroker error codes. - * \note Value from -32099 to -32000 are reserved for implementation-defined server-errors. - */ - enum ErrorCode - { - CONTROLLER_EXISTS = -32000, /**< Controller has been already registered. */ - SUBSCRIBTION_EXISTS = -32001, /**< Property has been already subscribed by this controller. */ - PARSING_ERROR = -32700, /**< Invalid JSON. An error occurred on the server while parsing the JSON text. */ - INVALID_REQUEST = -32600, /**< The received JSON not a valid MessageBroker Request. */ - METHOD_NOT_FOUND = -32601, /**< The requested remote-procedure does not exist / is not available. */ - INVALID_PARAMS = -32602, /**< Invalid method parameters. */ - INTERNAL_ERROR = -32603, /**< Internal MessageBroker error. */ - UNSUPPORTED_RESOURCE = 2 /**< Controller doesn't registered. */ - }; - - /** - * \brief Forward declaration of the private class. - */ - class CMessageBroker_Private; - - /** - * \class CMessageBroker - * \brief Singletone CMessageBroker class implementation. - */ - class CMessageBroker - { - public: - /** - * \brief Singletone instantiator. - * \return pointer to CMessageBroker instance. - */ - static CMessageBroker* getInstance(); - - /** - * \brief Destructor. - */ - ~CMessageBroker(); - - /** - * \brief Receive data from TCP server (from client). - * \param fd FileDescriptor of socket. - * \param aJSONData JSON string. - * \param tryHard give up on first JSON parse error or try to workaround it. - */ - void onMessageReceived(int fd, std::string& aJSONData, bool tryHard); - - /** - * \brief Test of buffer parsing. - */ - void Test(); - - /** - * @brief OnSocketClosed should be called if socked is closed by HMI - * @param fd socket descriptor - */ - void OnSocketClosed(const int fd); - - /** - * \brief Starts MessageBroker. - */ - void startMessageBroker(CSender* pSender); - - /** - * \brief Stops MessageBroker. - */ - void stopMessageBroker(); - - /** - * \brief Method for thread with que processing. - */ - void* MethodForThread(void * arg); - - private: - /** - * \brief Private constructor. - */ - CMessageBroker(); - - /** - * \brief The PIMPL of the class. - */ - CMessageBroker_Private *p; - }; -} /* namespace NsMessageBroker */ - -#endif // CMESSAGEBROKER_H - diff --git a/src/3rd_party-static/MessageBroker/include/CMessageBrokerRegistry.hpp b/src/3rd_party-static/MessageBroker/include/CMessageBrokerRegistry.hpp deleted file mode 100644 index 001f978bbf..0000000000 --- a/src/3rd_party-static/MessageBroker/include/CMessageBrokerRegistry.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef CMESSAGEBROKERREGISTRY_H -#define CMESSAGEBROKERREGISTRY_H - -#include -#include -#include -#include -#include "utils/lock.h" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - - /** - * \class CMessageBrokerRegistry - * \brief Singletone CMessageBrokerRegistry class implementation. - */ - class CMessageBrokerRegistry - { - public: - /** - * \brief Singletone instantiator. - * \return pointer to CMessageBroker instance - */ - static CMessageBrokerRegistry* getInstance(); - - /** - * \brief Destructor. - */ - ~CMessageBrokerRegistry(); - - /** - * \brief adds controller to the registry. - * \param fd file descriptor of controller. - * \param name name of controller. - * \return false if already exist. - */ - bool addController(int fd, std::string name); - - /** - * \brief deletes controller from the registry. - * \param name name of controller. - */ - void deleteController(std::string name); - - /** - * \brief Remove all controllers by descriptor - * \param fd descriptor - */ - void removeControllersByDescriptor(const int fd); - - /** - * \brief Remove all subscribers by descriptor - * \param fd descriptor - */ - void removeSubscribersByDescriptor(const int fd); - - /** - * \brief adds notification subscriber to the registry. - * \param fd file descriptor of controller. - * \param name name of property which should be observed. - * \return false if already exist. - */ - bool addSubscriber(int fd, std::string name); - - /** - * \brief deletes notification subscriber from the registry. - * \param fd file descriptor of controller. - * \param name name of property which should be observed. - */ - void deleteSubscriber(int fd, std::string name); - - /** - * \brief gets controller fd from the registry by name. - * \param name name of controller. - * \return file descriptor of controller. - */ - int getDestinationFd(std::string name); - - /** - * \brief gets subscribers fd's. - * \param name name of property. - * \param result vector for results. - * \return count of subscribers. - */ - int getSubscribersFd(std::string name, std::vector& result); - private: - /** - * \brief Constructor. - */ - CMessageBrokerRegistry(); - - /** - * \brief Map to store controllers information like ComponentName:socketFd. - * For example PhoneController:1080 - */ - std::map mControllersList; - sync_primitives::Lock mControllersListLock; - - /** - * \brief Map to store subscribers information like ComponentName.PropertyName:socketFd:. - * For example PhoneController.onPhoneBookChanged:1080 - */ - std::multimap mSubscribersList; - sync_primitives::Lock mSubscribersListLock; - }; -} /* namespace NsMessageBroker */ - -#endif // CMESSAGEBROKERREGISTRY_H - diff --git a/src/3rd_party-static/MessageBroker/include/CSender.hpp b/src/3rd_party-static/MessageBroker/include/CSender.hpp deleted file mode 100644 index 78faf7dad2..0000000000 --- a/src/3rd_party-static/MessageBroker/include/CSender.hpp +++ /dev/null @@ -1,53 +0,0 @@ -/** - * \file CSender.hpp - * \brief CSender class header. - * \author AKara - */ - -#ifndef CSENDER_H -#define CSENDER_H - -#if _MSC_VER >= 1400 // VC++ 8.0 -typedef int ssize_t; -#endif - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \class CSender - * \brief CSender interface class implementation. - */ - class CSender - { - public: - /** - * \brief Constructor. - */ - CSender() - { - } - - /** - * \brief Destructor. - */ - ~CSender() - { - } - - /** - * \brief Send data. - * \param fd file descriptor of the client TCP socket - * \param data data to send - * \return number of bytes sent or -1 if error - */ - virtual ssize_t Send(int fd, const std::string& data)=0; - }; -} /* namespace NsMessageBroker */ - -#endif // CSENDER_H - - diff --git a/src/3rd_party-static/MessageBroker/include/MBDebugHelper.h b/src/3rd_party-static/MessageBroker/include/MBDebugHelper.h deleted file mode 100644 index fa835da3f0..0000000000 --- a/src/3rd_party-static/MessageBroker/include/MBDebugHelper.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * \file MBDebugHelper.h - * \brief DebugHelper. - * \author AKara - */ - -#ifndef MB_DEBUG_HELPER_H -#define MB_DEBUG_HELPER_H - -#include - -/** -* \def DEBUG_ON -* \brief Switches on debug messages. -*/ -//#define DEBUG_ON - -#ifdef DEBUG_ON -/** -* \def DBG_MSG -* \brief Debug message output with file name and line number. -* \param x formatted debug message. -* \return printf construction. -*/ -#define DBG_MSG(x) printf("%s:%d ", __FILE__, __LINE__);\ - printf x -#else -#define DBG_MSG(x) -#endif - -/** -* \def DBG_MSG_ERROR -* \brief Debug ERROR message output with file name and line number. -* \param x formatted debug message. -* \return printf construction. -*/ -#define DBG_MSG_ERROR(x) printf("ERROR!!! %s:%d ", __FILE__, __LINE__);\ - printf x - -#endif /*MB_DEBUG_HELPER_H*/ diff --git a/src/3rd_party-static/MessageBroker/include/mb_client.hpp b/src/3rd_party-static/MessageBroker/include/mb_client.hpp deleted file mode 100644 index cd70a31cd8..0000000000 --- a/src/3rd_party-static/MessageBroker/include/mb_client.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/** - * \file mb_client.hpp - * \brief MessageBroker client. - * \author AKara - */ - -#ifndef MB_CLIENT_H -#define MB_CLIENT_H - -#if _MSC_VER >= 1400 // VC++ 8.0 -typedef int ssize_t; -#endif - -#include "networking.h" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - - /** - * \class Client - * \brief Abstract MessageBroker client. - */ - class Client - { - public: - /** - * \brief Constructor. - * \param address remote network address or FQDN to contact - * \param port remote local port to contact - */ - Client(const std::string& address, uint16_t port); - - /** - * \brief Destructor. - */ - virtual ~Client(); - - /** - * \brief Get socket descriptor. - * \return socket descriptor. - */ - int GetSocket() const; - - /** - * \brief Get the address. - * \return address or FQDN - */ - std::string GetAddress() const; - - /** - * \brief Get the port. - * \return local port - */ - uint16_t GetPort() const; - - /** - * \brief Connect to the remote machine - * \return true if success, false otherwise - * \note on connectionless protocol like UDP, this function - * always returns true even if remote peer is not reachable. - */ - virtual bool Connect(); - - /** - * \brief Receive data from the network. - * \param data if data is received it will put in this reference - * \return number of bytes received or -1 if error - * \note This method will blocked until data comes. - */ - virtual ssize_t Recv(std::string& data) = 0; - - /** - * \brief Close socket. - */ - virtual void Close(); - - protected: - /** - * \brief Socket descriptor. - */ - int m_sock; - - /** - * \brief Transport protocol of the socket. - */ - enum networking::TransportProtocol m_protocol; - - /** - * \brief Remote socket address. - */ - struct sockaddr_storage m_sockaddr; - - /** - * \brief Remote socket address length. - */ - socklen_t m_sockaddrlen; - - /** - * \brief Protected constructor so our inherited classes - * don't need to call the default constructor - */ - Client(); - - /** - * \brief Protected SetAddress so out inherited classes - * don't need to call the default constructor - */ - void SetAddress(const std::string& address); - - /** - * \brief Protected SetPort so out inherited classes - * don't need to call the default constructor - */ - void SetPort(uint16_t port); - - private: - - /** - * \brief Network address or FQDN. - */ - std::string m_address; - - /** - * \brief Local port. - */ - uint16_t m_port; - }; - -} /* namespace NsMessageBroker */ - -#endif /* MB_CLIENT_H */ diff --git a/src/3rd_party-static/MessageBroker/include/mb_controller.hpp b/src/3rd_party-static/MessageBroker/include/mb_controller.hpp deleted file mode 100644 index 2d196aced2..0000000000 --- a/src/3rd_party-static/MessageBroker/include/mb_controller.hpp +++ /dev/null @@ -1,253 +0,0 @@ -/** - * \file mb_controller.hpp - * \brief MessageBroker Controller. - * \author AKara - */ - -#ifndef MB_CONTROLLER_H -#define MB_CONTROLLER_H - -#include - -#include "json/json.h" - -#include "mb_tcpclient.hpp" -#include "utils/lock.h" -#include "utils/atomic_object.h" - -#include - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - - /** - *\class CMessageBrokerController - * \brief MessageBroker Controller. - */ - class CMessageBrokerController : public TcpClient - { - public: - /** - * \brief Constructor. - * \param address remote network address or FQDN - * \param port remote local port - * \param name name of component - */ - CMessageBrokerController(const std::string& address, uint16_t port, std::string name); - - - /** - * \brief Destructor. - */ - ~CMessageBrokerController(); - - /** - * \brief Receive data from the network. - * \param data if data is received it will put in this reference - * \return number of bytes received or -1 if error - * \note This method will blocked until data comes. - */ - virtual ssize_t Recv(std::string& data); - - /** - * \brief Send data. - * \param data data to send - * \return number of bytes sent or -1 if error - */ - ssize_t Send(const std::string& data); - - /** - * \brief send Json message. - * \param message JSON message. - */ - void sendJsonMessage(Json::Value& message); - - /** - * \brief generates new message id from diapason mControllersIdStart - (mControllersIdStart+999). - * \return next id for message - */ - int getNextMessageId(); - - /** - * \brief generates new message with id, jsonrpc version. - * \param root container for prepared message - */ - void prepareMessage(Json::Value& root); - - /** - * \brief generates new message with id, jsonrpc version. - * \note Doesn't change/add fields id and jsonrpc - * \param errCode error code - * \param errMessage string of message - * \param error container for prepared error message - */ - void prepareErrorMessage(int errCode, std::string errMessage, Json::Value& error); - - /** - * \brief gets destination component name. - * \param root JSON message. - * \return string destination component name. - */ - std::string getDestinationComponentName(Json::Value& root); - - /** - * \brief gets method name. - * \param root JSON message. - * \return string method name. - */ - std::string getMethodName(Json::Value& root); - - /** - * \brief checks is message notification or not. - * \param root JSON message. - * \return true if notification. - */ - bool isNotification(Json::Value& root); - - /** - * \brief checks is message response or not. - * \param root JSON message. - * \return true if response. - */ - bool isResponse(Json::Value& root); - - /** - * \brief searches Method by id in mWaitResponseQueue. - * \param id id of incoming JSON message. - * \return string method name or "" in case not found. - */ - std::string findMethodById(std::string id); - - /** - * \brief register controller on the server. - * \param id message id for JSON message due the id diapason hasn't been received. - */ - void registerController(int id = 0); - - /** - * \brief unregister controller on the server. - */ - void unregisterController(); - - /** - * \brief subscribes controller to the property changing. - * \param property property name in format ComponentName.PropertyName. - */ - void subscribeTo(std::string property); - - /** - * \brief unsubscribes controller from the property changing. - * \param property property name in format ComponentName.PropertyName. - */ - void unsubscribeFrom(std::string property); - - /** - * \brief pure virtual method to process response. - * \param method method name which has been called. - * \param root JSON message. - */ - virtual void processResponse(std::string method, Json::Value& root) = 0; - - /** - * \brief pure virtual method to process request. - * \param root JSON message. - */ - virtual void processRequest(Json::Value& root) = 0; - - /** - * \brief Process notification message. - * \brief Notify subscribers about property change. - * expected notification format example: - * \code - * {"jsonrpc": "2.0", "method": ".", "params": } - * \endcode - * \param root JSON message. - */ - virtual void processNotification(Json::Value& root) = 0; - - /** - * \brief Checks message. - * \param root JSON message. - * \param error JSON message to fill in case of any errors. - * \return true if message is good. - */ - bool checkMessage(Json::Value& root, Json::Value& error); - - /** - * \brief Returns name of Controller. - * \return name of controller. - */ - std::string getControllersName(); - - /** - * \brief Method for receiving thread. - */ - void* MethodForReceiverThread(void * arg); - - virtual void exitReceivingThread() { - Close(); - stop = true; - } - - protected: - /** - * @brief flag top stop thread - */ - sync_primitives::atomic_bool stop; - - private: - /** - * \brief Method for receiving messages without tcp packeting. - * \param message received data - */ - void onMessageReceived(Json::Value message); - /** - * \brief Start value of id's diapason. - */ - std::string m_receivingBuffer; - - /** - * \brief Start value of id's diapason. - */ - int mControllersIdStart; - - /** - * \brief Current id's value. - */ - int mControllersIdCurrent; - - /** - * \brief Already sent messages Methods to recognize esponses: MessageId:MethodName. - */ - std::map mWaitResponseQueue; - - /** - * \brief Name of component. - */ - std::string mControllersName; - - /** - * \brief JSON reader. - */ - Json::Reader m_reader; - - /** - * \brief JSON writer. - */ - Json::FastWriter m_writer; - - /** - * \brief JSON writer. - */ - Json::FastWriter m_receiverWriter; - /* - * @brief mutex for mWaitResponseQueue - */ - sync_primitives::Lock queue_lock_; - }; -} /* namespace NsMessageBroker */ -#endif /* MB_CONTROLLER_H */ diff --git a/src/3rd_party-static/MessageBroker/include/mb_server.hpp b/src/3rd_party-static/MessageBroker/include/mb_server.hpp deleted file mode 100644 index 684a89055a..0000000000 --- a/src/3rd_party-static/MessageBroker/include/mb_server.hpp +++ /dev/null @@ -1,121 +0,0 @@ -/** - * \file mb_server.hpp - * \brief MessageBroker server. - * \author AKara - */ - -#ifndef MB_SERVER_H -#define MB_SERVER_H - -#include "networking.h" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - - /** - * \class Server - * \brief Abstract MessageBroker server. - */ - class Server - { - public: - /** - * \brief Constructor. - * \param address network address or FQDN to bind - * \param port local port to bind - */ - Server(const std::string& address, uint16_t port); - - /** - * \brief Destructor. - */ - virtual ~Server(); - - /** - * \brief Wait message. - * - * This function do a select() on the socket and Process() immediately - * the message. - * \param ms millisecond to wait (0 means infinite) - */ - virtual void WaitMessage(uint32_t ms) = 0; - - /** - * \brief Get socket descriptor. - * \return socket descriptor. - */ - int GetSocket() const; - - /** - * \brief Get the address. - * \return address or FQDN - */ - std::string GetAddress() const; - - /** - * \brief Get the port. - * \return local port - */ - uint16_t GetPort() const; - - /** - * \brief Bind the socket. - * \return true if success, false otherwise - */ - bool Bind(); - - /** - * \brief Receive data from the network and process it. - * \param fd file descriptor on which receive - * \return true if message has been correctly received, processed and - * response sent, false otherwise (mainly send/receive error) - * \note This method will blocked until data comes. - */ - virtual bool Recv(int fd) = 0; - - /** - * \brief Close socket. - * \note It should be overriden for connection-oriented protocol - * like TCP to properly close all client sockets. - */ - virtual void Close(); - - protected: - /** - * \brief Socket descriptor. - */ - int m_sock; - - /** - * \brief Transport protocol of the socket. - */ - enum networking::TransportProtocol m_protocol; - - /** - * \brief Transport protocol of the socket. - */ - - private: - /** - * \brief Network address or FQDN. - */ - std::string m_address; - - /** - * \brief Local port. - */ - uint16_t m_port; - - /** - * \brief Encapsulated format. - */ - }; - -} /* namespace NsMessageBroker */ - -#endif /* MB_SERVER_H */ - diff --git a/src/3rd_party-static/MessageBroker/include/mb_tcpclient.hpp b/src/3rd_party-static/MessageBroker/include/mb_tcpclient.hpp deleted file mode 100644 index 07697dbde7..0000000000 --- a/src/3rd_party-static/MessageBroker/include/mb_tcpclient.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * \file mb_tcpclient.hpp - * \brief MessageBroker TCP client. - * \author AKara - */ - -#ifndef MB_TCPCLIENT_H -#define MB_TCPCLIENT_H - -#include - -#include "mb_client.hpp" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - - /** - * \class TcpClient - * \brief MessageBroker TCP client. - */ - class TcpClient : public Client - { - public: - /** - * \brief Constructor. - * \param address remote network address or FQDN - * \param port remote local port - */ - TcpClient(const std::string& address, uint16_t port); - - /** - * \brief Destructor. - */ - virtual ~TcpClient(); - - /** - * \brief Receive data from the network. - * \param data if data is received it will put in this reference - * \return number of bytes received or -1 if error - * \note This method will blocked until data comes. - */ - virtual ssize_t Recv(std::string& data); - - /** - * \brief Send data. - * \param data data to send - * \return number of bytes sent or -1 if error - */ - ssize_t Send(const std::string& data); - }; - -} /* namespace NsMessageBroker */ - -#endif /* MB_TCPCLIENT_H */ diff --git a/src/3rd_party-static/MessageBroker/include/mb_tcpserver.hpp b/src/3rd_party-static/MessageBroker/include/mb_tcpserver.hpp deleted file mode 100644 index 8ab2ce6a6d..0000000000 --- a/src/3rd_party-static/MessageBroker/include/mb_tcpserver.hpp +++ /dev/null @@ -1,150 +0,0 @@ -/** - * \file mb_tcpserver.hpp - * \brief MessageBroker TCP server. - * \author AKara - */ - -#ifndef MB_TCPSERVER_H -#define MB_TCPSERVER_H - -#include -#include - -#include "mb_server.hpp" -#include "CMessageBroker.hpp" -#include "CSender.hpp" -#include "websocket_handler.hpp" - -#define RECV_BUFFER_LENGTH 4097 -#define MAX_RECV_BUFFER_LENGTH 100000 -#define MAX_RECV_DATA 4096 - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \class TcpServer - * \brief MessageBroker TCP server implementation. - */ - class TcpServer : public Server, public CSender - { - public: - /** - * \brief Constructor. - * \param address network address or FQDN to bind - * \param port local port to bind - * \param pMessageBroker pointer to MessageBroker - */ - TcpServer(const std::string& address, uint16_t port, NsMessageBroker::CMessageBroker* pMessageBroker); - - /** - * \brief Destructor. - */ - virtual ~TcpServer(); - - /** - * \brief Receive data from the network and process it. - * \param fd socket descriptor to receive data - * \return true if message has been correctly received, processed and - * response sent, false otherwise (mainly send/recv error) - * \note This method will blocked until data comes. - */ - virtual bool Recv(int fd); - - /** - * \brief Send data. - * \param fd file descriptor of the client TCP socket - * \param data data to send - * \return number of bytes sent or -1 if error - */ - virtual ssize_t Send(int fd, const std::string& data); - - /** - * \brief Wait message. - * - * This function do a select() on the socket and Process() immediately - * the message. - * \param ms millisecond to wait (0 means infinite) - */ - virtual void WaitMessage(uint32_t ms); - - /** - * \brief Put the TCP socket in LISTEN state. - */ - bool Listen() const; - - /** - * \brief Accept a new client socket. - * \return -1 if error, 0 otherwise - */ - bool Accept(); - - /** - * \brief Close listen socket and all client sockets. - */ - void Close(); - - /** - * \brief Method for thread with WaitMessage. - */ - void* MethodForThread(void * arg); - - private: - /** - * \brief Checks if incoming messages are websocket request. - * \param fd - * \param pReceivingBuffer string receiving buffer pointer - * \return true if it is a websocket handshake - */ - bool checkWebSocketHandShake(int fd, std::string* pReceivingBuffer); - - /** - * \brief Checks if incoming messages are websocket request. - * \param fd file descriptor of the client TCP socket - * \return true if it is a websocket - */ - bool isWebSocket(int fd); - - /** - * \brief Gets buffer for socket which received data. - * \param fd socket file descriptor - */ - std::string* getBufferFor(int fd); - private: - /** - * \brief WebSocket clients fd's list. - */ - std::list m_WebSocketClients; - - /** - * \brief Just accepted clients fd's list. - */ - std::list m_AcceptedClients; - - /** - * \brief Receiving buffers map SocketFd:bufferPointer. - */ - std::map m_receivingBuffers; - - /** - * \brief List of disconnected sockets to be purged. - */ - std::list m_purge; - - /** - * \brief MessageBroker pointer. - */ - NsMessageBroker::CMessageBroker* mpMessageBroker; - - /** - * \brief WebSocket handler. - */ - CWebSocketHandler mWebSocketHandler; - }; - -} /* namespace NsMessageBroker */ - -#endif /* MB_TCPSERVER_H */ diff --git a/src/3rd_party-static/MessageBroker/include/networking.h b/src/3rd_party-static/MessageBroker/include/networking.h deleted file mode 100644 index a08853bb31..0000000000 --- a/src/3rd_party-static/MessageBroker/include/networking.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * JsonRpc-Cpp - JSON-RPC implementation. - * Copyright (C) 2008-2011 Sebastien Vincent - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/** - * \file networking.h - * \brief Networking utils. - * \author Sebastien Vincent - */ - -#ifndef NETWORKING_H -#define NETWORKING_H - -#ifdef _WIN32 - -#ifndef _MSC_VER -#include -#endif //_MSC_VER - -#include -#include - -#if _MSC_VER >= 1400 // VC++ 8.0 -typedef unsigned short uint16_t; -typedef unsigned long uint32_t; -#define snprintf _snprintf -#endif //_MSC_VER >= 1400 - -/* to use getaddrinfo, _WIN32_WINNT have to - * equal at least 0x0501 - */ -#define OLD_WIN32_WINNT _WIN32_WINNT - -#if (_WIN32_WINNT < 0x0501) -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x501 -#endif //(_WIN32_WINNT < 0x0501) - -#include - -#if (_WIN32_WINNT != OLD_WIN32_WINNT) -#undef _WIN32_WINNT -#define _WIN32_WINNT OLD_WIN32_WINNT -#endif //(_WIN32_WINNT != OLD_WIN32_WINNT) - -typedef int socklen_t; -#define close closesocket - -#else //_WIN32 - -#include - -#include -#include -#include - -#include - -#include - -#include - -#endif //_WIN32 - -#include - -/** - * \namespace networking - * \brief Networking related functions. - */ -namespace networking -{ - /** - * \enum TransportProtocol - * \brief Transport protocol. - */ - enum TransportProtocol - { - UDP = IPPROTO_UDP, /**< UDP protocol. */ - TCP = IPPROTO_TCP /**< TCP protocol. */ - }; - - /** - * \brief Initialize networking. - * \return true if network is correctly initialized, false otherwise - * \note On MS Windows, this step is mandatory to use - * socket API (socket(), bind(), recvfrom(), ...). - */ - bool init(); - - /** - * \brief Cleanup networking. - * \note On MS Windows, after calling this function, - * it will be impossible to use socket API. - */ - void cleanup(); - - /** - * \brief Connect to remote machine. - * \param protocol transport protocol used - * \param address remote address - * \param port remote port - * \param sockaddr if function succeed, sockaddr - * representation of address/port - * \param addrlen if function succeed, length of sockaddr - * \return socket descriptor if success, -1 otherwise - */ - int connect(enum TransportProtocol protocol, const std::string& address, uint16_t port, struct sockaddr_storage* sockaddr, socklen_t* addrlen); - - /** - * \brief Bind on a local address. - * \param protocol transport protocol used - * \param address local address - * \param port local port - * \param sockaddr if function succeed, sockaddr - * representation of address/port - * \param addrlen if function succeed, length of sockaddr - * \return socket descriptor if success, -1 otherwise - */ - int bind(enum TransportProtocol protocol, const std::string& address, uint16_t port, struct sockaddr_storage* sockaddr, socklen_t* addrlen); - -} /* namespace networking */ - -#endif /* NETWORKING_H */ - diff --git a/src/3rd_party-static/MessageBroker/include/system.h b/src/3rd_party-static/MessageBroker/include/system.h deleted file mode 100644 index fac4f7926b..0000000000 --- a/src/3rd_party-static/MessageBroker/include/system.h +++ /dev/null @@ -1,320 +0,0 @@ -/** - * \file system.h - * \brief System utils. - * \author Sebastien Vincent - */ - -#ifndef SYSTEM_H -#define SYSTEM_H - -#ifdef _WIN32 - -#include - -#else - -#include - -#endif - -/** - * \namespace System - * \brief System related class (thread, ...). - */ -namespace System -{ - - /** - * \brief Sleep for x milliseconds - * \param ms millisecond to sleep - */ - void msleep(unsigned long ms); - - /** - * \class ThreadArg - * \brief Abstract class to represent thread argument. - * \see ThreadArgImpl - * \see Thread - */ - class ThreadArg - { - public: - /** - * \brief Destructor. - */ - virtual ~ThreadArg(); - - /** - * \brief Call the method. - * \note Have to be implemented by subclasses - */ - virtual void* Call() = 0; - }; - - /** - * \class ThreadArgImpl - * \brief Template class that represent thread argument. - * - * This class is used to provide callback function within - * an object. The method which will be called during thread - * execution must be of the form void* MyMethod(void* arg). - * Inside this method you are free to called any method of the object. - * - * \warning As class keep pointer of object reference, you should take - * care at the lifetime of object you pass in ThreadArgImpl constructor, - * else it could lead to crash your program.\n See Thread class documentation - * for an example of how to use ThreadArgImpl class. - * \see Thread - */ - template class ThreadArgImpl : public ThreadArg - { - public: - /** - * \typedef Method - * \brief T method signature. - */ - typedef void* (T::*Method)(void*); - - /** - * \brief Constructor. - * \param obj object - * \param method class method - * \param arg argument to method - */ - ThreadArgImpl(T& obj, Method method, void* arg) - { - m_obj = &obj; - m_method = method; - m_arg = arg; - } - - /** - * \brief Call the method. - */ - virtual void* Call() - { - return (m_obj->*m_method)(m_arg); - } - - private: - /** - * \brief Object pointer. - */ - T* m_obj; - - /** - * \brief Method of T class. - */ - Method m_method; - - /** - * \brief Argument of method. - */ - void* m_arg; - }; - - /** - * \class Thread - * \brief Thread implementation. - * - * Preferred use of this class is to construct ThreadArgImpl inside - * another class and pass *this as obj parameter:\n - * \n - * \code - * class MyClass - * { - * public: - * void MyMethod() - * { - * ThreadArg* arg = new ThreadArgImpl(*this, &MyClass::MethodForThread, NULL); - * Thread th(arg); - * th.Start(); - * } - * - * void* MethodForThread(void * arg) - * { - * // do stuff - * } - * }; - * \endcode - * - */ - class Thread - { - public: - /** - * \brief Constructor. - * \param arg thread argument (MUST be dynamically allocated using new) - * \note System::Thread object takes care of freeing method memory.\n - * The way of calling constructor is: - * - * Thread thread(new ThreadArgImpl(instanceOfMyClass, &MyClass::Method)); - * - * \warning You should take care of the object (instanceOfMyClass) lifetime pass - * into ThreadArgImpl constructor, else it could lead to a crash because ThreadArgImpl - * keep pointer of the reference. - * \warning The "arg" parameter MUST be dynamically allocated (using new). - * \see ThreadArgImpl - */ - Thread(ThreadArg* arg); - - /** - * \brief Destructor. - */ - virtual ~Thread(); - - /** - * \brief Start thread. - * \param detach if set to true, the thread will be in detach state so - * you do not have to call join on this type of thread. - * \return true if success, false otherwise - * \warning Do NOT Join a detached thread. - */ - bool Start(bool detach); - - /** - * \brief Stop thread. - * \return true if success, false otherwise - * \warning Calling this method could lead callback object to an - * incoherent state. You should call it really in desperate situations when - * you really want to stop thread and do not care about the rest. - * \warning With POSIX thread implementation, calling Stop (one or more times) - * will leak 28 bytes of memory. - */ - bool Stop(); - - /** - * \brief Join thread. - * \param ret pointer to return code of the joined thread - * \return true if success, false otherwise - * \warning Do NOT Join a detached thread. - */ - bool Join(void** ret = NULL); - -#ifdef _WIN32 - HANDLE -#else - pthread_t -#endif - GetId() const { - return m_id; - } - - private: - /** - * \brief Entry point of thread before calling specific - * callback. - * \param arg thread argument - * \return result of ThreadArg callback - */ -#ifdef _WIN32 - static DWORD WINAPI Call(LPVOID arg); -#else - static void* Call(void* arg); -#endif - /** - * \brief Thread identifier. - */ -#ifdef _WIN32 /* Win32 thread */ - HANDLE m_id; -#else /* POSIX thread */ - pthread_t m_id; -#endif - - /** - * \brief Thread argument. - */ - ThreadArg* m_arg; - }; - - /** - * \class Mutex - * \brief Mutex implementation. - */ - class Mutex - { - public: - /** - * \brief Constructor. - */ - Mutex(); - - /** - * \brief Destructor. - */ - ~Mutex(); - - /** - * \brief Lock the mutex. - * \return true if mutex is locked, false if error - */ - bool Lock(); - - /** - * \brief Unlock the mutex. - * \return true if mutex is unlocked, false if error - */ - bool Unlock(); - - private: - /** - * \brief The mutex. - */ -#ifdef _WIN32 - HANDLE m_mutex; -#else - pthread_mutex_t m_mutex; -#endif - }; - -#ifdef _WIN32 -#warning "BinarySemaphore is implemented for POSIX systems only" -#else - /** - * \class BinarySemaphore - * \brief Binary semaphore implementation. - */ - class BinarySemaphore { - public: - /** - * \brief Constructor. - */ - BinarySemaphore(); - - /** - * \brief Destructor. - */ - ~BinarySemaphore(); - - /** - * \brief Wait until the semaphore is unlocked. - */ - void Wait(); - - /** - * \brief Notify the semaphore. - */ - void Notify(); - - private: - /** - * \brief Mutex to prevent concurrent access to the flag. - */ - pthread_mutex_t m_mutex; - - /** - * \brief Conditional variable to block threads. - */ - pthread_cond_t m_cond; - - /** - * \brief Semaphore state: false = down, true = up. - */ - bool m_isUp; - }; -#endif /* _WIN32 */ - -} /* namespace System */ - -#endif /* SYSTEM_H */ - diff --git a/src/3rd_party-static/MessageBroker/include/websocket_handler.hpp b/src/3rd_party-static/MessageBroker/include/websocket_handler.hpp deleted file mode 100644 index 8bed007436..0000000000 --- a/src/3rd_party-static/MessageBroker/include/websocket_handler.hpp +++ /dev/null @@ -1,226 +0,0 @@ -/** - * \file websocket_handler.hpp - * \brief WebSocket Handler. - * Supports RFC6455 standard of protocol - * Protocol specification: - * http://tools.ietf.org/html/rfc6455 - * \author AKara - */ - -#ifndef WEBSOCKET_HANDLER_H -#define WEBSOCKET_HANDLER_H - -#include -#include -#include - -#define MAX_WEBSOCKET_04_KEY_LEN 128 /**< Max WS key length */ - -#define K(t) _K[(t) / 20] /**< K(t) */ -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) /**< F0(b, c, d) */ -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) /**< F1(b, c, d) */ -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) /**< F2(b, c, d) */ -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) /**< F3(b, c, d) */ - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) /**< S(n, x) */ -#define H(n) (ctxt->h.b32[(n)]) /**< H(n) */ -#define COUNT (ctxt->count) /**< COUNT */ -#define W(n) (ctxt->m.b32[(n)]) /**< W(n) */ - -#define PUTPAD(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } /**< PUTPAD(x) */ - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \brief sha1_ctxt txt structure. - */ - struct sha1_ctxt - { - union { - unsigned char b8[20]; - unsigned int b32[5]; - } h; /**< h */ - union { - unsigned char b8[8]; - unsigned long long b64[1]; - } c; /**< c */ - union { - unsigned char b8[64]; - unsigned int b32[16]; - } m; /**< m */ - unsigned char count; /**< count */ - }; - - - /** - * \brief Constant table. - */ - const unsigned int _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; - - /** - * \brief Constant table. - */ - const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789+/"; - - /** - * \brief Constant table. - */ - const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" - "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; - - /** - * \brief Type to present raw bytes. - */ - typedef std::vector rawBytes; - - - /** - * \class CWebSocketHandler - * \brief WebSocket messages handler. - */ - class CWebSocketHandler - { - public: - /** - * \brief Constructor. - */ - CWebSocketHandler() - { - } - - /** - * \brief Destructor. - */ - ~CWebSocketHandler() - { - } - - /** - * \brief Generates Sec-WebSocket-Accept key - * \param key Sec-WebSocket-Key from client - */ - void handshake_0405(std::string &key); - - /** - * \brief Generates accept key for older (hybi-00) WebSocket protocol version. - * \param key1 The first key of the client's handshake (a string) - * \param key2 The second key of the client's handshake (a string) - * \param key3 The third key of the client's handshake (raw bytes), must be 8 bytes long - * \return Raw bytes of the generated accept key, or no bytes if error - */ - rawBytes handshake_hybi00(const std::string &key1, const std::string &key2, const rawBytes &key3); - - /** - * \brief Parses WebSocket data header to retrieve packet size - * \param Buffer input buffer - * \param b_size buffer size - * \return Packet size - */ - unsigned int parseWebSocketDataLength(const char* Buffer, unsigned int& b_size); - - /** - * \brief Parses WebSocket data - * \param Buffer input buffer - * \param b_size buffer size - * \return -1 in case of issues, data length in case of success - */ - int parseWebSocketData(char* Buffer, unsigned int& b_size); - - /** - * \brief Prepares WebSocket data - * \param Buffer input buffer - * \param b_size buffer size - * \return -1 in case of issues, data length in case of success - */ - int prepareWebSocketDataHeader(unsigned char* Buffer, unsigned long long b_size); - private: - /** - * \brief SHA1 hash calculator. - * \param d input buffer - * \param n size of buffer - * \param md mask buffer - * \return pointer to result - */ - unsigned char * SHA1(const unsigned char *d, size_t n, unsigned char *md); - - /** - * \brief base 64 encode string. - * \param in input buffer - * \param in_len size of buffer - * \param out output buffer - * \param out_size size of buffer - * \return -1 in case of errors - */ - int lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); - - /** - * \brief base 64 decode string. - * \param in input buffer - * \param out output buffer - * \param out_size size of buffer - * \return -1 in case of errors - */ - int lws_b64_decode_string(const char *in, char *out, int out_size); - - /** - * \brief one step of SHA1. - * \param ctxt input txt structure - */ - void sha1_step(struct sha1_ctxt *ctxt); - - /** - * \brief init step of SHA1. - * \param ctxt input txt structure - */ - void sha1_init(struct sha1_ctxt *ctxt); - - /** - * \brief pad step of SHA1. - * \param ctxt input txt structure - */ - void sha1_pad(struct sha1_ctxt *ctxt); - - /** - * \brief loop step of SHA1. - * \param ctxt input txt structure - * \param input input buffer buffer - * \param len length of input buffer - */ - void sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len); - - /** - * \brief result step of SHA1. - * \param ctxt input txt structure - * \param digest0 buffer - */ - void sha1_result(struct sha1_ctxt *ctxt, unsigned char* digest0); - - /** - * \brief base 64 test. - * \return -1 in case of errors - */ - int lws_b64_selftest(void); - - /** - * \brief Extracts and processes the number from key, - * according to the WebSocket hybi-00 specification. - * \param key Key to extract the number from - * \return The number, or 0 if error - */ - unsigned long extractNumber(const std::string &key) const; - }; - -} /* namespace NsMessageBroker */ - -#endif /* WEBSOCKET_HANDLER_H */ diff --git a/src/3rd_party-static/MessageBroker/src/client/mb_client.cpp b/src/3rd_party-static/MessageBroker/src/client/mb_client.cpp deleted file mode 100644 index 6342c776a8..0000000000 --- a/src/3rd_party-static/MessageBroker/src/client/mb_client.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/** - * \file mb_client.cpp - * \brief MessageBroker client. - * \author AKara - */ - -#include - -#include "mb_client.hpp" - -namespace NsMessageBroker -{ - - Client::Client() - { - } - - Client::Client(const std::string& address, uint16_t port) - { - m_sock = -1; - m_address = address; - m_port = port; - memset(&m_sockaddr, 0x00, sizeof(struct sockaddr_storage)); - m_sockaddrlen = 0; - } - - Client::~Client() - { - if(m_sock != -1) - { - Close(); - } - } - - int Client::GetSocket() const - { - return m_sock; - } - - std::string Client::GetAddress() const - { - return m_address; - } - - void Client::SetAddress(const std::string& address) - { - m_address = address; - } - - void Client::SetPort(uint16_t port) - { - m_port = port; - } - - uint16_t Client::GetPort() const - { - return m_port; - } - - bool Client::Connect() - { - m_sock = networking::connect(m_protocol, GetAddress(), GetPort(), &m_sockaddr, &m_sockaddrlen); - - return (m_sock != -1) ? true : false; - } - - void Client::Close() - { - shutdown(m_sock, SHUT_RDWR); - - close(m_sock); - m_sock = -1; - } - -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/client/mb_controller.cpp b/src/3rd_party-static/MessageBroker/src/client/mb_controller.cpp deleted file mode 100644 index 8a4a77cf30..0000000000 --- a/src/3rd_party-static/MessageBroker/src/client/mb_controller.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/** - * \file mb_controller.cpp - * \brief MessageBroker Controller. - * \author AKara - */ - -#include "mb_controller.hpp" - -#include "MBDebugHelper.h" -#include "CMessageBroker.hpp" - -namespace NsMessageBroker -{ - CMessageBrokerController::CMessageBrokerController(const std::string& address, uint16_t port, std::string name): - TcpClient(address, port), - stop(false), - m_receivingBuffer(""), - mControllersIdStart(-1), - mControllersIdCurrent(0) - { - mControllersName = name; - } - - std::string CMessageBrokerController::getControllersName() - { - return mControllersName; - } - - CMessageBrokerController::~CMessageBrokerController() - { - } - - ssize_t CMessageBrokerController::Recv(std::string& data) - { - DBG_MSG(("CMessageBrokerController::Recv()\n")); - ssize_t recv = TcpClient::Recv(data); - DBG_MSG(("Received message: %s\n", data.c_str())); - m_receivingBuffer += data; - while (!stop) - { - Json::Value root; - if (!m_reader.parse(m_receivingBuffer, root)) - { - DBG_MSG(("Received not JSON string! %s\n", m_receivingBuffer.c_str())); - return recv; - } - std::string wmes = m_receiverWriter.write(root); - DBG_MSG(("Parsed JSON string:%s; length: %d\n", wmes.c_str(), wmes.length())); - DBG_MSG(("Buffer is:%s\n", m_receivingBuffer.c_str())); - ssize_t beginpos = m_receivingBuffer.find(wmes); - if (-1 != beginpos) - { - m_receivingBuffer.erase(0, beginpos + wmes.length()); - DBG_MSG(("Buffer after cut is:%s\n", m_receivingBuffer.c_str())); - } else - { - m_receivingBuffer.clear(); - } - onMessageReceived(root); - } - return recv; - } - - void CMessageBrokerController::onMessageReceived(Json::Value message) - { - // Determine message type and process... - Json::Value error; - if (checkMessage(message, error)) - { - if (isNotification(message)) - { - DBG_MSG(("Message is notification!\n")); - processNotification(message); - } else if (isResponse(message)) - { - std::string id = message["id"].asString(); - std::string method = findMethodById(id); - DBG_MSG(("Message is response on: %s\n", method.c_str())); - if ("" != method) - { - if ("MB.registerComponent" == method) - { // initialize mControllersIdStart - if (message.isMember("result") && message["result"].isInt()) - { - mControllersIdStart = message["result"].asInt(); - } else - { - DBG_MSG_ERROR(("Not possible to initialize mControllersIdStart!\n")); - } - } else if ("MB.subscribeTo" == method || "MB.unregisterComponent" == method || "MB.unsubscribeFrom" == method) - { - //nothing to do for now - } else - { - processResponse(method, message); - } - } else - { - DBG_MSG_ERROR(("Request with id %s has not been found!\n", id.c_str())); - } - } else - { - DBG_MSG(("Message is request!\n")); - processRequest(message); - } - } else - { - DBG_MSG_ERROR(("Message contains wrong data!\n")); - } - } - - ssize_t CMessageBrokerController::Send(const std::string& data) - { - return TcpClient::Send(data); - } - - void CMessageBrokerController::sendJsonMessage(Json::Value& message) - { - DBG_MSG(("CMessageBrokerController::sendJsonMessage()\n")); - sync_primitives::AutoLock auto_lock(queue_lock_); - std::string mes = m_writer.write(message); - if (!isNotification(message) && !isResponse(message)) - {// not notification, not a response, store id and method name to recognize an answer - mWaitResponseQueue.insert(std::map::value_type(message["id"].asString(), message["method"].asString())); - } - int bytesSent = Send(mes); - bytesSent = bytesSent; // to prevent compiler warnings in case DBG_MSG off - DBG_MSG(("Length:%d, Sent: %d bytes\n", mes.length(), bytesSent)); - } - - std::string CMessageBrokerController::findMethodById(std::string id) - { - DBG_MSG(("CMessageBrokerController::findMethodById()\n")); - sync_primitives::AutoLock auto_lock(queue_lock_); - std::string res = ""; - std::map ::iterator it; - it = mWaitResponseQueue.find(id); - if (it != mWaitResponseQueue.end()) - { - res = (*it).second; - mWaitResponseQueue.erase(it); - } - return res; - } - - int CMessageBrokerController::getNextMessageId() - { - if (mControllersIdCurrent < (mControllersIdStart+1000)) - { - return mControllersIdCurrent++; - } else - { - return mControllersIdCurrent = mControllersIdStart; - } - } - - void CMessageBrokerController::prepareMessage(Json::Value& root) - { - root["jsonrpc"] = "2.0"; - root["id"] = getNextMessageId(); - } - - void CMessageBrokerController::prepareErrorMessage(int errCode, std::string errMessage, Json::Value& error) - { - DBG_MSG(("CMessageBrokerController::prepareErrorMessage()\n")); - Json::Value err; - err["code"] = errCode; - err["message"] = errMessage; - error["error"] = err; - } - - std::string CMessageBrokerController::getDestinationComponentName(Json::Value& root) - { - DBG_MSG(("CMessageBrokerController::getDestinationComponentName()\n")); - std::string ret = ""; - std::string method = root["method"].asString(); - int pos = method.find("."); - if (-1 != pos) - { - ret = method.substr(0, pos); - } - DBG_MSG(("Destination component is: %s\n", ret.c_str())); - return ret; - } - - std::string CMessageBrokerController::getMethodName(Json::Value& root) - { - DBG_MSG(("CMessageBrokerController::getMethodName()\n")); - std::string ret = ""; - std::string method = root["method"].asString(); - int pos = method.find("."); - if (-1 != pos) - { - ret = method.substr(pos+1); - } - DBG_MSG(("Method is: %s\n", ret.c_str())); - return ret; - } - - bool CMessageBrokerController::isNotification(Json::Value& root) - { - DBG_MSG(("CMessageBrokerController::isNotification()\n")); - bool ret = false; - if (false == root.isMember("id")) - { - ret = true; - } - DBG_MSG(("Result: %d\n", ret)); - return ret; - } - - bool CMessageBrokerController::isResponse(Json::Value& root) - { - DBG_MSG(("CMessageBrokerController::isResponse()\n")); - bool ret = false; - if ((true == root.isMember("result")) || (true == root.isMember("error"))) - { - ret = true; - } - DBG_MSG(("Result: %d\n", ret)); - return ret; - } - - void CMessageBrokerController::registerController(int id) - { - DBG_MSG(("CMessageBrokerController::registerController()\n")); - Json::Value root; - Json::Value params; - prepareMessage(root); - root["id"] = id; - root["method"] = "MB.registerComponent"; - params["componentName"] = mControllersName; - root["params"] = params; - sendJsonMessage(root); - } - - void CMessageBrokerController::unregisterController() - { - DBG_MSG(("CMessageBrokerController::unregisterController()\n")); - Json::Value root; - Json::Value params; - prepareMessage(root); - root["method"] = "MB.unregisterComponent"; - params["componentName"] = mControllersName; - root["params"] = params; - sendJsonMessage(root); - } - - void CMessageBrokerController::subscribeTo(std::string property) - { - DBG_MSG(("CMessageBrokerController::subscribeTo()\n")); - Json::Value root; - Json::Value params; - prepareMessage(root); - root["method"] = "MB.subscribeTo"; - params["propertyName"] = property; - root["params"] = params; - sendJsonMessage(root); - } - - void CMessageBrokerController::unsubscribeFrom(std::string property) - { - DBG_MSG(("CMessageBrokerController::unsubscribeFrom()\n")); - Json::Value root; - Json::Value params; - prepareMessage(root); - root["method"] = "MB.unsubscribeFrom"; - params["propertyName"] = property; - root["params"] = params; - sendJsonMessage(root); - } - - void* CMessageBrokerController::MethodForReceiverThread(void * arg) - { - stop = false; - arg = arg; // to avoid compiler warnings - while(!stop) - { - std::string data = ""; - Recv(data); - } - return NULL; - } - - bool CMessageBrokerController::checkMessage(Json::Value& root, Json::Value& error) - { - DBG_MSG(("CMessageBrokerController::checkMessage()\n")); - Json::Value err; - - try - { - /* check the JSON-RPC version => 2.0 */ - if (!root.isObject() || !root.isMember("jsonrpc") || root["jsonrpc"] != "2.0") - { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = NsMessageBroker::INVALID_REQUEST; - err["message"] = "Invalid MessageBroker request."; - error["error"] = err; - return false; - } - - if (root.isMember("id") && (root["id"].isArray() || root["id"].isObject())) - { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = NsMessageBroker::INVALID_REQUEST; - err["message"] = "Invalid MessageBroker request."; - error["error"] = err; - return false; - } - - if (root.isMember("result") && root.isMember("error")) - { - /* message can't contain simultaneously result and error*/ - return false; - } - - if (root.isMember("method")) - { - if (!root["method"].isString()) - { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = NsMessageBroker::INVALID_REQUEST; - err["message"] = "Invalid MessageBroker request."; - error["error"] = err; - return false; - } - /* Check the params is an object*/ - if (root.isMember("params") && !root["params"].isObject()) - { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Invalid JSONRPC params."; - error["error"] = err; - return false; - } - } else if (!root.isMember("result") && !root.isMember("error")) - { - return false; - } - return true; - } catch (...) - { - DBG_MSG_ERROR(("CMessageBrokerController::checkMessage() EXCEPTION has been caught!\n")); - return false; - } - } - -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/client/mb_tcpclient.cpp b/src/3rd_party-static/MessageBroker/src/client/mb_tcpclient.cpp deleted file mode 100644 index 02db417c26..0000000000 --- a/src/3rd_party-static/MessageBroker/src/client/mb_tcpclient.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/** - * \file mb_tcpclient.cpp - * \brief MessageBroker TCP client. - * \author AKara - */ - -#include "mb_tcpclient.hpp" -#include "MBDebugHelper.h" - -namespace NsMessageBroker -{ - - TcpClient::TcpClient(const std::string& address, uint16_t port) : Client(address, port) - { - m_protocol = networking::TCP; - } - - TcpClient::~TcpClient() - { - } - - ssize_t TcpClient::Send(const std::string& data) - { - std::string rep = data; - int bytesToSend = rep.length(); - const char* ptrBuffer = rep.c_str(); - do - { - int retVal = send(m_sock, ptrBuffer, bytesToSend, 0); - if(retVal == -1) - { - return -1; - } - bytesToSend -= retVal; - ptrBuffer += retVal; - }while(bytesToSend > 0); - return rep.length(); - } - - ssize_t TcpClient::Recv(std::string& data) - { - char buf[1500]; - ssize_t nb = -1; - - if((nb = ::recv(m_sock, buf, sizeof(buf), 0)) == -1) - { - std::cerr << "Error while receiving" << std::endl; - return -1; - } - - data = std::string(buf, nb); - DBG_MSG(("Received from server: %s\n", data.c_str())); - - return nb; - } - -} /* namespace NsMessageBroker */ - diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.cpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.cpp deleted file mode 100644 index 77ab1ca2c1..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * \file MessageBrokerControllerAVA.cpp - * \brief MessageBroker Controller for Avatar. - * \author AKara - */ - -#include - -#include "MessageBrokerControllerAVA.hpp" - -#include "MBDebugHelper.h" - -extern int start; - -namespace NsMessageBroker -{ - CMessageBrokerControllerAVA::CMessageBrokerControllerAVA(const std::string& address, uint16_t port): - CMessageBrokerController(address, port, "AVA") - { - } - - CMessageBrokerControllerAVA::~CMessageBrokerControllerAVA() - { - } - - void CMessageBrokerControllerAVA::processRequest(Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerAVA::processRequest()\n")); - root=root;//to prevent compiler warning - } - - void CMessageBrokerControllerAVA::processNotification(Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerAVA::processNotification()\n")); - root=root;//to prevent compiler warning - } - - void CMessageBrokerControllerAVA::processResponse(std::string method, Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerAVA::processResponse()\n")); - DWORD stop = GetTickCount(); - int diff = stop - start; - std::string id = root["id"].asString(); - printf("Execution time for id %s is %d ms!\n", id.c_str(), diff); - root=root;//to prevent compiler warning - method=method;//to prevent compiler warning - } - - void CMessageBrokerControllerAVA::makeCall(std::string phoneNumber) - { - DBG_MSG(("CMessageBrokerControllerAVA::makeCall()\n")); - Json::Value request, params; - prepareMessage(request); - request["method"] = "Phone.makeCall"; - params["phoneNumber"] = phoneNumber; - request["params"] = params; - sendJsonMessage(request); - } -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.hpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.hpp deleted file mode 100644 index 47e684a7e4..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerAVA.hpp +++ /dev/null @@ -1,68 +0,0 @@ -/** - * \file MessageBrokerControllerAVA.hpp - * \brief MessageBroker Controller AVA. - * \author AKara - */ - -#ifndef MB_CONTROLLERAVA_H -#define MB_CONTROLLERAVA_H - -#include - -#include "json/json.h" - -#include "mb_controller.hpp" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \class CMessageBrokerControllerAVA - * \brief MessageBroker Controller. - */ - class CMessageBrokerControllerAVA : public CMessageBrokerController - { - public: - /** - * \brief Constructor. - * \param address remote network address or FQDN - * \param port remote local port - */ - CMessageBrokerControllerAVA(const std::string& address, uint16_t port); - - /** - * \brief Destructor. - */ - ~CMessageBrokerControllerAVA(); - - /** - * \brief process request. - * \param root JSON message. - */ - void processRequest(Json::Value& root); - - /** - * \brief process notification. - * \param root JSON message. - */ - void processNotification(Json::Value& root); - - /** - * \brief process response. - * \param method method name which has been called. - * \param root JSON message. - */ - void processResponse(std::string method, Json::Value& root); - - /** - * \brief sends message to the phone to make call. - * \param phoneNumber number for call. - */ - void makeCall(std::string phoneNumber); - - }; -}/* namespace NsMessageBroker */ -#endif /* MB_CONTROLLERAVA_H */ \ No newline at end of file diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.cpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.cpp deleted file mode 100644 index cbbe39492b..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/** - * \file MessageBrokerControllerBackend.cpp - * \brief MessageBroker Controller for Backend. - * \author AKara - */ - -#include "MessageBrokerControllerBackend.hpp" - -#include "MBDebugHelper.h" - -namespace NsMessageBroker -{ - CMessageBrokerControllerBackend::CMessageBrokerControllerBackend(const std::string& address, unsigned short port): -CMessageBrokerController(address, port, std::string("Backend")) - { - } - - CMessageBrokerControllerBackend::~CMessageBrokerControllerBackend() - { - } - - void CMessageBrokerControllerBackend::processRequest(Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerBackend::processRequest()\n")); - if (getControllersName() == getDestinationComponentName(root)) - { - Json::Value response; - response["jsonrpc"] = root["jsonrpc"]; - response["id"] = root["id"]; - if ("isFirstStart" == getMethodName(root)) - { - isFirstStart(response); - } else if ("isFullScreen" == getMethodName(root)) - { - isFullScreen(response); - } else if ("getWindowSize" == getMethodName(root)) - { - getWindowSize(response); - } else if ("getWindowDensity" == getMethodName(root)) - { - getWindowDensity(response); - } else if ("getOSInfo" == getMethodName(root)) - { - getOSInfo(response); - } else if ("logToOS" == getMethodName(root)) - { - logToOS(response); - } else - { - DBG_MSG_ERROR(("Method has not been found!\n")); - Json::Value err; - err["code"] = NsMessageBroker::INVALID_REQUEST; - err["message"] = "Method has not been found."; - response["error"] = err; - } - sendJsonMessage(response); - } else - { - DBG_MSG_ERROR(("Wrong message destination!\n")); - } - } - - void CMessageBrokerControllerBackend::processNotification(Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerBackend::processNotification()\n")); - root=root;//to prevent compiler warning - } - - void CMessageBrokerControllerBackend::processResponse(std::string method, Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerBackend::processResponse()\n")); - root=root;//to prevent compiler warning - method=method;//to prevent compiler warning - } - - void CMessageBrokerControllerBackend::isFirstStart(Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerBackend::isFirstStart()\n")); - Json::Value res; - res["isFirstStart"] = false; - response["result"] = res; - } - - void CMessageBrokerControllerBackend::isFullScreen(Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerBackend::isFullScreen()\n")); - Json::Value res; - res["isFullScreen"] = false; - response["result"] = res; - } - - void CMessageBrokerControllerBackend::getWindowSize(Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerBackend::getWindowSize()\n")); - Json::Value res; - res["width"] = 800; - res["height"] = 480; - response["result"] = res; - } - - void CMessageBrokerControllerBackend::getWindowDensity(Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerBackend::getWindowDensity()\n")); - Json::Value res; - res["windowDensity"] = 1; - response["result"] = res; - } - - void CMessageBrokerControllerBackend::getOSInfo(Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerBackend::getOSInfo()\n")); - Json::Value res; - res["osType"] = ""; - res["osVersion"] = ""; - res["isNativeApplication"] = true; - response["result"] = res; - } - - void CMessageBrokerControllerBackend::logToOS(Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerBackend::logToOS()\n")); - response["result"] = ""; - } - -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.hpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.hpp deleted file mode 100644 index b79411dc98..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerBackend.hpp +++ /dev/null @@ -1,96 +0,0 @@ -/** - * \file MessageBrokerControllerBackend.hpp - * \brief MessageBroker Controller Backend. - * \author AKara - */ -#pragma once - -#include - -#include "json/json.h" - -#include "mb_controller.hpp" -#include "CMessageBroker.hpp" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \class CMessageBrokerControllerBackend - * \brief MessageBroker Controller. - */ - - class CMessageBrokerControllerBackend : public CMessageBrokerController - { - public: - /** - * \brief Constructor. - * \param address remote network address or FQDN - * \param port remote local port - */ - CMessageBrokerControllerBackend(const std::string& address, unsigned short port); - - /** - * \brief Destructor. - */ - ~CMessageBrokerControllerBackend(); - - /** - * \brief process request. - * \param root JSON message. - */ - void processRequest(Json::Value& root); - - /** - * \brief process notification. - * \param root JSON message. - */ - void processNotification(Json::Value& root); - - /** - * \brief process response. - * \param method method name which has been called. - * \param root JSON message. - */ - void processResponse(std::string method, Json::Value& root); - private: - /** - * \brief Checks first start. - * \param response container for response - */ - void isFirstStart(Json::Value& response); - - /** - * \brief Checks first start. - * \param response container for response - */ - void isFullScreen(Json::Value& response); - - /** - * \brief Checks first start. - * \param response container for response - */ - void getWindowSize(Json::Value& response); - - /** - * \brief Checks first start. - * \param response container for response - */ - void getWindowDensity(Json::Value& response); - - /** - * \brief Checks first start. - * \param response container for response - */ - void getOSInfo(Json::Value& response); - - /** - * \brief Checks first start. - * \param response container for response - */ - void logToOS(Json::Value& response); - }; -}/* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.cpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.cpp deleted file mode 100644 index 6f308e71c2..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/** - * \file MessageBrokerControllerPhone.cpp - * \brief MessageBroker Controller for Phone. - * \author AKara - */ - -#include "MessageBrokerControllerPhone.hpp" - -#include "CMessageBroker.hpp" - -#include "MBDebugHelper.h" - -namespace NsMessageBroker -{ - CMessageBrokerControllerPhone::CMessageBrokerControllerPhone(const std::string& address, uint16_t port): - CMessageBrokerController(address, port, "Phone") - { - } - - CMessageBrokerControllerPhone::~CMessageBrokerControllerPhone() - { - } - - void CMessageBrokerControllerPhone::processRequest(Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerPhone::processRequest()\n")); - if (getControllersName() == getDestinationComponentName(root)) - { - Json::Value response; - response["jsonrpc"] = root["jsonrpc"]; - response["id"] = root["id"]; - if ("makeCall" == getMethodName(root)) - { - if (root.isMember("params")) - { - Json::Value params = root["params"]; - if (params.isMember("phoneNumber") && params["phoneNumber"].isString()) - { - makeCall(params["phoneNumber"].asString(), response); - } else - { - DBG_MSG_ERROR(("Wrong params!\n")); - prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params!", response); - } - } else - { - DBG_MSG_ERROR(("Not possible to parse phone number!\n")); - prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Not possible to parse phone number!", response); - } - } else if ("endCall" == getMethodName(root)) - { - endCall(root["params"].asString(), response); - } else if ("holdCall" == getMethodName(root)) - { - holdCall(root["params"].asString(), response); - } else if ("getContacts" == getMethodName(root)) - { - if (root.isMember("params")) - { - Json::Value params = root["params"]; - if (params.isMember("firstLetter") && params["firstLetter"].isString() - && params.isMember("offset") && params["offset"].isInt() - && params.isMember("numberOfItems") && params["numberOfItems"].isInt()) - { - getContacts(params["firstLetter"].asString(), params["offset"].asInt(), params["numberOfItems"].asInt(), response); - } else - { - DBG_MSG_ERROR(("Wrong params of getContacts()!\n")); - prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params of getContacts()!", response); - } - } else - { - DBG_MSG_ERROR(("Params is not an object!\n")); - prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Params is not an object!", response); - } - } else if ("getHistory" == getMethodName(root)) - { - if (root.isMember("params")) - { - Json::Value params = root["params"]; - if (params.isMember("typeOfContacts") && params["typeOfContacts"].isString() - && params.isMember("offset") && params["offset"].isInt() - && params.isMember("numberOfItems") && params["numberOfItems"].isInt()) - { - getHistory(params["typeOfContacts"].asString(), params["offset"].asInt(), params["numberOfItems"].asInt(), response); - } else - { - DBG_MSG_ERROR(("Wrong params of getHistory()!\n")); - prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params of getHistory()!", response); - } - } else - { - DBG_MSG_ERROR(("Params is not an object!\n")); - prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Params is not an object!", response); - } - } else - { - DBG_MSG_ERROR(("Method has not been found!\n")); - Json::Value err; - err["code"] = NsMessageBroker::INVALID_REQUEST; - err["message"] = "Method has not been found."; - response["error"] = err; - } - sendJsonMessage(response); - } else - { - DBG_MSG_ERROR(("Wrong message destination!\n")); - } - } - - void CMessageBrokerControllerPhone::makeCall(std::string phoneNumber, Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerPhone::makeCall()\n")); - phoneNumber = phoneNumber; // to avoid compiler's warning - response["result"] = "OK"; - } - - void CMessageBrokerControllerPhone::endCall(std::string phoneNumber, Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerPhone::endCall()\n")); - phoneNumber = phoneNumber; // to avoid compiler's warning - response["result"] = "OK"; - } - - void CMessageBrokerControllerPhone::holdCall(std::string phoneNumber, Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerPhone::holdCall()\n")); - phoneNumber = phoneNumber; // to avoid compiler's warning - response["result"] = "OK"; - } - - void CMessageBrokerControllerPhone::getContacts(std::string firstLetter, int offset, int numberOfItems, Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerPhone::getContacts()\n")); - firstLetter = firstLetter; // to avoid compiler's warning - offset = offset; // to avoid compiler's warning - numberOfItems = numberOfItems; // to avoid compiler's warning - response["result"] = "OK"; - } - - void CMessageBrokerControllerPhone::getHistory(std::string firstLetter, int offset, int numberOfItems, Json::Value& response) - { - DBG_MSG(("CMessageBrokerControllerPhone::getHistory()\n")); - firstLetter = firstLetter; // to avoid compiler's warning - offset = offset; // to avoid compiler's warning - numberOfItems = numberOfItems; // to avoid compiler's warning - response["result"] = "OK"; - } - - void CMessageBrokerControllerPhone::onCallStatusChanged(int callStatus) - { - DBG_MSG(("CMessageBrokerControllerPhone::onCallStatusChanged()\n")); - Json::Value request, params; - request["jsonrpc"] = "2.0"; - request["method"] = "Phone.onCallStatusChanged"; - params["callStatus"] = callStatus; - request["params"] = params; - sendJsonMessage(request); - } - - void CMessageBrokerControllerPhone::onContactsUpdated() - { - DBG_MSG(("CMessageBrokerControllerPhone::onContactsUpdated()\n")); - Json::Value request; - request["jsonrpc"] = "2.0"; - request["method"] = "Phone.onContactsUpdated"; - sendJsonMessage(request); - } - - void CMessageBrokerControllerPhone::onHistoryUpdated() - { - DBG_MSG(("CMessageBrokerControllerPhone::onHistoryUpdated()\n")); - Json::Value request; - request["jsonrpc"] = "2.0"; - request["method"] = "Phone.onHistoryUpdated"; - sendJsonMessage(request); - } - - void CMessageBrokerControllerPhone::processNotification(Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerPhone::processNotification()\n")); - root=root;//to prevent compiler warning - } - - void CMessageBrokerControllerPhone::processResponse(std::string method, Json::Value& root) - { - DBG_MSG(("CMessageBrokerControllerPhone::processResponse()\n")); - root=root;//to prevent compiler warning - method = method; - } -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.hpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.hpp deleted file mode 100644 index e6f4898226..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerControllerPhone.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/** - * \file MessageBrokerControllerPhone.hpp - * \brief MessageBroker Controller Phone. - * \author AKara - */ - -#ifndef MB_CONTROLLERPHONE_H -#define MB_CONTROLLERPHONE_H - -#include - -#include "json/json.h" - -#include "mb_controller.hpp" - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - /** - * \class CMessageBrokerControllerPhone - * \brief MessageBroker Controller Phone. - */ - class CMessageBrokerControllerPhone : public CMessageBrokerController - { - public: - /** - * \brief Constructor. - * \param address remote network address or FQDN - * \param port remote local port - */ - CMessageBrokerControllerPhone(const std::string& address, uint16_t port); - - /** - * \brief Destructor. - */ - ~CMessageBrokerControllerPhone(); - - /** - * \brief process request. - * \param root JSON message. - */ - void processRequest(Json::Value& root); - - /** - * \brief process notification. - * \param root JSON message. - */ - void processNotification(Json::Value& root); - - /** - * \brief process response. - * \param method method name which has been called. - * \param root JSON message. - */ - void processResponse(std::string method, Json::Value& root); - public://Notifications - /** - * \brief Notifies Call Status changing. - * \param callStatus status of current active call - */ - void onCallStatusChanged(int callStatus); - - /** - * \brief Notifies Contacts list updated. - */ - void onContactsUpdated(); - - /** - * \brief Notifies History list updated. - */ - void onHistoryUpdated(); - private: - /** - * \brief Makes call. - * \param phoneNumber number for call. - * \param response container for response - */ - void makeCall(std::string phoneNumber, Json::Value& response); - - /** - * \brief Ends call. - * \param phoneNumber number of call. - * \param response container for response - */ - void endCall(std::string phoneNumber, Json::Value& response); - - /** - * \brief Holds call. - * \param phoneNumber number of call. - * \param response container for response - */ - void holdCall(std::string phoneNumber, Json::Value& response); - - /** - * \brief Gets contacts. - * \param firstLetter first letter of list. - * \param offset offset from first item - * \param numberOfItems number of expected items - * \param response container for response - */ - void getContacts(std::string firstLetter, int offset, int numberOfItems, Json::Value& response); - - /** - * \brief Gets history. - * \param typeOfContacts type of contacts (incoming/outgoing/missed/all calls). - * \param offset offset from first item - * \param numberOfItems number of expected items - * \param response container for response - */ - void getHistory(std::string typeOfContacts, int offset, int numberOfItems, Json::Value& response); - - }; -}/* namespace NsMessageBroker */ -#endif /* MB_CONTROLLERPHONE_H */ \ No newline at end of file diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.cpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.cpp deleted file mode 100644 index 405b3fcbd5..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.cpp +++ /dev/null @@ -1,245 +0,0 @@ -/** - * \file MessageBrokerServer.cpp - * \brief MessageBrokerServer sources - * \author AKara - */ - -#include -#include -#include -#include -#include - -#include "system.h" - -#include "MBDebugHelper.h" - -#include "mb_tcpserver.hpp" -#include "mb_tcpclient.hpp" -#include "CMessageBroker.hpp" - -#include "MessageBrokerControllerAVA.hpp" -#include "MessageBrokerControllerPhone.hpp" -#include "MessageBrokerControllerBackend.hpp" - -/** - * \brief Signal management. - * \param code signal code - */ - static void signal_handler(int code) - { - switch(code) - { - case SIGINT: - case SIGTERM: - break; - default: - break; - } -} - -/** - * \brief stores start time of test operation. - */ -int start; - -/** - * \brief Entry point of the program. - * \param argc number of argument - * \param argv array of arguments - * \return EXIT_SUCCESS or EXIT_FAILURE - */ -int main(int argc, char** argv) -{ - NsMessageBroker::CMessageBroker* mpMessageBroker = NsMessageBroker::CMessageBroker::getInstance(); - if (!mpMessageBroker) - { - DBG_MSG_ERROR(("NULL pointer\n")); - exit(EXIT_FAILURE); - } - - - NsMessageBroker::TcpServer server(std::string("127.0.0.1"), 8086, mpMessageBroker); - - DBG_MSG(("Start MessageBroker component\n")); - mpMessageBroker->startMessageBroker(&server); - - NsMessageBroker::CMessageBrokerControllerAVA tcpControllerAVA(std::string("127.0.0.1"), 8086); - NsMessageBroker::CMessageBrokerControllerPhone tcpControllerPhone(std::string("127.0.0.1"), 8086); - NsMessageBroker::CMessageBrokerControllerBackend tcpControllerBackend(std::string("127.0.0.1"), 8086); - - /* avoid compilation warnings */ - argc = argc; - argv = argv; - - if(!networking::init()) - { - DBG_MSG_ERROR(("Networking initialization failed!\n")); - - } - - if(signal(SIGTERM, signal_handler) == SIG_ERR) - { - DBG_MSG_ERROR(("Error signal SIGTERM will not be handled!\n")); - } - - if(signal(SIGINT, signal_handler) == SIG_ERR) - { - DBG_MSG_ERROR(("Error signal SIGINT will not be handled!\n")); - } - - if(!server.Bind()) - { - DBG_MSG_ERROR(("Bind failed!\n")); - exit(EXIT_FAILURE); - } else - { - DBG_MSG(("Bind successful!\n")); - } - - if(!server.Listen()) - { - DBG_MSG_ERROR(("Listen failed!\n")); - exit(EXIT_FAILURE); - } else - { - DBG_MSG(("Listen successful!\n")); - } - - if(!tcpControllerAVA.Connect()) - { - DBG_MSG_ERROR(("Cannot connect to remote peer!\n")); - exit(EXIT_FAILURE); - } else - { - DBG_MSG(("ClientAVA connected to the server! SocketID = %d\n", tcpControllerAVA.GetSocket())); - } - - if(!tcpControllerPhone.Connect()) - { - DBG_MSG_ERROR(("Cannot connect to remote peer!\n")); - exit(EXIT_FAILURE); - } else - { - DBG_MSG(("ClientPhone connected to the server! SocketID = %d\n",tcpControllerPhone.GetSocket())); - } - - if(!tcpControllerBackend.Connect()) - { - DBG_MSG_ERROR(("Cannot connect to remote peer!\n")); - exit(EXIT_FAILURE); - } else - { - DBG_MSG(("ClientBackend connected to the server! SocketID = %d\n",tcpControllerBackend.GetSocket())); - } - - DBG_MSG(("Start CMessageBroker thread!\n")); - System::Thread th1(new System::ThreadArgImpl(*mpMessageBroker, &NsMessageBroker::CMessageBroker::MethodForThread, NULL)); - th1.Start(false); - - DBG_MSG(("Start MessageBroker TCP server thread!\n")); - System::Thread th2(new System::ThreadArgImpl(server, &NsMessageBroker::TcpServer::MethodForThread, NULL)); - th2.Start(false); - - DBG_MSG(("Start tcpControllerAVA receiver thread!\n")); - System::Thread th3(new System::ThreadArgImpl(tcpControllerAVA, &NsMessageBroker::CMessageBrokerControllerAVA::MethodForReceiverThread, NULL)); - th3.Start(false); - - DBG_MSG(("Start tcpControllerPhone receiver thread!\n")); - System::Thread th4(new System::ThreadArgImpl(tcpControllerPhone, &NsMessageBroker::CMessageBrokerControllerPhone::MethodForReceiverThread, NULL)); - th4.Start(false); - - DBG_MSG(("Start tcpControllerBackend receiver thread!\n")); - System::Thread th5(new System::ThreadArgImpl(tcpControllerBackend, &NsMessageBroker::CMessageBrokerControllerBackend::MethodForReceiverThread, NULL)); - th5.Start(false); - - bool loop = true; - while(loop) - { - DBG_MSG(("Enter command code:\n")); - int i; - std::cin >> i; - switch(i) - { - case 0: - { - DBG_MSG(("Exit!\n")); - mpMessageBroker->stopMessageBroker(); - th1.Stop(); - th2.Stop(); - th3.Stop(); - th4.Stop(); - server.Close(); - loop = false; - break; - } - case 1:// register component - { - DBG_MSG(("tcpControllerAVA.register()\n")); - tcpControllerAVA.registerController(0); - DBG_MSG(("tcpControllerPhone.register()\n")); - tcpControllerPhone.registerController(1); - DBG_MSG(("tcpControllerBackend.register()\n")); - tcpControllerBackend.registerController(2); - break; - } - case 2:// external message - { - DBG_MSG(("tcpControllerAVA.Phone.Call()\n")); - start = GetTickCount(); - tcpControllerAVA.makeCall("+380677639550"); - break; - } - case 3://subscribe - { - DBG_MSG(("tcpControllerAVA.subscribeTo()\n")); - tcpControllerAVA.subscribeTo("Phone.onContactsUpdated"); - break; - } - case 4://notify - { - DBG_MSG(("tcpControllerPhone.onContactsUpdated()\n")); - tcpControllerPhone.onContactsUpdated(); - break; - } - case 5: //unsubscribe - { - DBG_MSG(("tcpControllerAVA.unsubscribeFrom()\n")); - tcpControllerAVA.unsubscribeFrom("Phone.onContactsUpdated"); - break; - } - case 6: //unregister - { - DBG_MSG(("tcpControllerPhone.unregister()\n")); - tcpControllerPhone.unregisterController(); - break; - } - case 7: //stress test - { - - DBG_MSG(("tcpControllerAVA.Phone.Call() 500 times\n")); - start = GetTickCount(); - for (int c =0; c<1000; c++) - { - tcpControllerAVA.makeCall("+380677639550"); - } - int stop = GetTickCount(); - int diff = stop - start; - printf("Requests execution time is %d ms!\n", diff); - break; - } - case 8: //parser test - { - DBG_MSG(("Parser test\n")); - mpMessageBroker->Test(); - break; - } - default: - { - DBG_MSG(("Entered: %d\n", i)); - break; - } - } - } - return EXIT_SUCCESS; -} \ No newline at end of file diff --git a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.hpp b/src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.hpp deleted file mode 100644 index 884ed0309f..0000000000 --- a/src/3rd_party-static/MessageBroker/src/example/MessageBrokerServer.hpp +++ /dev/null @@ -1,19 +0,0 @@ -/** - * \file MessageBrokerServer.hpp - * \brief MessageBrokerServer header - * \author AKara - */ - -#ifndef MESSAGEBROKERSERVER_H -#define MESSAGEBROKERSERVER_H - -/** - * \namespace NsMessageBroker - * \brief MessageBroker related functions. - */ -namespace NsMessageBroker -{ - -} /* namespace NsMessageBroker */ - -#endif /* MESSAGEBROKERSERVER_H */ diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBroker.cpp b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBroker.cpp deleted file mode 100644 index 3b14489a8c..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBroker.cpp +++ /dev/null @@ -1,958 +0,0 @@ -/** - * \file CMessageBroker.cpp - * \brief CMessageBroker singletone class implementation. - * \author AKara - */ - -#include -#include -#include - -#include - -#include "CMessageBroker.hpp" -#include "CMessageBrokerRegistry.hpp" - -#include "system.h" - -#include "json/json.h" - -#include "libMBDebugHelper.h" - -namespace NsMessageBroker { -/** - * \class CMessage - * \brief CMessage class implementation. - */ -class CMessage { - public: - /** - * \brief Constructor. - */ - CMessage(int aSenderFp, Json::Value aMessage) { - mSenderFd = aSenderFp; - mMessage = aMessage; - } - - /** - * \brief Destructor. - */ - ~CMessage() { - } - - /** - * \brief getter for Json::Value message. - * \return Json::Value message. - */ - Json::Value getMessage() const { - return mMessage; - } - - /** - * \brief getter for sender FileDescriptor. - * \return sender FileDescriptor. - */ - int getSenderFd() const { - return mSenderFd; - } - private: - /** - * \brief sender FileDescriptor. - */ - int mSenderFd; - - /** - * \brief Json::Value message. - */ - Json::Value mMessage; -}; - - -class CMessageBroker_Private { - public: - /** - * \brief Constructor. - */ - CMessageBroker_Private(); - - /** - * \brief Check if que empty (Thread safe). - * \return True when empty. - */ - bool isEventQueueEmpty(); - - /** - * \brief Pop message from que (Thread safe). - * \return Pointer to CMessage. - */ - CMessage* popMessage(); - - /** - * \brief Push message to que (Thread safe). - * \param pMessage pointer to new CMessage object. - */ - void pushMessage(CMessage* pMessage); - - /** - * \brief gets destination component name. - * \param pMessage JSON message. - * \return string destination component name. - */ - std::string getDestinationComponentName(CMessage* pMessage); - - /** - * \brief gets method name. - * \param pMessage JSON message. - * \return string method name. - */ - std::string getMethodName(CMessage* pMessage); - - /** - * \brief checks is message notification or not. - * \param pMessage JSON message. - * \return true if notification. - */ - bool isNotification(CMessage* pMessage); - - /** - * \brief checks is message response or not. - * \param pMessage JSON message. - * \return true if response. - */ - bool isResponse(CMessage* pMessage); - - /** - * \brief checks message. - * \param pMessage JSON message. - * \param error JSON message to fill in case of any errors. - * \return true if message is good. - */ - bool checkMessage(CMessage* pMessage, Json::Value& error); - - /** - * \brief Process internal MessageBrocker message - * - * \brief Register controller in MessageBroker. - * Use following JSON command to register new component: - * \code - * {"jsonrpc": "2.0", "method": "MB.registerComponent", "params": ""} - * \endcode - * - * \brief Unregister controller in MessageBroker. - * Use following JSON command to unregister component: - * \code - * {"jsonrpc": "2.0", "method": "MB.unregisterComponent", "params": ""} - * \endcode - * - * \brief Subscribe controller on property change. - * Use following JSON command to subscribe to notifications: - * \code - * {"jsonrpc": "2.0", "method": "MB.subscribeTo", "params": "."} - * \endcode - * - * \brief Unsubscribe controller from property change. - * Use following JSON command to unsubscribe from notifications: - * \code - * {"jsonrpc": "2.0", "method": "MB.unsubscribeFrom", "params": "."} - * \endcode - * - * \param pMessage JSON message. - */ - void processInternalMessage(CMessage* pMessage); - - /** - * \brief process external message. - * \param pMessage JSON message. - */ - void processExternalMessage(CMessage* pMessage); - - /** - * \brief process response. - * \param pMessage JSON message. - */ - void processResponse(CMessage* pMessage); - - /** - * \brief Process notification message. - * \brief Notify subscribers about property change. - * expected notification format example: - * \code - * {"jsonrpc": "2.0", "method": ".", "params": } - * \endcode - * \param pMessage JSON message. - */ - void processNotification(CMessage* pMessage); - - /** - * \brief send error message. - * \param pMessage JSON message. - */ - void processError(CMessage* pMessage); - - /** - * \brief send Json message. - * \param fd FileDescriptor of socket. - * \param message JSON message. - */ - void sendJsonMessage(int fd, Json::Value message); - - /** - * \brief push message to wait response que. - * \param pMessage JSON message. - */ - void pushMessageToWaitQue(CMessage* pMessage); - - /** - * \brief Returns start position for Id's generator of controller. - * \return start position for Id's generator of controller (1000 id's). - */ - int getNextControllerIdDiapason() { - return 1000 * mControllersIdCounter++; - } - - /** - * \brief pop message from wait response que. - * \param pMessage JSON message. - */ - int popMessageFromWaitQue(CMessage* pMessage); - - /** - * \brief Tries to remove the parsed part of the buffer - * \param root Parsed JSON value - * \param aJSONData The string buffer - * \return true on success, false on failure - */ - bool cutParsedJSON(const Json::Value& root, std::string& aJSONData); - - /** - * \brief Finds the position just after a JSON object or array in a buffer - * \param isObject Must be true for object, false for array - * \param aJSONData The string buffer - * \return The position in the buffer after the object or array on success, - * std::strin::npos on failure - */ - size_t jumpOverJSONObjectOrArray(bool isObject, const std::string& aJSONData); - - /** - * \brief Finds the position just after a JSON string in a buffer - * \param aJSONData The string buffer - * \return The position in the buffer after the string on success, - * std::strin::npos on failure - */ - size_t jumpOverJSONString(const std::string& aJSONData); - - /** - * \brief Que of messages. - */ - std::deque mMessagesQueue; - - /** - * \brief Counter of messages Id's diapason for the next controllers - * From mControllersIdCounter*1000 to mControllersIdCounter*1000+999. - */ - int mControllersIdCounter; - - /** - * \brief Que of messages which are waiting the response in format: MessageId:SenderFd. - */ - std::map mWaitResponseQueue; - - /** - * \brief Pointer to sender. - */ - CSender* mpSender; - - /** - * \brief Pointer to registry. - */ - CMessageBrokerRegistry* mpRegistry; - - /** - * \brief JSON reader. - */ - Json::Reader m_reader; - - /** - * \brief JSON writer. - */ - Json::FastWriter m_writer; - - /** - * \brief JSON writer for receiver. - */ - Json::FastWriter m_recieverWriter; - - /** - * \brief Messages que mutex. - */ - System::Mutex mMessagesQueueMutex; - - /** - * \brief Binary semaphore that is used to notify the - * messaging thread that a new message is available. - */ - System::BinarySemaphore m_messageQueueSemaphore; -}; - -CMessageBroker_Private::CMessageBroker_Private() : - mControllersIdCounter(1), - mpSender(NULL) { - mpRegistry = CMessageBrokerRegistry::getInstance(); -} - - -CMessageBroker::CMessageBroker() : - p(new CMessageBroker_Private()) { -} - -CMessageBroker::~CMessageBroker() { - delete p, p = 0; -} - -CMessageBroker* CMessageBroker::getInstance() { - static CMessageBroker instance; - return &instance; -} - - -size_t CMessageBroker_Private::jumpOverJSONObjectOrArray(bool isObject, - const std::string& aJSONData) { - const char openBracket = isObject? '{' : '['; - const char closeBracket = isObject? '}' : ']'; - int open_minus_close_brackets(1); - size_t position = aJSONData.find(openBracket); // Find the beginning of the object - - while ((position != std::string::npos) && (open_minus_close_brackets > 0)) { - position = aJSONData.find_first_of(std::string("\"")+openBracket+closeBracket, - position+1); - if (std::string::npos == position) { - break; - } - if ('"' == aJSONData[position]) { - // Ignore string interior, which might contain brackets and escaped "-s - do { - position = aJSONData.find('"', position+1); // Find the closing quote - } while ((std::string::npos != position) && ('\\' == aJSONData[position-1])); - } else if (openBracket == aJSONData[position]) { - ++open_minus_close_brackets; - } else if (closeBracket == aJSONData[position]) { - --open_minus_close_brackets; - } - } - - if ((0 == open_minus_close_brackets) && (std::string::npos != position)) { - ++position; // Move after the closing bracket - } else { - position = std::string::npos; - } - - return position; -} - - -size_t CMessageBroker_Private::jumpOverJSONString(const std::string& aJSONData) { - size_t position = aJSONData.find('"'); // Find the beginning of the string - - do { - position = aJSONData.find('"', position+1); // Find the closing quote - } while ((std::string::npos != position) && ('\\' == aJSONData[position-1])); - - if (std::string::npos != position) { - ++position; // Move after the closing quote - } - - return position; -} - - -bool CMessageBroker_Private::cutParsedJSON(const Json::Value& root, - std::string& aJSONData) { - if (root.isNull() || aJSONData.empty()) { - DBG_MSG_ERROR(("JSON is null or the buffer is empty!\n")); - return false; - } - - std::string parsed_json_str = m_recieverWriter.write(root); - DBG_MSG(("Parsed JSON string: '%s'\n", parsed_json_str.c_str())); - - // Trim front spaces (if any) - const size_t nonempty_position = aJSONData.find_first_not_of(" \t\n\v\f\r"); - aJSONData.erase(0, nonempty_position); - if (std::string::npos == nonempty_position) { - DBG_MSG_ERROR(("Buffer contains only blanks!\n")); - return false; - } - - // JSON writer puts '\n' at the end. Remove it. - const size_t final_lf_pos = parsed_json_str.rfind('\n'); - if (final_lf_pos == parsed_json_str.length()-1) { - parsed_json_str.erase(final_lf_pos, 1); - } - - /* RFC 4627: "A JSON value MUST be an object, array, number, or string, or - * one of the following three literal names: false null true" - * So we will try to find the borders of the parsed part based on its type. */ - - size_t position(std::string::npos); - - if (0 == aJSONData.find(parsed_json_str)) { - // If by chance parsed JSON is the same in the buffer and is at the beginning - position = parsed_json_str.length(); - } else if (root.isObject() || root.isArray()) { - position = jumpOverJSONObjectOrArray(root.isObject(), aJSONData); - } else if (root.isString()) { - position = jumpOverJSONString(aJSONData); - } else if (root.isNumeric()) { - position = aJSONData.find_first_not_of("+-0123456789.eE"); - } else if (root.isBool() || ("null" == parsed_json_str)) { - position = aJSONData.find(parsed_json_str); - if (std::string::npos != position) { - position += parsed_json_str.length(); - } - } else { - DBG_MSG_ERROR(("Unknown JSON type!\n")); - } - - if (std::string::npos == position) { - DBG_MSG_ERROR(("Error finding JSON object boundaries!\n")); - /* This should not happen, because the string is already parsed as a - * valid JSON. If this happens then above code is wrong. It is better - * to assert() than just return here, because otherwise we may enter an - * endless cycle - fail to process one and the same message again and - * again. Or we may clear the buffer and return, but in this way we will - * loose the next messages, miss a bug here, and create another bug. */ - assert(std::string::npos != position); - return false; // For release version - } - - if ((position >= aJSONData.length()) || - ((position == aJSONData.length()-1) && isspace(aJSONData[position]))) { - // No next object. Clear entire aJSONData. - aJSONData = ""; - } else { - // There is another object. Clear the current one. - aJSONData.erase(0, position); - } - - return true; -} - - -void CMessageBroker::onMessageReceived(int fd, std::string& aJSONData, bool tryHard) { - DBG_MSG(("CMessageBroker::onMessageReceived(%d, '%s')\n", fd, aJSONData.c_str())); - - while (! aJSONData.empty()) { - Json::Value root; - if ((! p->m_reader.parse(aJSONData, root)) || root.isNull()) { - DBG_MSG_ERROR(("Unable to parse JSON!")); - if (! tryHard) { - return; - } - uint8_t first_byte = static_cast(aJSONData[0]); - if ((first_byte <= 0x08) || ((first_byte >= 0x80) && (first_byte <= 0x88))) { - DBG_MSG((" There is an unparsed websocket header probably.\n")); - /* Websocket headers can have FIN flag set in the first byte (0x80). - * Then there are 3 zero bits and 4 bits for opcode (from 0x00 to 0x0A). - * But actually we don't use opcodes above 0x08. - * Use this fact to distinguish websocket header from payload text data. - * It can be a coincidence of course, but we have to give it a try. */ - return; - } else if ('{' == aJSONData[0]) { - DBG_MSG_ERROR((" Incomplete JSON object probably.\n")); - return; - } else { - DBG_MSG_ERROR((" Step in the buffer and try again...\n")); - aJSONData.erase(0, 1); - DBG_MSG_ERROR(("Buffer after cut is: '%s'\n", aJSONData.c_str())); - continue; - } - - } else if (! root.isObject()) { - /* JSON RPC 2.0 messages are objects. Batch calls must be pre-rpocessed, - * so no need for "and !root.isArray()" */ - DBG_MSG_ERROR(("Parsed JSON is not an object!\n")); - if (! tryHard) { - return; - } - // Cut parsed data from the buffer below and continue - - } else if ((!root.isMember("jsonrpc")) || (root["jsonrpc"]!="2.0")) { - DBG_MSG_ERROR(("'jsonrpc' is not set correctly in parsed JSON!\n")); - if (! tryHard) { - return; - } - // Cut parsed object from the buffer below and continue - - } else { - // Parsing successful. Pass the message up. - p->pushMessage(new CMessage(fd, root)); - } - - p->cutParsedJSON(root, aJSONData); - - DBG_MSG(("Buffer after cut is: '%s'\n", aJSONData.c_str())); - } -} - -void CMessageBroker::Test() { - Json::Value root, err; - std::string ReceivingBuffer = - "{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"MB.registerComponent\",\"params\":{\"componentName\":\"AVA\"}}123{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"MB.registerComponent\",\"params\":{\"componentName\":\"AVA\"}}"; - DBG_MSG(("String is:%s\n", ReceivingBuffer.c_str())); - while (1) { - if (!p->m_reader.parse(ReceivingBuffer, root)) { - DBG_MSG_ERROR(("Received not JSON string! %s\n", ReceivingBuffer.c_str())); - return; - } - std::string wmes = p->m_recieverWriter.write(root); - DBG_MSG(("Parsed JSON string:%s; length: %d\n", wmes.c_str(), wmes.length())); - DBG_MSG(("Buffer is:%s\n", ReceivingBuffer.c_str())); - ssize_t beginpos = ReceivingBuffer.find(wmes); - ReceivingBuffer.erase(0, beginpos + wmes.length()); - DBG_MSG(("Buffer after cut is:%s\n", ReceivingBuffer.c_str())); - CMessage message(0, root); - if (p->checkMessage(&message, err)) { - //here put message to que - } else { - DBG_MSG_ERROR(("Wrong message:%s\n", wmes.c_str())); - } - } -} - -void CMessageBroker::OnSocketClosed(const int fd) { - DBG_MSG(("CMessageBroker::OnSocketClosed(%d)\n", fd)); - if (p->mpRegistry) { - p->mpRegistry->removeControllersByDescriptor(fd); - } -} - -void CMessageBroker::startMessageBroker(CSender* pSender) { - DBG_MSG(("CMessageBroker::startMessageBroker()\n")); - p->mpSender = pSender; -} - -void CMessageBroker::stopMessageBroker() { - p->mpSender = NULL; - DBG_MSG(("CMessageBroker::stopMessageBroker()\n")); -} - -CMessage* CMessageBroker_Private::popMessage() { - CMessage* ret = NULL; - DBG_MSG(("CMessageBroker::popMessage()\n")); - mMessagesQueueMutex.Lock(); - if (false == mMessagesQueue.empty()) { - ret = mMessagesQueue.front(); - mMessagesQueue.pop_front();// delete message from que - } else { - DBG_MSG(("Que is empty!\n")); - } - mMessagesQueueMutex.Unlock(); - return ret; -} - -void CMessageBroker_Private::pushMessage(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::pushMessage()\n")); - mMessagesQueueMutex.Lock(); - if (pMessage) { - mMessagesQueue.push_back(pMessage); - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } - mMessagesQueueMutex.Unlock(); - - m_messageQueueSemaphore.Notify(); -} - -bool CMessageBroker_Private::isEventQueueEmpty() { - bool bResult = true; - mMessagesQueueMutex.Lock(); - bResult = mMessagesQueue.empty(); - mMessagesQueueMutex.Unlock(); - return bResult; -} - -std::string CMessageBroker_Private::getDestinationComponentName(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::getDestinationComponentName()\n")); - std::string ret = ""; - if (pMessage) { - Json::Value mes = pMessage->getMessage(); - std::string method = mes["method"].asString(); - int pos = method.find("."); - if (-1 != pos) { - ret = method.substr(0, pos); - } - DBG_MSG(("Destination component is: %s\n", ret.c_str())); - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } - return ret; -} - -std::string CMessageBroker_Private::getMethodName(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::getMethodName()\n")); - std::string ret = ""; - if (pMessage) { - Json::Value mes = pMessage->getMessage(); - std::string method = mes["method"].asString(); - int pos = method.find("."); - if (-1 != pos) { - ret = method.substr(pos + 1); - } - DBG_MSG(("Method is: %s\n", ret.c_str())); - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } - return ret; -} - -bool CMessageBroker_Private::isNotification(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::isNotification()\n")); - bool ret = false; - Json::Value mes = pMessage->getMessage(); - if (false == mes.isMember("id")) { - ret = true; - } - DBG_MSG(("Result: %d\n", ret)); - return ret; -} - -bool CMessageBroker_Private::isResponse(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::isResponse()\n")); - bool ret = false; - Json::Value mes = pMessage->getMessage(); - if ((true == mes.isMember("result")) || (true == mes.isMember("error"))) { - ret = true; - } - DBG_MSG(("Result: %d\n", ret)); - return ret; -} - -void CMessageBroker_Private::pushMessageToWaitQue(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::pushMessageToWaitQue()\n")); - if (pMessage) { - Json::Value root = pMessage->getMessage(); - mWaitResponseQueue.insert(std::map::value_type(root["id"].asInt(), pMessage->getSenderFd())); - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } -} - -int CMessageBroker_Private::popMessageFromWaitQue(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::popMessageFromWaitQue()\n")); - int result = -1; - if (pMessage) { - Json::Value root = pMessage->getMessage(); - int messageId = root["id"].asInt(); - std::map ::iterator it; - it = mWaitResponseQueue.find(messageId); - if (it != mWaitResponseQueue.end()) { - result = (*it).second; - mWaitResponseQueue.erase(it); - } - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } - DBG_MSG(("Senders Fd: %d\n", result)); - return result; -} - -void CMessageBroker_Private::processInternalMessage(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::processInternalMessage()\n")); - if (pMessage) { - std::string amethodName = getMethodName(pMessage); - DBG_MSG(("Method: %s\n", amethodName.c_str())); - Json::Value root = pMessage->getMessage(); - if ("registerComponent" == amethodName) { - Json::Value params = root["params"]; - if (params.isMember("componentName") && params["componentName"].isString()) { - std::string controllerName = params["componentName"].asString(); - if (mpRegistry->addController(pMessage->getSenderFd(), controllerName)) { - Json::Value response; - response["id"] = root["id"]; - response["jsonrpc"] = "2.0"; - response["result"] = getNextControllerIdDiapason(); - sendJsonMessage(pMessage->getSenderFd(), response); - } else { - Json::Value error, err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = CONTROLLER_EXISTS; - err["message"] = "Controller has been already registered."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else { - Json::Value error, err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Wrong method parameter."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else if ("subscribeTo" == amethodName) { - Json::Value params = root["params"]; - if (params.isMember("propertyName") && params["propertyName"].isString()) { - std::string propertyName = params["propertyName"].asString(); - if (mpRegistry->addSubscriber(pMessage->getSenderFd(), propertyName)) { - Json::Value response; - response["id"] = root["id"]; - response["jsonrpc"] = "2.0"; - response["result"] = "OK"; - sendJsonMessage(pMessage->getSenderFd(), response); - } else { - Json::Value error, err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = CONTROLLER_EXISTS; - err["message"] = "Subscribe has been already registered."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else { - Json::Value error, err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Wrong method parameter."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else if ("unregisterComponent" == amethodName) { - Json::Value params = root["params"]; - if (params.isMember("componentName") && params["componentName"].isString()) { - std::string controllerName = params["componentName"].asString(); - mpRegistry->deleteController(controllerName); - Json::Value response; - response["id"] = root["id"]; - response["jsonrpc"] = "2.0"; - response["result"] = "OK"; - sendJsonMessage(pMessage->getSenderFd(), response); - } else { - Json::Value error, err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Wrong method parameter."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else if ("unsubscribeFrom" == amethodName) { - Json::Value params = root["params"]; - if (params.isMember("propertyName") && params["propertyName"].isString()) { - std::string propertyName = params["propertyName"].asString(); - mpRegistry->deleteSubscriber(pMessage->getSenderFd(), propertyName); - Json::Value response; - response["id"] = root["id"]; - response["jsonrpc"] = "2.0"; - response["result"] = "OK"; - sendJsonMessage(pMessage->getSenderFd(), response); - } else { - Json::Value error, err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Wrong method parameter."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else { - DBG_MSG(("Unknown method!\n")); - Json::Value error; - Json::Value err; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Invalid MessageBroker method."; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } -} - -void CMessageBroker_Private::processExternalMessage(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::processExternalMessage()\n")); - if (pMessage) { - std::string destComponentName = getDestinationComponentName(pMessage); - int destFd = mpRegistry->getDestinationFd(destComponentName); - Json::Value root = pMessage->getMessage(); - if (0 < destFd) { - sendJsonMessage(destFd, root); - pushMessageToWaitQue(pMessage); - } else { - // error, controller not found in the registry - DBG_MSG(("Unknown method!\n")); - Json::Value error; - Json::Value err; - Json::Value error_data; - error["id"] = root["id"]; - error["jsonrpc"] = "2.0"; - err["code"] = UNSUPPORTED_RESOURCE; - err["message"] = "Destination controller not found!"; - error_data["method"] = root["method"]; - err["data"] = error_data; - error["error"] = err; - processError(new CMessage(pMessage->getSenderFd(), error)); - } - } else { - DBG_MSG_ERROR(("NULL pointer\n")); - } -} - -void CMessageBroker_Private::processResponse(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::processResponse()\n")); - if (pMessage) { - int senderFd = popMessageFromWaitQue(pMessage); - if (-1 != senderFd) { - sendJsonMessage(senderFd, pMessage->getMessage()); - } - } else { - DBG_MSG_ERROR(("NULL pointer\n")); - } -} - -void CMessageBroker_Private::processNotification(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::processNotification()\n")); - if (pMessage) { - Json::Value root = pMessage->getMessage(); - std::string methodName = root["method"].asString(); - DBG_MSG(("Property: %s\n", methodName.c_str())); - std::vector result; - int subscribersCount = mpRegistry->getSubscribersFd(methodName, result); - if (0 < subscribersCount) { - std::vector::iterator it; - for (it = result.begin(); it != result.end(); it++) { - sendJsonMessage(*it, root); - } - } else { - DBG_MSG(("No subscribers for this property!\n")); - } - } else { - DBG_MSG_ERROR(("NULL pointer\n")); - } -} - -void CMessageBroker_Private::processError(CMessage* pMessage) { - DBG_MSG(("CMessageBroker::processError()\n")); - if (pMessage) { - sendJsonMessage(pMessage->getSenderFd(), pMessage->getMessage()); - delete pMessage;// delete CMessage object with error description!!! - } else { - DBG_MSG_ERROR(("NULL pointer\n")); - } -} - -void CMessageBroker_Private::sendJsonMessage(int fd, Json::Value message) { - DBG_MSG(("CMessageBroker::sendJsonMessage(%d)\n", fd)); - if (mpSender) { - std::string mes = m_writer.write(message); - int retVal = mpSender->Send(fd, mes); - if (retVal == -1) { - DBG_MSG_ERROR(("Message hasn't been sent!\n")); - return; - } - DBG_MSG(("Length:%d, Sent: %d bytes\n", mes.length(), retVal)); - } else { - DBG_MSG_ERROR(("mpSender NULL pointer\n")); - } -} - -void* CMessageBroker::MethodForThread(void* arg) { - arg = arg; // to avoid compiler warnings - while (1) { - while (!p->isEventQueueEmpty()) { - CMessage* message = p->popMessage(); - if (message) { - Json::Value error; - if (p->checkMessage(message, error)) { - if (p->isNotification(message)) { - DBG_MSG(("Message is notification!\n")); - p->processNotification(message); - } else if (p->isResponse(message)) { - DBG_MSG(("Message is response!\n")); - p->processResponse(message); - } else { - if ("MB" == p->getDestinationComponentName(message)) { - DBG_MSG(("Internal MessageBroker method!\n")); - p->processInternalMessage(message); - } else { - DBG_MSG(("Not MessageBroker method!\n")); - p->processExternalMessage(message); - } - } - } else { - DBG_MSG_ERROR(("Message contains wrong data!\n")); - CMessage* errMessage = new CMessage(message->getSenderFd(), error); - if (NULL != errMessage) { - p->processError(errMessage); - } else { - DBG_MSG_ERROR(("NULL pointer!\n")); - } - } - delete message;// delete message object - } - } - p->m_messageQueueSemaphore.Wait(); - } - - return NULL; -} - -bool CMessageBroker_Private::checkMessage(CMessage* pMessage, Json::Value& error) { - DBG_MSG(("CMessageBroker::checkMessage()\n")); - Json::Value root; - root = pMessage->getMessage(); - Json::Value err; - - /* check the JSON-RPC version => 2.0 */ - if (!root.isObject() || !root.isMember("jsonrpc") || root["jsonrpc"] != "2.0") { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Invalid JSON RPC version."; - error["error"] = err; - return false; - } - - /* Check the id of message */ - if (root.isMember("id") && (root["id"].isArray() || root["id"].isObject() || root["id"].isString())) { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Invalid ID of message."; - error["error"] = err; - return false; - } - - /* extract "method" attribute */ - if (root.isMember("method")) { - if (!root["method"].isString()) { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Invalid JSONRPC method."; - error["error"] = err; - return false; - } - /* Check the params is an object*/ - if (root.isMember("params") && !root["params"].isObject()) { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Invalid JSONRPC params."; - error["error"] = err; - return false; - } - } else if (!(root.isMember("result") || root.isMember("error"))) { - error["id"] = Json::Value::null; - error["jsonrpc"] = "2.0"; - err["code"] = INVALID_REQUEST; - err["message"] = "Unknwn message type."; - error["error"] = err; - return false; - } - return true; -} -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBrokerRegistry.cpp b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBrokerRegistry.cpp deleted file mode 100644 index fb24d08f1c..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/CMessageBrokerRegistry.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/** - * \file CMessageBrokerRegistry.cpp - * \brief CMessageBrokerRegistry singletone class implementation. - * \author AKara - */ - -#include "CMessageBrokerRegistry.hpp" -#include "libMBDebugHelper.h" - -#include -#include - -namespace NsMessageBroker -{ - CMessageBrokerRegistry::CMessageBrokerRegistry() - { - } - - CMessageBrokerRegistry::~CMessageBrokerRegistry() - { - } - - CMessageBrokerRegistry* CMessageBrokerRegistry::getInstance() - { - static CMessageBrokerRegistry instance; - return &instance; - } - - bool CMessageBrokerRegistry::addController(int fd, std::string name) - { - DBG_MSG(("CMessageBrokerRegistry::addController()\n")); - bool result = false; - std::map ::iterator it; - - sync_primitives::AutoLock lock(mControllersListLock); - it = mControllersList.find(name); - if (it == mControllersList.end()) - { - mControllersList.insert(std::map ::value_type(name, fd)); - result = true; - } else - { - DBG_MSG(("Controller already exists!\n")); - } - - DBG_MSG(("Count of controllers: %d\n", mControllersList.size())); - return result; - } - - void CMessageBrokerRegistry::deleteController(std::string name) - { - DBG_MSG(("CMessageBrokerRegistry::deleteController()\n")); - std::map ::iterator it; - - int fd; - { - sync_primitives::AutoLock lock(mControllersListLock); - it = mControllersList.find(name); - if (it != mControllersList.end()) - { - fd = it->second; - mControllersList.erase(it); - } else { - DBG_MSG(("No such controller in the list!\n")); - return; - } - DBG_MSG(("Count of controllers: %d\n", mControllersList.size())); - } - removeSubscribersByDescriptor(fd); - } - - void CMessageBrokerRegistry::removeControllersByDescriptor(const int fd) { - DBG_MSG(("CMessageBrokerRegistry::removeControllersByDescriptor(%d)\n", - fd)); - { - sync_primitives::AutoLock lock(mControllersListLock); - std::map ::iterator it = mControllersList.begin(); - for (; it != mControllersList.end();) { - if (it->second == fd) { - mControllersList.erase(it++); - } else { - ++it; - } - } - } - removeSubscribersByDescriptor(fd); - } - - void CMessageBrokerRegistry::removeSubscribersByDescriptor(const int fd) { - DBG_MSG(("CMessageBrokerRegistry::removeSubscribersByDescriptor(%d)\n", - fd)); - sync_primitives::AutoLock lock(mSubscribersListLock); - std::multimap ::iterator it_s = mSubscribersList.begin(); - for (; it_s !=mSubscribersList.end(); ) { - if (it_s->second == fd) { - mSubscribersList.erase(it_s++); - } else { - ++it_s; - } - } - } - - bool CMessageBrokerRegistry::addSubscriber(int fd, std::string name) - { - DBG_MSG(("CMessageBrokerRegistry::addSubscriber()\n")); - bool result = true; - - sync_primitives::AutoLock lock(mSubscribersListLock); - std::pair::iterator, std::multimap ::iterator> p = mSubscribersList.equal_range(name); - if (p.first != p.second) - { - std::multimap ::iterator itr; - for (itr = p.first; itr != p.second; itr++) - { - if (fd == itr->second) - { - result = false; - DBG_MSG(("Subscriber already exists!\n")); - } - } - } - if (result) - { - mSubscribersList.insert(std::map ::value_type(name, fd)); - } - - DBG_MSG(("Count of subscribers: %d\n", mSubscribersList.size())); - return result; - } - - void CMessageBrokerRegistry::deleteSubscriber(int fd, std::string name) - { - DBG_MSG(("CMessageBrokerRegistry::deleteSubscriber()\n")); - - sync_primitives::AutoLock lock(mSubscribersListLock); - std::pair::iterator, std::multimap ::iterator> p = mSubscribersList.equal_range(name); - if (p.first != p.second) { - std::multimap ::iterator itr; - for (itr = p.first; itr != p.second; ) { - DBG_MSG(("My for loop %s, %d", itr->first.c_str() ,itr->second)); - if (fd == itr->second) { - mSubscribersList.erase(itr++); - } else { - ++itr; - } - } - } - - DBG_MSG(("Count of subscribers: %d\n", mSubscribersList.size())); - } - - int CMessageBrokerRegistry::getDestinationFd(std::string name) - { - DBG_MSG(("CMessageBrokerRegistry::getDestinationFd()\n")); - int result = -1; - std::map ::iterator it; - - sync_primitives::AutoLock lock(mControllersListLock); - it = mControllersList.find(name); - if (it != mControllersList.end()) - { - result = it->second; - } - - DBG_MSG(("Controllers Fd: %d\n", result)); - return result; - } - - int CMessageBrokerRegistry::getSubscribersFd(std::string name, std::vector& result) - { - DBG_MSG(("CMessageBrokerRegistry::getSubscribersFd()\n")); - int res = 0; - std::map ::iterator it; - - sync_primitives::AutoLock lock(mSubscribersListLock); - std::pair::iterator, std::multimap ::iterator> p = mSubscribersList.equal_range(name); - if (p.first != p.second) - { - std::multimap ::iterator itr; - for (itr = p.first; itr != p.second; itr++) - { - result.push_back(itr->second); - DBG_MSG(("Controllers Fd: %d\n", itr->second)); - } - } - - res = result.size(); - DBG_MSG(("Result vector size: %d\n", res)); - return res; - } -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/libMBDebugHelper.h b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/libMBDebugHelper.h deleted file mode 100644 index 0d5260cdda..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/libMBDebugHelper.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * \file libMBDebugHelper.h - * \brief DebugHelper. - * \author AKara - */ - -#ifndef MB_DEBUG_HELPER_H -#define MB_DEBUG_HELPER_H - -#include - -/** -* \def DEBUG_MB_ON -* \brief Switches on MessageBroker debug messages. -*/ -#ifdef DEBUG_MB_ON - -/** -* \def DBG_MSG -* \brief Debug message output with file name and line number. -* \param x formatted debug message. -* \return printf construction. -*/ -#define DBG_MSG(x) printf("%s:%d_lib ", __FILE__, __LINE__);\ - printf x - -/** - * \def DBG_MSG_ERROR - * \brief Debug ERROR message output with file name and line number. - * \param x formatted debug message. - * \return printf construction. - */ -#define DBG_MSG_ERROR(x) printf("ERROR!!! %s:%d_lib ", __FILE__, __LINE__);\ - printf x - -#else - -#define DBG_MSG(x) -#define DBG_MSG_ERROR(x) - -#endif - -#endif /*MB_DEBUG_HELPER_H*/ diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.cpp b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.cpp deleted file mode 100644 index b3e347d9d7..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/* MD5 - converted to C++ class by Frank Thilo (thilo@unix-ag.org) - for bzflag (http://www.bzflag.org) - - based on: - - md5.h and md5.c - reference implemantion of RFC 1321 - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - rights reserved. - - License to copy and use this software is granted provided that it - is identified as the "RSA Data Security, Inc. MD5 Message-Digest - Algorithm" in all material mentioning or referencing this software - or this function. - - License is also granted to make and use derivative works provided - that such works are identified as "derived from the RSA Data - Security, Inc. MD5 Message-Digest Algorithm" in all material - mentioning or referencing the derived work. - - RSA Data Security, Inc. makes no representations concerning either - the merchantability of this software or the suitability of this - software for any particular purpose. It is provided "as is" - without express or implied warranty of any kind. - - These notices must be retained in any copies of any part of this - documentation and/or software. - - */ - -/* interface header */ -#include "md5.h" - -/* system implementation headers */ -#include -#include - -// Constants for MD5Transform routine. -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - -/////////////////////////////////////////////// - -// F, G, H and I are basic MD5 functions. -inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) { - return (x&y) | (~x&z); -} - -inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) { - return (x&z) | (y&~z); -} - -inline MD5::uint4 MD5::H_(uint4 x, uint4 y, uint4 z) { - return x^y^z; -} - -inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) { - return y ^ (x | ~z); -} - -// rotate_left rotates x left n bits. -inline MD5::uint4 MD5::rotate_left(uint4 x, int n) { - return (x << n) | (x >> (32-n)); -} - -// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -// Rotation is separate from addition to prevent recomputation. -inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a+ F(b,c,d) + x + ac, s) + b; -} - -inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a + G(b,c,d) + x + ac, s) + b; -} - -inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a + H_(b,c,d) + x + ac, s) + b; -} - -inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { - a = rotate_left(a + I(b,c,d) + x + ac, s) + b; -} - -////////////////////////////////////////////// - -// default ctor, just initailize -MD5::MD5() -{ - init(); -} - -////////////////////////////////////////////// - -// nifty shortcut ctor, compute MD5 for string and finalize it right away -MD5::MD5(const std::string &text) -{ - init(); - update(text.c_str(), text.length()); - finalize(); -} - -////////////////////////////// - -void MD5::init() -{ - finalized=false; - - count[0] = 0; - count[1] = 0; - - // load magic initialization constants. - state[0] = 0x67452301; - state[1] = 0xefcdab89; - state[2] = 0x98badcfe; - state[3] = 0x10325476; -} - -////////////////////////////// - -// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4. -void MD5::decode(uint4 output[], const uint1 input[], size_type len) -{ - for (unsigned int i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | - (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); -} - -////////////////////////////// - -// encodes input (uint4) into output (unsigned char). Assumes len is -// a multiple of 4. -void MD5::encode(uint1 output[], const uint4 input[], size_type len) -{ - for (size_type i = 0, j = 0; j < len; i++, j += 4) { - output[j] = input[i] & 0xff; - output[j+1] = (input[i] >> 8) & 0xff; - output[j+2] = (input[i] >> 16) & 0xff; - output[j+3] = (input[i] >> 24) & 0xff; - } -} - -////////////////////////////// - -// apply MD5 algo on a block -void MD5::transform(const uint1 block[blocksize]) -{ - uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - decode (x, block, blocksize); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - // Zeroize sensitive information. - memset(x, 0, sizeof x); -} - -////////////////////////////// - -// MD5 block update operation. Continues an MD5 message-digest -// operation, processing another message block -void MD5::update(const unsigned char input[], size_type length) -{ - // compute number of bytes mod 64 - size_type index = count[0] / 8 % blocksize; - - // Update number of bits - if ((count[0] += (length << 3)) < (length << 3)) - count[1]++; - count[1] += (length >> 29); - - // number of bytes we need to fill in buffer - size_type firstpart = 64 - index; - - size_type i; - - // transform as many times as possible. - if (length >= firstpart) - { - // fill buffer first, transform - memcpy(&buffer[index], input, firstpart); - transform(buffer); - - // transform chunks of blocksize (64 bytes) - for (i = firstpart; i + blocksize <= length; i += blocksize) - transform(&input[i]); - - index = 0; - } - else - i = 0; - - // buffer remaining input - memcpy(&buffer[index], &input[i], length-i); -} - -////////////////////////////// - -// for convenience provide a verson with signed char -void MD5::update(const char input[], size_type length) -{ - update((const unsigned char*)input, length); -} - -////////////////////////////// - -// MD5 finalization. Ends an MD5 message-digest operation, writing the -// the message digest and zeroizing the context. -MD5& MD5::finalize() -{ - static unsigned char padding[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - if (!finalized) { - // Save number of bits - unsigned char bits[8]; - encode(bits, count, 8); - - // pad out to 56 mod 64. - size_type index = count[0] / 8 % 64; - size_type padLen = (index < 56) ? (56 - index) : (120 - index); - update(padding, padLen); - - // Append length (before padding) - update(bits, 8); - - // Store state in digest - encode(digest, state, 16); - - // Zeroize sensitive information. - memset(buffer, 0, sizeof buffer); - memset(count, 0, sizeof count); - - finalized=true; - } - - return *this; -} - -////////////////////////////// - -void MD5::getdigest(char *digest) const -{ - if (!finalized) - return; - - if (digest == NULL) - return; - - memcpy(digest, this->digest, 16); -} - -// return hex representation of digest as string -std::string MD5::hexdigest() const -{ - if (!finalized) - return ""; - - char buf[33]; - for (int i=0; i<16; i++) - sprintf(buf+i*2, "%02x", digest[i]); - buf[32]=0; - - return std::string(buf); -} - -////////////////////////////// - -std::ostream& operator<<(std::ostream& out, MD5 md5) -{ - return out << md5.hexdigest(); -} - -////////////////////////////// - -std::string md5(const std::string str) -{ - MD5 md5 = MD5(str); - - return md5.hexdigest(); -} \ No newline at end of file diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.h b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.h deleted file mode 100644 index 2c54c03b1b..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/md5.h +++ /dev/null @@ -1,93 +0,0 @@ -/* MD5 - converted to C++ class by Frank Thilo (thilo@unix-ag.org) - for bzflag (http://www.bzflag.org) - - based on: - - md5.h and md5.c - reference implementation of RFC 1321 - - Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All - rights reserved. - - License to copy and use this software is granted provided that it - is identified as the "RSA Data Security, Inc. MD5 Message-Digest - Algorithm" in all material mentioning or referencing this software - or this function. - - License is also granted to make and use derivative works provided - that such works are identified as "derived from the RSA Data - Security, Inc. MD5 Message-Digest Algorithm" in all material - mentioning or referencing the derived work. - - RSA Data Security, Inc. makes no representations concerning either - the merchantability of this software or the suitability of this - software for any particular purpose. It is provided "as is" - without express or implied warranty of any kind. - - These notices must be retained in any copies of any part of this - documentation and/or software. - - */ - -#ifndef BZF_MD5_H -#define BZF_MD5_H - -#include -#include - -// a small class for calculating MD5 hashes of strings or byte arrays -// it is not meant to be fast or secure -// -// usage: 1) feed it blocks of uchars with update() -// 2) finalize() -// 3) get hexdigest() string -// or -// MD5(std::string).hexdigest() -// -// assumes that char is 8 bit and int is 32 bit -class MD5 -{ -public: - typedef unsigned int size_type; // must be 32bit - - MD5(); - MD5(const std::string& text); - void update(const unsigned char *buf, size_type length); - void update(const char *buf, size_type length); - MD5& finalize(); - void getdigest(char *digest) const; // digest must be 16 bytes long - std::string hexdigest() const; - friend std::ostream& operator<<(std::ostream&, MD5 md5); - -private: - void init(); - typedef unsigned char uint1; // 8bit - typedef unsigned int uint4; // 32bit - enum {blocksize = 64}; // VC6 won't eat a const static int here - - void transform(const uint1 block[blocksize]); - static void decode(uint4 output[], const uint1 input[], size_type len); - static void encode(uint1 output[], const uint4 input[], size_type len); - - bool finalized; - uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk - uint4 count[2]; // 64bit counter for number of bits (lo, hi) - uint4 state[4]; // digest so far - uint1 digest[16]; // the result - - // low level logic operations - static inline uint4 F(uint4 x, uint4 y, uint4 z); - static inline uint4 G(uint4 x, uint4 y, uint4 z); - static inline uint4 H_(uint4 x, uint4 y, uint4 z); - static inline uint4 I(uint4 x, uint4 y, uint4 z); - static inline uint4 rotate_left(uint4 x, int n); - static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); - static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); - static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); - static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); -}; - -std::string md5(const std::string str); - -#endif \ No newline at end of file diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/system.cpp b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/system.cpp deleted file mode 100644 index 456362f9d8..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/system.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - * JsonRpc-Cpp - JSON-RPC implementation. - * Copyright (C) 2008-2011 Sebastien Vincent - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/** - * \file system.cpp - * \brief System utils. - * \author Sebastien Vincent - */ - -#include -#include - -#include "system.h" - -namespace System { - -void msleep(unsigned long ms) { -#ifdef _WIN32 - Sleep(ms); -#else - /* Unix */ - struct timespec req; - req.tv_sec = ms / 1000; - req.tv_nsec = (ms % 1000) * 1000000; - nanosleep(&req, NULL); -#endif -} - -ThreadArg::~ThreadArg() { -} - -#ifndef WIN32 - -/* POSIX specific part for thread and mutex */ - -Thread::Thread(ThreadArg* arg) { - m_arg = arg; -} - -Thread::~Thread() { - delete m_arg; -} - -bool Thread::Start(bool detach) { - pthread_attr_t attr; - int ret = -1; - - /* must have valid object argument */ - if (m_arg == NULL) { - return false; - } - - /* set the detach state value */ - if (pthread_attr_init(&attr) != 0) { - return false; - } - - if (pthread_attr_setdetachstate(&attr, detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE) != 0) { - pthread_attr_destroy(&attr); - return false; - } - - /* create thread */ - ret = pthread_create(&m_id, &attr, &Thread::Call, this); - pthread_setname_np(m_id, "MB Thread"); - pthread_attr_destroy(&attr); - return ret == 0; -} - -bool Thread::Stop() { - pthread_cancel(m_id); - return false;// Android does not support 'pthread_cancel'; -} - -bool Thread::Join(void** ret) { - return pthread_join(m_id, ret) == 0; -} - -void* Thread::Call(void* arg) { - // Disable system signals receiving in thread - // by setting empty signal mask - // (system signals processes only in the main thread) - sigset_t set; - sigfillset(&set); - pthread_sigmask(SIG_SETMASK, &set, NULL); - - Thread* thread = static_cast(arg); - - /* call our specific object method */ - return thread->m_arg->Call(); -} - -Mutex::Mutex() { - pthread_mutexattr_t attr; - - pthread_mutexattr_init(&attr); - pthread_mutex_init(&m_mutex, &attr); - pthread_mutexattr_destroy(&attr); -} - -Mutex::~Mutex() { - pthread_mutex_destroy(&m_mutex); -} - -bool Mutex::Lock() { - return !pthread_mutex_lock(&m_mutex); -} - -bool Mutex::Unlock() { - return !pthread_mutex_unlock(&m_mutex); -} - - -// Based on Binary Semaphores example at -// http://www.mathcs.emory.edu/~cheung/Courses/455/Syllabus/5c-pthreads/sync.html -BinarySemaphore::BinarySemaphore() : - m_mutex(PTHREAD_MUTEX_INITIALIZER), - m_cond(PTHREAD_COND_INITIALIZER), - m_isUp(false) { - pthread_mutex_init(&m_mutex, NULL); - pthread_cond_init(&m_cond, NULL); -} - -BinarySemaphore::~BinarySemaphore() { - pthread_cond_destroy(&m_cond); - pthread_mutex_destroy(&m_mutex); -} - -void BinarySemaphore::Wait() { - // try to get exclusive access to the flag - pthread_mutex_lock(&m_mutex); - // success: no other thread can get here unless - // the current thread unlocks the mutex - - // wait until the flag is up - while (!m_isUp) { - pthread_cond_wait(&m_cond, &m_mutex); - // when the current thread executes this, it will be - // blocked on m_cond, and automatically unlocks the - // mutex! Unlocking the mutex will let other threads - // in to test the flag. - } - - // here we know that flag is upand this thread has now - // successfully passed the semaphore - - // this will cause all other threads that execute the Wait() - // call to wait in the above loop - m_isUp = false; - - // release the exclusive access to the flag - pthread_mutex_unlock(&m_mutex); -} - -void BinarySemaphore::Notify() { - // try to get exclusive access to the flag - pthread_mutex_lock(&m_mutex); - - // this call may resume a thread that is blocked on m_cond - // (in the Wait() call). if there was none, this does nothing - pthread_cond_signal(&m_cond); - - // up the flag - m_isUp = true; - - // release the exclusive access to the flag - pthread_mutex_unlock(&m_mutex); -} - -#else - -/* Windows specific part for thread and mutex */ - -Thread::Thread(ThreadArg* arg) { - m_arg = arg; -} - -Thread::~Thread() { - delete m_arg; -} - -bool Thread::Start(bool detach) { - detach = detach; /* unused parameter */ - - m_id = CreateThread(NULL, /* default security attributes */ - 0, /* use default stack size */ - &Thread::Call, /* thread function name */ - this, /* argument to thread function */ - 0, /* use default creation flags */ - NULL); /* returns the thread identifier */ - - return m_id != NULL; -} - -bool Thread::Stop() { - return TerminateThread(m_id, (DWORD) - 1); -} - -bool Thread::Join(void** ret) { - DWORD val = 0; - WaitForSingleObject(m_id, INFINITE); - GetExitCodeThread(m_id, &val); - CloseHandle(m_id); - m_id = NULL; - *ret = (void*)val; - return true; -} - -DWORD WINAPI Thread::Call(LPVOID arg) { - Thread* thread = static_cast(arg); - - /* call our specific object method */ -#ifdef _WIN64 - return (DWORD64)thread->m_arg->Call(); -#else - return (DWORD)thread->m_arg->Call(); -#endif -} - -Mutex::Mutex() { - m_mutex = CreateMutex(NULL, /* no security attribute */ - 0, /* not initial owner (i.e. no first lock) */ - NULL); /* no name */ -} - -Mutex::~Mutex() { - /* free mutex */ - if (m_mutex) { - CloseHandle(m_mutex); - } -} - -bool Mutex::Lock() { - if (!m_mutex) { - return false; - } - - return (WaitForSingleObject(m_mutex, INFINITE) == WAIT_OBJECT_0); -} - -bool Mutex::Unlock() { - if (!m_mutex) { - return false; - } - - return ReleaseMutex(m_mutex); -} - -#endif - -} /* namespace System */ - diff --git a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/websocket_handler.cpp b/src/3rd_party-static/MessageBroker/src/lib_messagebroker/websocket_handler.cpp deleted file mode 100644 index 7d3890b7a8..0000000000 --- a/src/3rd_party-static/MessageBroker/src/lib_messagebroker/websocket_handler.cpp +++ /dev/null @@ -1,667 +0,0 @@ -/** - * \file websocket_handler.cpp - * \brief WebSocket Handler. - * \author AKara - */ - -#include - -#include -#include -#include - -#ifdef _WIN32 -#include -#endif//_WIN32 - -#include "websocket_handler.hpp" - -#include "libMBDebugHelper.h" -#include "md5.h" - -namespace NsMessageBroker -{ - - unsigned int CWebSocketHandler::parseWebSocketDataLength( - const char* Buffer, unsigned int& b_size) { - - unsigned char payload = - (unsigned char)((Buffer[1] & 0x40) | (Buffer[1] & 0x20) | - (Buffer[1] & 0x10) | (Buffer[1] & 0x08) | (Buffer[1] & 0x04) | - (Buffer[1] & 0x02) | (Buffer[1] & 0x01)); - unsigned long length = 0; - unsigned char position = 2; // current buffer position - - switch(payload) { - case 126: - { - length = (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - break; - } - case 127: - { - length = (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - length <<=8; - length |= (unsigned char)Buffer[position++]; - break; - } - default: - { - length = payload; - return length; - } - } - - return length; - } - - int CWebSocketHandler::parseWebSocketData(char* Buffer, unsigned int& b_size) { - // Please see RFC6455 standard protocol specification: - //http://tools.ietf.org/html/rfc6455 - // Chapter 5.2 - DBG_MSG(("CWebSocketHandler::parseWebSocketData()b_size = %d\n", b_size)); - char* recBuffer = Buffer; - unsigned int parsedBufferPosition = 0; - unsigned char position = 0; // current buffer position - unsigned int size = b_size; - - static uint32_t minimum_heade_size = 4; - while (minimum_heade_size < size) { - - bool fin = ((recBuffer[0] & 0x80) | (recBuffer[0] & 0x01)) == 0x81; - bool rsv1 = (recBuffer[0] & 0x40) == 0x40; - bool rsv2 = (recBuffer[0] & 0x20) == 0x20; - bool rsv3 = (recBuffer[0] & 0x10) == 0x10; - unsigned char opCode = ((recBuffer[0] & 0x08) | (recBuffer[0] & 0x04) | - (recBuffer[0] & 0x02) | (recBuffer[0] & 0x01)); - - bool mask = (recBuffer[1] & 0x80) == 0x80; - - DBG_MSG(("CWebSocketHandler::fin = %d recBuffer[0] = 0x%02X\n" - " parsedlength = %d b_size= %d parsedBufferPosition = %d\n" - "rsv1 = %d, rsv2 = %d, rsv3 = %d, opCode = %u\n", - fin, recBuffer[0], parsedBufferPosition + position, - size, parsedBufferPosition, rsv1, rsv2, rsv3, opCode)); - - if ((rsv1)|(rsv2)|(rsv3)) { - DBG_MSG(("rsv1 or rsv2 or rsv3 is 0 \n")); - break; - } - - switch(opCode) { - case 0x0: break; //Continuation frame - case 0x1: break; //Text Frame - case 0x2: break; //Binary Frame - case 0x8: break; //Connection close Frame - case 0x9: break; //ping Frame - case 0xA: break; //Pong Frame - default: break; //Unknown frame - } - - if (false == fin) { - break; - } - - unsigned char payload = (unsigned char) - ((recBuffer[1] & 0x40) | (recBuffer[1] & 0x20) | (recBuffer[1] & 0x10) | - (recBuffer[1] & 0x08) | (recBuffer[1] & 0x04) | (recBuffer[1] & 0x02) | - (recBuffer[1] & 0x01)); - - unsigned long length = parseWebSocketDataLength(recBuffer, size); - position = 2; - - if (length > size) { - DBG_MSG_ERROR(("Incomplete message")); - break; - } - - switch(payload) { - case 126: { - position +=2; - break; - } - case 127: { - position +=8; - break; - } - default: { - break; - } - } - - if (mask) { - unsigned char maskKeys[4]; - maskKeys[0] = recBuffer[position++]; - maskKeys[1] = recBuffer[position++]; - maskKeys[2] = recBuffer[position++]; - maskKeys[3] = recBuffer[position++]; - DBG_MSG(("CWebSocketHandler::parseWebSocketData()maskKeys[0]:0x%02X;" - "maskKeys[1]:0x%02X; maskKeys[2]:0x%02X; maskKeys[3]:0x%02X\n" - , maskKeys[0], maskKeys[1], maskKeys[2], maskKeys[3])); - for (unsigned long i = position; i < position+length; i++) - { - recBuffer[i] = recBuffer[i] ^ maskKeys[(i-position)%4]; - } - } - DBG_MSG(("CWebSocketHandler::parseWebSocketData()length:%d; size:%d;" - " position:%d\n", (int)length, size, position)); - - for (unsigned long i = 0; (i < size); i++) { - Buffer[parsedBufferPosition + i] = recBuffer[i+position]; - } - b_size -= position; - parsedBufferPosition += length; - recBuffer += length; - size -= length+position; - } - return b_size; - } - - int CWebSocketHandler::prepareWebSocketDataHeader(unsigned char* Buffer, - unsigned long long b_size) - { - unsigned int headerLength = 2; - unsigned char payload; - - memset(Buffer, 0, headerLength); - Buffer[0] = 0x81; // 129 - - if (b_size <= 125) - { - payload = b_size; - Buffer[1] = b_size; // string length - } else if (b_size >= 126 && b_size <= 65535) - { - headerLength += 2; - payload = 126; - Buffer[1] = 0x7E; // 126 - } else - { - headerLength += 8; - payload = 127; - Buffer[1] = 0x7F; // 127 - } - - - if (payload == 126) - { - Buffer[2] = (b_size>>8); - Buffer[3] = b_size; - } else if (payload == 127) - { - Buffer[9] = (b_size & 0xFF); - Buffer[8] = ((b_size>>8) & 0xFF); - Buffer[7] = ((b_size>>16) & 0xFF); - Buffer[6] = ((b_size>>24) & 0xFF); - Buffer[5] = ((b_size>>32) & 0xFF); - Buffer[4] = ((b_size>>40) & 0xFF); - Buffer[3] = ((b_size>>48) & 0xFF); - Buffer[2] = ((b_size>>56) & 0xFF); - } - return headerLength; -} - - void CWebSocketHandler::handshake_0405(std::string &key) - { - static const char *websocket_magic_guid_04 = - "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - char accept_buf[MAX_WEBSOCKET_04_KEY_LEN + 37]; - unsigned char hash[20] = {0xb3, 0x7a, 0x4f, 0x2c, 0xc0, 0x62, 0x4f, 0x16, 0x90, 0xf6, 0x46, 0x06, 0xcf, 0x38, 0x59, 0x45, 0xb2, 0xbe, 0xc4, 0xea}; - int accept_len; - - strncpy(accept_buf, key.c_str(), MAX_WEBSOCKET_04_KEY_LEN + 37); - strncpy(accept_buf + key.length(), websocket_magic_guid_04, - MAX_WEBSOCKET_04_KEY_LEN + 37 - strlen(key.c_str())); - - SHA1((unsigned char *)accept_buf, key.length() + strlen(websocket_magic_guid_04), hash); - - accept_len = lws_b64_encode_string((char *)hash, 20, accept_buf, sizeof accept_buf); - if (accept_len < 0) - { - fprintf(stderr, "Base64 encoded hash too long\n"); - } - fprintf(stderr, "accept_buf: %s\n", accept_buf); - key = accept_buf; - } - - void CWebSocketHandler::sha1_step(struct sha1_ctxt *ctxt) - { - unsigned int a, b, c, d, e; - size_t t, s; - unsigned int tmp; - - struct sha1_ctxt tctxt; - - memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60]; - - a = H(0); b = H(1); c = H(2); d = H(3); e = H(4); - - for (t = 0; t < 20; t++) - { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 20; t < 40; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 40; t < 60; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 60; t < 80; t++) - { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - memset(&ctxt->m.b8[0], 0, 64); - } - - void CWebSocketHandler::sha1_init(struct sha1_ctxt *ctxt) - { - memset(ctxt, 0, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; - } - - void CWebSocketHandler::sha1_pad(struct sha1_ctxt *ctxt) - { - size_t padlen; /*pad length in bytes*/ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) - { - memset(&ctxt->m.b8[padstart], 0, padlen); - COUNT += padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - memset(&ctxt->m.b8[padstart], 0, padlen - 8); - COUNT += (padlen - 8); - COUNT %= 64; - - PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]); - } - - void CWebSocketHandler::sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len) - { - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - off = 0; - - while (off < len) - { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } - } - - void CWebSocketHandler::sha1_result(struct sha1_ctxt *ctxt, unsigned char* digest0) - { - unsigned char *digest; - - digest = (unsigned char *)digest0; - sha1_pad(ctxt); - digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16]; - } - - /* - * This should look and work like the libcrypto implementation - */ - - unsigned char * CWebSocketHandler::SHA1(const unsigned char *d, size_t n, unsigned char *md) - { - struct sha1_ctxt ctx; - - sha1_init(&ctx); - sha1_loop(&ctx, d, n); - sha1_result(&ctx, (unsigned char*)md); - - return md; - } - - int CWebSocketHandler::lws_b64_encode_string(const char *in, int in_len, char *out, int out_size) - { - unsigned char triple[3]; - int i; - int len; - int line = 0; - int done = 0; - - while (in_len) - { - len = 0; - for (i = 0; i < 3; i++) - { - if (in_len) - { - triple[i] = *in++; - len++; - in_len--; - } else - triple[i] = 0; - } - if (len) - { - - if (done + 4 >= out_size) - return -1; - - *out++ = encode[triple[0] >> 2]; - *out++ = encode[((triple[0] & 0x03) << 4) | - ((triple[1] & 0xf0) >> 4)]; - *out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) | - ((triple[2] & 0xc0) >> 6)] : '='); - *out++ = (len > 2 ? encode[triple[2] & 0x3f] : '='); - - done += 4; - line += 4; - } - if (line >= 72) - { - - if (done + 2 >= out_size) - return -1; - - *out++ = '\r'; - *out++ = '\n'; - done += 2; - line = 0; - } - } - - if (done + 1 >= out_size) - return -1; - - *out++ = '\0'; - - return done; - } - - /* - * returns length of decoded string in out, or -1 if out was too small - * according to out_size - */ - - int CWebSocketHandler::lws_b64_decode_string(const char *in, char *out, int out_size) - { - int len; - int i; - int done = 0; - unsigned char v; - unsigned char quad[4]; - - while (*in) - { - - len = 0; - for (i = 0; i < 4 && *in; i++) - { - - v = 0; - while (*in && !v) - { - - v = *in++; - v = (v < 43 || v > 122) ? 0 : decode[v - 43]; - if (v) - v = (v == '$') ? 0 : v - 61; - if (*in) - { - len++; - if (v) - quad[i] = v - 1; - } else - quad[i] = 0; - } - } - if (!len) - continue; - - if (out_size < (done + len - 1)) - /* out buffer is too small */ - return -1; - - if (len >= 2) - *out++ = quad[0] << 2 | quad[1] >> 4; - if (len >= 3) - *out++ = quad[1] << 4 | quad[2] >> 2; - if (len >= 4) - *out++ = ((quad[2] << 6) & 0xc0) | quad[3]; - - done += len - 1; - } - - if (done + 1 >= out_size) - return -1; - - *out++ = '\0'; - - return done; - } - - int CWebSocketHandler::lws_b64_selftest(void) - { - char buf[64]; - int n; - unsigned int test; - static const char *plaintext[] = {"sanity check base 64"}; - static const char *coded[] = {"c2FuaXR5IGNoZWNrIGJhc2UgNjQ="}; - - for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) - { - - buf[sizeof(buf) - 1] = '\0'; - n = lws_b64_encode_string(plaintext[test], - strlen(plaintext[test]), buf, sizeof buf); - if (n != (int)strlen(coded[test]) || strcmp(buf, coded[test])) - { - fprintf(stderr, "Failed lws_b64 encode selftest " - "%d result '%s' %d\n", test, buf, n); - return -1; - } - - buf[sizeof(buf) - 1] = '\0'; - n = lws_b64_decode_string(coded[test], buf, sizeof buf); - if (n != (int)strlen(plaintext[test]) || - strcmp(buf, plaintext[test])) - { - fprintf(stderr, "Failed lws_b64 decode selftest " - "%d result '%s' %d\n", test, buf, n); - return -1; - } - } - - return 0; - } - - rawBytes CWebSocketHandler::handshake_hybi00(const std::string &key1, const std::string &key2, const rawBytes &key3) - { - if (key3.size() < 8) - { - DBG_MSG_ERROR(("key3's size is %d, less than 8 bytes\n", key3.size())); - return rawBytes(); - } - - unsigned long number1 = extractNumber(key1); - unsigned long number2 = extractNumber(key2); - DBG_MSG(("number1 is %ld, number2 is %ld\n", number1, number2)); - - if ((number1 == 0) || (number2 == 0)) - { - return rawBytes(); - } - - // represent the numbers in big-endian format (network-byte order) - unsigned long bigEndianNumber1 = htonl(number1); - unsigned long bigEndianNumber2 = htonl(number2); - - // the temporary key consists of bytes of the first and second numbers - // and the key3 - rawBytes key(8); - memcpy(&key[0], &bigEndianNumber1, 4); - memcpy(&key[4], &bigEndianNumber2, 4); - key.insert(key.end(), key3.begin(), key3.begin() + 8); - - MD5 md5(std::string(key.begin(), key.end())); - char digest[16]; - md5.getdigest(digest); - rawBytes resultBytes(&digest[0], &digest[16]); - - return resultBytes; - } - - unsigned long CWebSocketHandler::extractNumber(const std::string &key) const - { - // leave digits only - // and count the number of spaces in the key - std::string keyDigits; - int spacesCountKey = 0; - for (unsigned int index = 0; index < key.length(); ++index) - { - char keyChar = key[index]; - if (keyChar == ' ') - { - ++spacesCountKey; - } - else if (isdigit(keyChar)) - { - keyDigits += keyChar; - } - } - - unsigned long result = 0; - - // convert string to number - long long numberKey; - if (std::stringstream(keyDigits) >> numberKey) - { - if (spacesCountKey != 0) - { - if (numberKey % spacesCountKey == 0) - { - // divide the number by the count - result = numberKey / spacesCountKey; - } - else - { - // key is not an integral multiple of spaces count - } - } - else - { - // the denominator is 0 - } - } - else - { - // couldn't convert - } - - return result; - } - -} /* namespace NsMessageBroker */ - diff --git a/src/3rd_party-static/MessageBroker/src/server/mb_server.cpp b/src/3rd_party-static/MessageBroker/src/server/mb_server.cpp deleted file mode 100644 index 25ec7fc9f3..0000000000 --- a/src/3rd_party-static/MessageBroker/src/server/mb_server.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * \file mb_server.cpp - * \brief MessageBroker server. - * \author AKara - */ - -#include "mb_server.hpp" - -namespace NsMessageBroker { - -Server::Server(const std::string& address, uint16_t port) { - m_sock = -1; - m_address = address; - m_port = port; -} - -Server::~Server() { - if (m_sock != -1) { - Close(); - } -} - -int Server::GetSocket() const { - return m_sock; -} - -std::string Server::GetAddress() const { - return m_address; -} - -uint16_t Server::GetPort() const { - return m_port; -} - -bool Server::Bind() { - m_sock = networking::bind(m_protocol, m_address, m_port, NULL, NULL); - - return (m_sock != -1) ? true : false; -} - -void Server::Close() { - ::close(m_sock); - m_sock = -1; -} - -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/server/mb_tcpserver.cpp b/src/3rd_party-static/MessageBroker/src/server/mb_tcpserver.cpp deleted file mode 100644 index bdd7b2bfdf..0000000000 --- a/src/3rd_party-static/MessageBroker/src/server/mb_tcpserver.cpp +++ /dev/null @@ -1,331 +0,0 @@ -/** - * \file mb_tcpserver.cpp - * \brief MessageBroker TCP server. - * \author AKara - */ - -#include -#include -#include -#include -#include -#include - -#include "MBDebugHelper.h" - -#include "mb_tcpserver.hpp" -#include "CMessageBroker.hpp" - -namespace NsMessageBroker { - -TcpServer::TcpServer(const std::string& address, uint16_t port, NsMessageBroker::CMessageBroker* pMessageBroker) : - Server(address, port) { - m_protocol = networking::TCP; - mpMessageBroker = pMessageBroker; -} - -TcpServer::~TcpServer() { - if (m_sock != -1) { - Close(); - } -} - -ssize_t TcpServer::Send(int fd, const std::string& data) { - DBG_MSG(("Send to %d: %s\n", fd, data.c_str())); - std::string rep = data; - if (isWebSocket(fd)) { - unsigned char buf[10] = {'\0'}; - ssize_t headerlen = mWebSocketHandler.prepareWebSocketDataHeader( - (unsigned char*)buf, (unsigned long)rep.length()); - std::string header = std::string((char*)buf, headerlen); - rep = header + rep; - } - int bytesToSend = rep.length(); - const char* ptrBuffer = rep.c_str(); - do { - int retVal = send(fd, ptrBuffer, bytesToSend, MSG_NOSIGNAL); - if (retVal == -1) { - if (EPIPE == errno) { - m_purge.push_back(fd); - } - return -1; - } - bytesToSend -= retVal; - ptrBuffer += retVal; - } while (bytesToSend > 0); - return rep.length(); -} - -bool TcpServer::Recv(int fd) { - DBG_MSG(("TcpServer::Recv(%d)\n", fd)); - - std::string* pReceivingBuffer = getBufferFor(fd); - bool buffer_was_not_empty = pReceivingBuffer->size() > 0; - - std::vector buf; - buf.reserve(RECV_BUFFER_LENGTH + pReceivingBuffer->size()); - DBG_MSG(("Left in pReceivingBuffer: %d \n", - pReceivingBuffer->size())); - buf.assign(pReceivingBuffer->c_str(), - pReceivingBuffer->c_str() + pReceivingBuffer->size()); - buf.resize(RECV_BUFFER_LENGTH + pReceivingBuffer->size()); - - int received_bytes = recv(fd, &buf[pReceivingBuffer->size()], MAX_RECV_DATA, 0); - if (received_bytes <= 0) { - DBG_MSG(("Received %d bytes from %d; error = %d\n", - received_bytes, fd, errno)); - m_purge.push_back(fd); - return false; - } - - unsigned int nb = received_bytes; - std::vector last_msg_buf(buf.begin()+pReceivingBuffer->size(), - buf.begin()+pReceivingBuffer->size()+nb); - DBG_MSG(("Recieved %d from %d\n", nb, fd)); - nb += static_cast(pReceivingBuffer->size()); - DBG_MSG(("Recieved with buffer %d from %d\n", nb, fd)); - - if (nb > 0) { // This is redundant - if (isWebSocket(fd)) { - const unsigned int data_length = - mWebSocketHandler.parseWebSocketDataLength(&buf[0], nb); - - DBG_MSG(("Received %d actual data length %d\n", nb, data_length)); - - if (data_length > nb) { - DBG_MSG_ERROR(("Received %d actual data length %d\n", nb, data_length)); - DBG_MSG_ERROR(("Incomplete message")); - *pReceivingBuffer = std::string(&buf[0], nb); - return false; - } - mWebSocketHandler.parseWebSocketData(&buf[0], nb); - } - - *pReceivingBuffer = std::string(&buf[0], nb); - DBG_MSG(("pReceivingBuffer before onMessageReceived:%d : %s\n", - pReceivingBuffer->size(), pReceivingBuffer->c_str())); - - // we need to check for websocket handshake - if (!checkWebSocketHandShake(fd, pReceivingBuffer)) - { //JSON MESSAGE received. Send data in CMessageBroker. - if (mpMessageBroker) { - size_t buffer_size_before = pReceivingBuffer->size(); - mpMessageBroker->onMessageReceived(fd, *pReceivingBuffer, true); - - if (buffer_was_not_empty && (pReceivingBuffer->size() == buffer_size_before)) { - /* We couldn't parse the buffer (with the last message at the end) - * Try to parse ONLY the last message */ - DBG_MSG_ERROR(("Couldn't parse the whole buffer! Try only the last message.\n")); - - nb = static_cast(last_msg_buf.size()); - if (isWebSocket(fd)) { - const unsigned int data_length = - mWebSocketHandler.parseWebSocketDataLength(&last_msg_buf[0], nb); - if (data_length > nb) { - DBG_MSG_ERROR(("The last message may be incomplete. Don't do anything.\n")); - /* Should we replace the buffer with the last message? - * Probably not. It may not be a real websocket message. - * Wait for a full message. */ - return false; - } - mWebSocketHandler.parseWebSocketData(&last_msg_buf[0], nb); - } - - std::string last_message = std::string(&last_msg_buf[0], nb); - buffer_size_before = last_message.size(); - mpMessageBroker->onMessageReceived(fd, last_message, false); - if ( last_message.size() < buffer_size_before ) { - /* Parsing last message successful! Discard the old data and - * keep only what is left from the last message */ - DBG_MSG_ERROR(("Parsing last message successful! Discard the old data.\n")); - *pReceivingBuffer = last_message; - } - } - } else { - return false; - } - } else { // message is a websocket handshake - ssize_t webSocketKeyPos = pReceivingBuffer->find("Sec-WebSocket-Key: "); - if (-1 != webSocketKeyPos) { - std::string handshakeResponse = - "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\n" - "Connection: Upgrade\r\nSec-WebSocket-Accept: "; - std::string wsKey = pReceivingBuffer->substr(webSocketKeyPos + 19, 24); - mWebSocketHandler.handshake_0405(wsKey); - handshakeResponse += wsKey; - handshakeResponse += "\r\n\r\n"; - pReceivingBuffer->clear(); - std::list::iterator acceptedClientIt = - find(m_AcceptedClients.begin(), m_AcceptedClients.end(), fd); - if (m_AcceptedClients.end() != acceptedClientIt) { - m_AcceptedClients.erase(acceptedClientIt); - } - Send(fd, handshakeResponse); - m_WebSocketClients.push_back(fd); - } - } - } - return true; -} - -bool TcpServer::checkWebSocketHandShake(int fd, std::string* pReceivingBuffer) { - bool result = false; - std::list::iterator acceptedClientIt = find(m_AcceptedClients.begin(), m_AcceptedClients.end(), fd); - if (m_AcceptedClients.end() != acceptedClientIt) { - ssize_t httpheader = pReceivingBuffer->find("GET / HTTP/1.1"); - if (-1 != httpheader) { // here is a header - DBG_MSG(("HTTP header detected!\n")); - result = true; - } else { // not winsocket client - m_AcceptedClients.erase(acceptedClientIt); - } - } - DBG_MSG(("TcpServer::checkWebSocket(): %d!\n", result)); - return result; -} - -bool TcpServer::isWebSocket(int fd) { - bool result = false; - std::list::iterator wsClientIt = find(m_WebSocketClients.begin(), m_WebSocketClients.end(), fd); - if (m_WebSocketClients.end() != wsClientIt) { - result = true; - } - return result; -} - -std::string* TcpServer::getBufferFor(int fd) { - std::string* res = 0; - std::map ::iterator it; - it = m_receivingBuffers.find(fd); - if (it != m_receivingBuffers.end()) { - res = (*it).second; - } else { // create a new buffer... - res = new std::string(""); - printf("getBufferFor method!\n"); - m_receivingBuffers.insert(std::map::value_type(fd, res)); - } - - return res; -} - -void TcpServer::WaitMessage(uint32_t ms) { - fd_set fdsr; - struct timeval tv; - int max_sock = m_sock; - - tv.tv_sec = ms / 1000; - tv.tv_usec = (ms % 1000) / 1000; - - FD_ZERO(&fdsr); - -#ifdef _WIN32 - /* on Windows, a socket is not an int but a SOCKET (unsigned int) */ - FD_SET((SOCKET)m_sock, &fdsr); -#else - FD_SET(m_sock, &fdsr); -#endif - - for (std::map::iterator it = m_receivingBuffers.begin(); - it != m_receivingBuffers.end() ; it++) { -#ifdef _WIN32 - FD_SET((SOCKET)((*it).first), &fdsr); -#else - FD_SET(((*it).first), &fdsr); -#endif - - if (((*it).first) > max_sock) { - max_sock = ((*it).first); - } - } - - max_sock++; - - if (select(max_sock, &fdsr, NULL, NULL, ms ? &tv : NULL) > 0) { - if (FD_ISSET(m_sock, &fdsr)) { - Accept(); - } - - for (std::map::iterator it = m_receivingBuffers.begin(); - it != m_receivingBuffers.end() ; it++) { - if (FD_ISSET(((*it).first), &fdsr)) { - Recv((*it).first); - } - } - - /* remove disconnect socket descriptor */ - for (std::list::iterator it = m_purge.begin(); - it != m_purge.end() ; it++) { - std::map ::iterator itr; - itr = m_receivingBuffers.find((*it)); - if (itr != m_receivingBuffers.end()) - { // delete receiving buffer of disconnected client - mpMessageBroker->OnSocketClosed(itr->first); - delete itr->second; - m_receivingBuffers.erase(itr); - } - } - - /* purge disconnected list */ - m_purge.erase(m_purge.begin(), m_purge.end()); - } - else { - /* error */ - } -} - -bool TcpServer::Listen() const { - if (m_sock == -1) { - return false; - } - - if (listen(m_sock, 5) == -1) { - return false; - } - - return true; -} - -bool TcpServer::Accept() { - - int client = -1; - socklen_t addrlen = sizeof(struct sockaddr_storage); - - if (m_sock == -1) { - return false; - } - - client = accept(m_sock, 0, &addrlen); - - if (client == -1) { - return false; - } - - std::string* res = new std::string(""); - m_receivingBuffers.insert(std::map::value_type(client, res)); - m_AcceptedClients.push_back(client); - return true; -} - -void TcpServer::Close() { - /* close all client sockets */ - for (std::map::iterator it = m_receivingBuffers.begin(); - it != m_receivingBuffers.end() ; it++) { - ::close((*it).first); - if ((*it).second) { - delete(*it).second; - } - } - m_receivingBuffers.clear(); - Server::Close(); - /* listen socket should be closed in Server destructor */ -} - -void* TcpServer::MethodForThread(void* arg) { - arg = arg; - while (1) { - WaitMessage(1000); - } - return NULL; -} - -} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/MessageBroker/src/server/networking.cpp b/src/3rd_party-static/MessageBroker/src/server/networking.cpp deleted file mode 100644 index f054431690..0000000000 --- a/src/3rd_party-static/MessageBroker/src/server/networking.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * JsonRpc-Cpp - JSON-RPC implementation. - * Copyright (C) 2008-2011 Sebastien Vincent - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -/** - * \file networking.cpp - * \brief Networking utils. - * \author Sebastien Vincent - */ - -#include -#include - -#include "networking.h" - -namespace networking { -#ifdef _WIN32 -/** - * \var wsaData - * \brief MS Windows object to start - * networking stuff. - */ -static WSAData wsaData; -#endif - -bool init() { - bool ret = false; - -#ifdef _WIN32 - ret = (WSAStartup(MAKEWORD(2, 0), &wsaData) == 0); -#else - /* unix-like */ - ret = true; -#endif - - return ret; -} - -void cleanup() { -#ifdef _WIN32 - WSACleanup(); -#endif -} - -int connect(enum TransportProtocol protocol, - const std::string& address, - uint16_t port, struct sockaddr_storage* sockaddr, - socklen_t* addrlen) { - struct addrinfo hints; - struct addrinfo* res = NULL; - struct addrinfo* p = NULL; - char service[8]; - int sock = -1; - - if (!port || address == "") { - return -1; - } - - snprintf(service, sizeof(service), "%u", port); - service[sizeof(service) - 1] = 0x00; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = protocol == UDP ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = protocol; - hints.ai_flags = 0; - - if (getaddrinfo(address.c_str(), - service, &hints, &res) != 0) { - return -1; - } - - for (p = res ; p ; p = p->ai_next) { - sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - - if (sock == -1) { - continue; - } - - if (protocol == TCP && ::connect(sock, (struct sockaddr*)p->ai_addr, p->ai_addrlen) == -1) { - ::close(sock); - sock = -1; - continue; - } - - if (sockaddr) { - memcpy(sockaddr, p->ai_addr, p->ai_addrlen); - } - - if (addrlen) { - *addrlen = p->ai_addrlen; - } - - /* ok so now we have a socket bound, break the loop */ - break; - } - - freeaddrinfo(res); - p = NULL; - - return sock; -} - -int bind(enum TransportProtocol protocol, - const std::string& address, uint16_t port, - struct sockaddr_storage* sockaddr, socklen_t* addrlen) { - struct addrinfo hints; - struct addrinfo* res = NULL; - struct addrinfo* p = NULL; - char service[8]; - int sock = -1; - - if (!port || address == "") { - return -1; - } - - snprintf(service, sizeof(service), "%u", port); - service[sizeof(service) - 1] = 0x00; - - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = protocol == UDP ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = protocol; - hints.ai_flags = AI_PASSIVE; - - if (getaddrinfo(address.c_str(), service, &hints, &res) != 0) { - return -1; - } - - for (p = res ; p ; p = p->ai_next) { - int on = 1; - on = on; - - sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); - - if (sock == -1) { - continue; - } - -#ifndef _WIN32 - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); - - /* accept IPv6 OR IPv4 on the same socket */ - on = 1; - setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); -#else - on = 0; -#endif - - if (::bind(sock, p->ai_addr, p->ai_addrlen) == -1) { - ::close(sock); - sock = -1; - continue; - } - - if (sockaddr) { - memcpy(sockaddr, p->ai_addr, p->ai_addrlen); - } - - if (addrlen) { - *addrlen = p->ai_addrlen; - } - - /* ok so now we have a socket bound, break the loop */ - break; - } - - freeaddrinfo(res); - p = NULL; - - return sock; -} - -} /* namespace networking */ - diff --git a/src/3rd_party-static/encryption/CMakeLists.txt b/src/3rd_party-static/encryption/CMakeLists.txt index 3802c83cb5..5096f59c22 100644 --- a/src/3rd_party-static/encryption/CMakeLists.txt +++ b/src/3rd_party-static/encryption/CMakeLists.txt @@ -1,14 +1,43 @@ +# Copyright (c) 2015, Ford Motor Company +# 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 name of the Ford Motor Company nor the names of its 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. + +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + set(ENCRYPTION_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include) set(ENCRYPTION_INCLUDE_DIRECTORY ${ENCRYPTION_INCLUDE_DIRECTORY} PARENT_SCOPE) include_directories ( - ./include + ${ENCRYPTION_INCLUDE_DIRECTORY} ) -set (SOURCES - ./src/Base64.cpp - ./src/hashing.cc -) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") set (LIBRARIES crypto) diff --git a/src/3rd_party-static/jsoncpp/CMakeLists.txt b/src/3rd_party-static/jsoncpp/CMakeLists.txt index 04a4bd960c..ac273cfe7b 100644 --- a/src/3rd_party-static/jsoncpp/CMakeLists.txt +++ b/src/3rd_party-static/jsoncpp/CMakeLists.txt @@ -1,14 +1,42 @@ +# Copyright (c) 2016, Ford Motor Company +# 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 name of the Ford Motor Company nor the names of its 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. + +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + set(JSONCPP_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include) set(JSONCPP_INCLUDE_DIRECTORY ${JSONCPP_INCLUDE_DIRECTORY} PARENT_SCOPE) -include_directories ( - ./include/ +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/include ) -set (SOURCES - ./src/lib_json/json_value.cpp - ./src/lib_json/json_writer.cpp - ./src/lib_json/json_reader.cpp -) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/lib_json") -add_library("jsoncpp" ${SOURCES}) +add_library(jsoncpp ${SOURCES}) diff --git a/src/3rd_party-static/message_broker/CMakeLists.txt b/src/3rd_party-static/message_broker/CMakeLists.txt new file mode 100644 index 0000000000..348d050887 --- /dev/null +++ b/src/3rd_party-static/message_broker/CMakeLists.txt @@ -0,0 +1,78 @@ +# Copyright (c) 2016, Ford Motor Company +# 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 name of the Ford Motor Company nor the names of its 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. + +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + +set(MESSAGE_BROKER_INCLUDE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(MESSAGE_BROKER_INCLUDE_DIRECTORY ${MESSAGE_BROKER_INCLUDE_DIRECTORY} PARENT_SCOPE) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${JSONCPP_INCLUDE_DIRECTORY} +) + +set(CLIENT_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/src/client +) +collect_sources(CLIENT_SOURCES "${CLIENT_PATHS}") + +set(SERVER_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/src/server +) +collect_sources(SERVER_SOURCES "${SERVER_PATHS}") + +set(EXCLUDE_PATHS + ${CLIENT_PATHS} + ${SERVER_PATHS} + ${CMAKE_CURRENT_SOURCE_DIR}/src/example +) + +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") + +set(LIBRARIES + Utils +) + +add_library(message_broker ${SOURCES}) +target_link_libraries(message_broker ${LIBRARIES}) + +list(APPEND LIBRARIES + message_broker +) + +add_library(message_broker_client ${CLIENT_SOURCES}) +target_link_libraries(message_broker_client ${LIBRARIES}) + +add_library(message_broker_server ${SERVER_SOURCES}) +target_link_libraries(message_broker_server ${LIBRARIES}) diff --git a/src/3rd_party-static/message_broker/include/CMessageBroker.hpp b/src/3rd_party-static/message_broker/include/CMessageBroker.hpp new file mode 100644 index 0000000000..c542043796 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/CMessageBroker.hpp @@ -0,0 +1,108 @@ +/** + * \file CMessageBroker.hpp + * \brief CMessageBroker singletone class header. + * \author AKara + */ + +#ifndef CMESSAGEBROKER_H +#define CMESSAGEBROKER_H + +#include + +#include "CSender.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \enum ErrorCode + * \brief MessageBroker error codes. + * \note Value from -32099 to -32000 are reserved for implementation-defined server-errors. + */ + enum ErrorCode + { + CONTROLLER_EXISTS = -32000, /**< Controller has been already registered. */ + SUBSCRIBTION_EXISTS = -32001, /**< Property has been already subscribed by this controller. */ + PARSING_ERROR = -32700, /**< Invalid JSON. An error occurred on the server while parsing the JSON text. */ + INVALID_REQUEST = -32600, /**< The received JSON not a valid MessageBroker Request. */ + METHOD_NOT_FOUND = -32601, /**< The requested remote-procedure does not exist / is not available. */ + INVALID_PARAMS = -32602, /**< Invalid method parameters. */ + INTERNAL_ERROR = -32603, /**< Internal MessageBroker error. */ + UNSUPPORTED_RESOURCE = 2 /**< Controller doesn't registered. */ + }; + + /** + * \brief Forward declaration of the private class. + */ + class CMessageBroker_Private; + + /** + * \class CMessageBroker + * \brief Singletone CMessageBroker class implementation. + */ + class CMessageBroker + { + public: + /** + * \brief Singletone instantiator. + * \return pointer to CMessageBroker instance. + */ + static CMessageBroker* getInstance(); + + /** + * \brief Destructor. + */ + ~CMessageBroker(); + + /** + * \brief Receive data from TCP server (from client). + * \param fd FileDescriptor of socket. + * \param aJSONData JSON string. + * \param tryHard give up on first JSON parse error or try to workaround it. + */ + void onMessageReceived(int fd, std::string& aJSONData, bool tryHard); + + /** + * \brief Test of buffer parsing. + */ + void Test(); + + /** + * @brief OnSocketClosed should be called if socked is closed by HMI + * @param fd socket descriptor + */ + void OnSocketClosed(const int fd); + + /** + * \brief Starts MessageBroker. + */ + void startMessageBroker(CSender* pSender); + + /** + * \brief Stops MessageBroker. + */ + void stopMessageBroker(); + + /** + * \brief Method for thread with que processing. + */ + void* MethodForThread(void * arg); + + private: + /** + * \brief Private constructor. + */ + CMessageBroker(); + + /** + * \brief The PIMPL of the class. + */ + CMessageBroker_Private *p; + }; +} /* namespace NsMessageBroker */ + +#endif // CMESSAGEBROKER_H + diff --git a/src/3rd_party-static/message_broker/include/CMessageBrokerRegistry.hpp b/src/3rd_party-static/message_broker/include/CMessageBrokerRegistry.hpp new file mode 100644 index 0000000000..001f978bbf --- /dev/null +++ b/src/3rd_party-static/message_broker/include/CMessageBrokerRegistry.hpp @@ -0,0 +1,113 @@ +#ifndef CMESSAGEBROKERREGISTRY_H +#define CMESSAGEBROKERREGISTRY_H + +#include +#include +#include +#include +#include "utils/lock.h" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class CMessageBrokerRegistry + * \brief Singletone CMessageBrokerRegistry class implementation. + */ + class CMessageBrokerRegistry + { + public: + /** + * \brief Singletone instantiator. + * \return pointer to CMessageBroker instance + */ + static CMessageBrokerRegistry* getInstance(); + + /** + * \brief Destructor. + */ + ~CMessageBrokerRegistry(); + + /** + * \brief adds controller to the registry. + * \param fd file descriptor of controller. + * \param name name of controller. + * \return false if already exist. + */ + bool addController(int fd, std::string name); + + /** + * \brief deletes controller from the registry. + * \param name name of controller. + */ + void deleteController(std::string name); + + /** + * \brief Remove all controllers by descriptor + * \param fd descriptor + */ + void removeControllersByDescriptor(const int fd); + + /** + * \brief Remove all subscribers by descriptor + * \param fd descriptor + */ + void removeSubscribersByDescriptor(const int fd); + + /** + * \brief adds notification subscriber to the registry. + * \param fd file descriptor of controller. + * \param name name of property which should be observed. + * \return false if already exist. + */ + bool addSubscriber(int fd, std::string name); + + /** + * \brief deletes notification subscriber from the registry. + * \param fd file descriptor of controller. + * \param name name of property which should be observed. + */ + void deleteSubscriber(int fd, std::string name); + + /** + * \brief gets controller fd from the registry by name. + * \param name name of controller. + * \return file descriptor of controller. + */ + int getDestinationFd(std::string name); + + /** + * \brief gets subscribers fd's. + * \param name name of property. + * \param result vector for results. + * \return count of subscribers. + */ + int getSubscribersFd(std::string name, std::vector& result); + private: + /** + * \brief Constructor. + */ + CMessageBrokerRegistry(); + + /** + * \brief Map to store controllers information like ComponentName:socketFd. + * For example PhoneController:1080 + */ + std::map mControllersList; + sync_primitives::Lock mControllersListLock; + + /** + * \brief Map to store subscribers information like ComponentName.PropertyName:socketFd:. + * For example PhoneController.onPhoneBookChanged:1080 + */ + std::multimap mSubscribersList; + sync_primitives::Lock mSubscribersListLock; + }; +} /* namespace NsMessageBroker */ + +#endif // CMESSAGEBROKERREGISTRY_H + diff --git a/src/3rd_party-static/message_broker/include/CSender.hpp b/src/3rd_party-static/message_broker/include/CSender.hpp new file mode 100644 index 0000000000..78faf7dad2 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/CSender.hpp @@ -0,0 +1,53 @@ +/** + * \file CSender.hpp + * \brief CSender class header. + * \author AKara + */ + +#ifndef CSENDER_H +#define CSENDER_H + +#if _MSC_VER >= 1400 // VC++ 8.0 +typedef int ssize_t; +#endif + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class CSender + * \brief CSender interface class implementation. + */ + class CSender + { + public: + /** + * \brief Constructor. + */ + CSender() + { + } + + /** + * \brief Destructor. + */ + ~CSender() + { + } + + /** + * \brief Send data. + * \param fd file descriptor of the client TCP socket + * \param data data to send + * \return number of bytes sent or -1 if error + */ + virtual ssize_t Send(int fd, const std::string& data)=0; + }; +} /* namespace NsMessageBroker */ + +#endif // CSENDER_H + + diff --git a/src/3rd_party-static/message_broker/include/MBDebugHelper.h b/src/3rd_party-static/message_broker/include/MBDebugHelper.h new file mode 100644 index 0000000000..fa835da3f0 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/MBDebugHelper.h @@ -0,0 +1,40 @@ +/** + * \file MBDebugHelper.h + * \brief DebugHelper. + * \author AKara + */ + +#ifndef MB_DEBUG_HELPER_H +#define MB_DEBUG_HELPER_H + +#include + +/** +* \def DEBUG_ON +* \brief Switches on debug messages. +*/ +//#define DEBUG_ON + +#ifdef DEBUG_ON +/** +* \def DBG_MSG +* \brief Debug message output with file name and line number. +* \param x formatted debug message. +* \return printf construction. +*/ +#define DBG_MSG(x) printf("%s:%d ", __FILE__, __LINE__);\ + printf x +#else +#define DBG_MSG(x) +#endif + +/** +* \def DBG_MSG_ERROR +* \brief Debug ERROR message output with file name and line number. +* \param x formatted debug message. +* \return printf construction. +*/ +#define DBG_MSG_ERROR(x) printf("ERROR!!! %s:%d ", __FILE__, __LINE__);\ + printf x + +#endif /*MB_DEBUG_HELPER_H*/ diff --git a/src/3rd_party-static/message_broker/include/mb_client.hpp b/src/3rd_party-static/message_broker/include/mb_client.hpp new file mode 100644 index 0000000000..cd70a31cd8 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/mb_client.hpp @@ -0,0 +1,135 @@ +/** + * \file mb_client.hpp + * \brief MessageBroker client. + * \author AKara + */ + +#ifndef MB_CLIENT_H +#define MB_CLIENT_H + +#if _MSC_VER >= 1400 // VC++ 8.0 +typedef int ssize_t; +#endif + +#include "networking.h" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class Client + * \brief Abstract MessageBroker client. + */ + class Client + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN to contact + * \param port remote local port to contact + */ + Client(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + virtual ~Client(); + + /** + * \brief Get socket descriptor. + * \return socket descriptor. + */ + int GetSocket() const; + + /** + * \brief Get the address. + * \return address or FQDN + */ + std::string GetAddress() const; + + /** + * \brief Get the port. + * \return local port + */ + uint16_t GetPort() const; + + /** + * \brief Connect to the remote machine + * \return true if success, false otherwise + * \note on connectionless protocol like UDP, this function + * always returns true even if remote peer is not reachable. + */ + virtual bool Connect(); + + /** + * \brief Receive data from the network. + * \param data if data is received it will put in this reference + * \return number of bytes received or -1 if error + * \note This method will blocked until data comes. + */ + virtual ssize_t Recv(std::string& data) = 0; + + /** + * \brief Close socket. + */ + virtual void Close(); + + protected: + /** + * \brief Socket descriptor. + */ + int m_sock; + + /** + * \brief Transport protocol of the socket. + */ + enum networking::TransportProtocol m_protocol; + + /** + * \brief Remote socket address. + */ + struct sockaddr_storage m_sockaddr; + + /** + * \brief Remote socket address length. + */ + socklen_t m_sockaddrlen; + + /** + * \brief Protected constructor so our inherited classes + * don't need to call the default constructor + */ + Client(); + + /** + * \brief Protected SetAddress so out inherited classes + * don't need to call the default constructor + */ + void SetAddress(const std::string& address); + + /** + * \brief Protected SetPort so out inherited classes + * don't need to call the default constructor + */ + void SetPort(uint16_t port); + + private: + + /** + * \brief Network address or FQDN. + */ + std::string m_address; + + /** + * \brief Local port. + */ + uint16_t m_port; + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_CLIENT_H */ diff --git a/src/3rd_party-static/message_broker/include/mb_controller.hpp b/src/3rd_party-static/message_broker/include/mb_controller.hpp new file mode 100644 index 0000000000..2d196aced2 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/mb_controller.hpp @@ -0,0 +1,253 @@ +/** + * \file mb_controller.hpp + * \brief MessageBroker Controller. + * \author AKara + */ + +#ifndef MB_CONTROLLER_H +#define MB_CONTROLLER_H + +#include + +#include "json/json.h" + +#include "mb_tcpclient.hpp" +#include "utils/lock.h" +#include "utils/atomic_object.h" + +#include + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + *\class CMessageBrokerController + * \brief MessageBroker Controller. + */ + class CMessageBrokerController : public TcpClient + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + * \param name name of component + */ + CMessageBrokerController(const std::string& address, uint16_t port, std::string name); + + + /** + * \brief Destructor. + */ + ~CMessageBrokerController(); + + /** + * \brief Receive data from the network. + * \param data if data is received it will put in this reference + * \return number of bytes received or -1 if error + * \note This method will blocked until data comes. + */ + virtual ssize_t Recv(std::string& data); + + /** + * \brief Send data. + * \param data data to send + * \return number of bytes sent or -1 if error + */ + ssize_t Send(const std::string& data); + + /** + * \brief send Json message. + * \param message JSON message. + */ + void sendJsonMessage(Json::Value& message); + + /** + * \brief generates new message id from diapason mControllersIdStart - (mControllersIdStart+999). + * \return next id for message + */ + int getNextMessageId(); + + /** + * \brief generates new message with id, jsonrpc version. + * \param root container for prepared message + */ + void prepareMessage(Json::Value& root); + + /** + * \brief generates new message with id, jsonrpc version. + * \note Doesn't change/add fields id and jsonrpc + * \param errCode error code + * \param errMessage string of message + * \param error container for prepared error message + */ + void prepareErrorMessage(int errCode, std::string errMessage, Json::Value& error); + + /** + * \brief gets destination component name. + * \param root JSON message. + * \return string destination component name. + */ + std::string getDestinationComponentName(Json::Value& root); + + /** + * \brief gets method name. + * \param root JSON message. + * \return string method name. + */ + std::string getMethodName(Json::Value& root); + + /** + * \brief checks is message notification or not. + * \param root JSON message. + * \return true if notification. + */ + bool isNotification(Json::Value& root); + + /** + * \brief checks is message response or not. + * \param root JSON message. + * \return true if response. + */ + bool isResponse(Json::Value& root); + + /** + * \brief searches Method by id in mWaitResponseQueue. + * \param id id of incoming JSON message. + * \return string method name or "" in case not found. + */ + std::string findMethodById(std::string id); + + /** + * \brief register controller on the server. + * \param id message id for JSON message due the id diapason hasn't been received. + */ + void registerController(int id = 0); + + /** + * \brief unregister controller on the server. + */ + void unregisterController(); + + /** + * \brief subscribes controller to the property changing. + * \param property property name in format ComponentName.PropertyName. + */ + void subscribeTo(std::string property); + + /** + * \brief unsubscribes controller from the property changing. + * \param property property name in format ComponentName.PropertyName. + */ + void unsubscribeFrom(std::string property); + + /** + * \brief pure virtual method to process response. + * \param method method name which has been called. + * \param root JSON message. + */ + virtual void processResponse(std::string method, Json::Value& root) = 0; + + /** + * \brief pure virtual method to process request. + * \param root JSON message. + */ + virtual void processRequest(Json::Value& root) = 0; + + /** + * \brief Process notification message. + * \brief Notify subscribers about property change. + * expected notification format example: + * \code + * {"jsonrpc": "2.0", "method": ".", "params": } + * \endcode + * \param root JSON message. + */ + virtual void processNotification(Json::Value& root) = 0; + + /** + * \brief Checks message. + * \param root JSON message. + * \param error JSON message to fill in case of any errors. + * \return true if message is good. + */ + bool checkMessage(Json::Value& root, Json::Value& error); + + /** + * \brief Returns name of Controller. + * \return name of controller. + */ + std::string getControllersName(); + + /** + * \brief Method for receiving thread. + */ + void* MethodForReceiverThread(void * arg); + + virtual void exitReceivingThread() { + Close(); + stop = true; + } + + protected: + /** + * @brief flag top stop thread + */ + sync_primitives::atomic_bool stop; + + private: + /** + * \brief Method for receiving messages without tcp packeting. + * \param message received data + */ + void onMessageReceived(Json::Value message); + /** + * \brief Start value of id's diapason. + */ + std::string m_receivingBuffer; + + /** + * \brief Start value of id's diapason. + */ + int mControllersIdStart; + + /** + * \brief Current id's value. + */ + int mControllersIdCurrent; + + /** + * \brief Already sent messages Methods to recognize esponses: MessageId:MethodName. + */ + std::map mWaitResponseQueue; + + /** + * \brief Name of component. + */ + std::string mControllersName; + + /** + * \brief JSON reader. + */ + Json::Reader m_reader; + + /** + * \brief JSON writer. + */ + Json::FastWriter m_writer; + + /** + * \brief JSON writer. + */ + Json::FastWriter m_receiverWriter; + /* + * @brief mutex for mWaitResponseQueue + */ + sync_primitives::Lock queue_lock_; + }; +} /* namespace NsMessageBroker */ +#endif /* MB_CONTROLLER_H */ diff --git a/src/3rd_party-static/message_broker/include/mb_server.hpp b/src/3rd_party-static/message_broker/include/mb_server.hpp new file mode 100644 index 0000000000..684a89055a --- /dev/null +++ b/src/3rd_party-static/message_broker/include/mb_server.hpp @@ -0,0 +1,121 @@ +/** + * \file mb_server.hpp + * \brief MessageBroker server. + * \author AKara + */ + +#ifndef MB_SERVER_H +#define MB_SERVER_H + +#include "networking.h" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class Server + * \brief Abstract MessageBroker server. + */ + class Server + { + public: + /** + * \brief Constructor. + * \param address network address or FQDN to bind + * \param port local port to bind + */ + Server(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + virtual ~Server(); + + /** + * \brief Wait message. + * + * This function do a select() on the socket and Process() immediately + * the message. + * \param ms millisecond to wait (0 means infinite) + */ + virtual void WaitMessage(uint32_t ms) = 0; + + /** + * \brief Get socket descriptor. + * \return socket descriptor. + */ + int GetSocket() const; + + /** + * \brief Get the address. + * \return address or FQDN + */ + std::string GetAddress() const; + + /** + * \brief Get the port. + * \return local port + */ + uint16_t GetPort() const; + + /** + * \brief Bind the socket. + * \return true if success, false otherwise + */ + bool Bind(); + + /** + * \brief Receive data from the network and process it. + * \param fd file descriptor on which receive + * \return true if message has been correctly received, processed and + * response sent, false otherwise (mainly send/receive error) + * \note This method will blocked until data comes. + */ + virtual bool Recv(int fd) = 0; + + /** + * \brief Close socket. + * \note It should be overriden for connection-oriented protocol + * like TCP to properly close all client sockets. + */ + virtual void Close(); + + protected: + /** + * \brief Socket descriptor. + */ + int m_sock; + + /** + * \brief Transport protocol of the socket. + */ + enum networking::TransportProtocol m_protocol; + + /** + * \brief Transport protocol of the socket. + */ + + private: + /** + * \brief Network address or FQDN. + */ + std::string m_address; + + /** + * \brief Local port. + */ + uint16_t m_port; + + /** + * \brief Encapsulated format. + */ + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_SERVER_H */ + diff --git a/src/3rd_party-static/message_broker/include/mb_tcpclient.hpp b/src/3rd_party-static/message_broker/include/mb_tcpclient.hpp new file mode 100644 index 0000000000..07697dbde7 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/mb_tcpclient.hpp @@ -0,0 +1,58 @@ +/** + * \file mb_tcpclient.hpp + * \brief MessageBroker TCP client. + * \author AKara + */ + +#ifndef MB_TCPCLIENT_H +#define MB_TCPCLIENT_H + +#include + +#include "mb_client.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + + /** + * \class TcpClient + * \brief MessageBroker TCP client. + */ + class TcpClient : public Client + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + */ + TcpClient(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + virtual ~TcpClient(); + + /** + * \brief Receive data from the network. + * \param data if data is received it will put in this reference + * \return number of bytes received or -1 if error + * \note This method will blocked until data comes. + */ + virtual ssize_t Recv(std::string& data); + + /** + * \brief Send data. + * \param data data to send + * \return number of bytes sent or -1 if error + */ + ssize_t Send(const std::string& data); + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_TCPCLIENT_H */ diff --git a/src/3rd_party-static/message_broker/include/mb_tcpserver.hpp b/src/3rd_party-static/message_broker/include/mb_tcpserver.hpp new file mode 100644 index 0000000000..8ab2ce6a6d --- /dev/null +++ b/src/3rd_party-static/message_broker/include/mb_tcpserver.hpp @@ -0,0 +1,150 @@ +/** + * \file mb_tcpserver.hpp + * \brief MessageBroker TCP server. + * \author AKara + */ + +#ifndef MB_TCPSERVER_H +#define MB_TCPSERVER_H + +#include +#include + +#include "mb_server.hpp" +#include "CMessageBroker.hpp" +#include "CSender.hpp" +#include "websocket_handler.hpp" + +#define RECV_BUFFER_LENGTH 4097 +#define MAX_RECV_BUFFER_LENGTH 100000 +#define MAX_RECV_DATA 4096 + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class TcpServer + * \brief MessageBroker TCP server implementation. + */ + class TcpServer : public Server, public CSender + { + public: + /** + * \brief Constructor. + * \param address network address or FQDN to bind + * \param port local port to bind + * \param pMessageBroker pointer to MessageBroker + */ + TcpServer(const std::string& address, uint16_t port, NsMessageBroker::CMessageBroker* pMessageBroker); + + /** + * \brief Destructor. + */ + virtual ~TcpServer(); + + /** + * \brief Receive data from the network and process it. + * \param fd socket descriptor to receive data + * \return true if message has been correctly received, processed and + * response sent, false otherwise (mainly send/recv error) + * \note This method will blocked until data comes. + */ + virtual bool Recv(int fd); + + /** + * \brief Send data. + * \param fd file descriptor of the client TCP socket + * \param data data to send + * \return number of bytes sent or -1 if error + */ + virtual ssize_t Send(int fd, const std::string& data); + + /** + * \brief Wait message. + * + * This function do a select() on the socket and Process() immediately + * the message. + * \param ms millisecond to wait (0 means infinite) + */ + virtual void WaitMessage(uint32_t ms); + + /** + * \brief Put the TCP socket in LISTEN state. + */ + bool Listen() const; + + /** + * \brief Accept a new client socket. + * \return -1 if error, 0 otherwise + */ + bool Accept(); + + /** + * \brief Close listen socket and all client sockets. + */ + void Close(); + + /** + * \brief Method for thread with WaitMessage. + */ + void* MethodForThread(void * arg); + + private: + /** + * \brief Checks if incoming messages are websocket request. + * \param fd + * \param pReceivingBuffer string receiving buffer pointer + * \return true if it is a websocket handshake + */ + bool checkWebSocketHandShake(int fd, std::string* pReceivingBuffer); + + /** + * \brief Checks if incoming messages are websocket request. + * \param fd file descriptor of the client TCP socket + * \return true if it is a websocket + */ + bool isWebSocket(int fd); + + /** + * \brief Gets buffer for socket which received data. + * \param fd socket file descriptor + */ + std::string* getBufferFor(int fd); + private: + /** + * \brief WebSocket clients fd's list. + */ + std::list m_WebSocketClients; + + /** + * \brief Just accepted clients fd's list. + */ + std::list m_AcceptedClients; + + /** + * \brief Receiving buffers map SocketFd:bufferPointer. + */ + std::map m_receivingBuffers; + + /** + * \brief List of disconnected sockets to be purged. + */ + std::list m_purge; + + /** + * \brief MessageBroker pointer. + */ + NsMessageBroker::CMessageBroker* mpMessageBroker; + + /** + * \brief WebSocket handler. + */ + CWebSocketHandler mWebSocketHandler; + }; + +} /* namespace NsMessageBroker */ + +#endif /* MB_TCPSERVER_H */ diff --git a/src/3rd_party-static/message_broker/include/networking.h b/src/3rd_party-static/message_broker/include/networking.h new file mode 100644 index 0000000000..a08853bb31 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/networking.h @@ -0,0 +1,139 @@ +/* + * JsonRpc-Cpp - JSON-RPC implementation. + * Copyright (C) 2008-2011 Sebastien Vincent + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * \file networking.h + * \brief Networking utils. + * \author Sebastien Vincent + */ + +#ifndef NETWORKING_H +#define NETWORKING_H + +#ifdef _WIN32 + +#ifndef _MSC_VER +#include +#endif //_MSC_VER + +#include +#include + +#if _MSC_VER >= 1400 // VC++ 8.0 +typedef unsigned short uint16_t; +typedef unsigned long uint32_t; +#define snprintf _snprintf +#endif //_MSC_VER >= 1400 + +/* to use getaddrinfo, _WIN32_WINNT have to + * equal at least 0x0501 + */ +#define OLD_WIN32_WINNT _WIN32_WINNT + +#if (_WIN32_WINNT < 0x0501) +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x501 +#endif //(_WIN32_WINNT < 0x0501) + +#include + +#if (_WIN32_WINNT != OLD_WIN32_WINNT) +#undef _WIN32_WINNT +#define _WIN32_WINNT OLD_WIN32_WINNT +#endif //(_WIN32_WINNT != OLD_WIN32_WINNT) + +typedef int socklen_t; +#define close closesocket + +#else //_WIN32 + +#include + +#include +#include +#include + +#include + +#include + +#include + +#endif //_WIN32 + +#include + +/** + * \namespace networking + * \brief Networking related functions. + */ +namespace networking +{ + /** + * \enum TransportProtocol + * \brief Transport protocol. + */ + enum TransportProtocol + { + UDP = IPPROTO_UDP, /**< UDP protocol. */ + TCP = IPPROTO_TCP /**< TCP protocol. */ + }; + + /** + * \brief Initialize networking. + * \return true if network is correctly initialized, false otherwise + * \note On MS Windows, this step is mandatory to use + * socket API (socket(), bind(), recvfrom(), ...). + */ + bool init(); + + /** + * \brief Cleanup networking. + * \note On MS Windows, after calling this function, + * it will be impossible to use socket API. + */ + void cleanup(); + + /** + * \brief Connect to remote machine. + * \param protocol transport protocol used + * \param address remote address + * \param port remote port + * \param sockaddr if function succeed, sockaddr + * representation of address/port + * \param addrlen if function succeed, length of sockaddr + * \return socket descriptor if success, -1 otherwise + */ + int connect(enum TransportProtocol protocol, const std::string& address, uint16_t port, struct sockaddr_storage* sockaddr, socklen_t* addrlen); + + /** + * \brief Bind on a local address. + * \param protocol transport protocol used + * \param address local address + * \param port local port + * \param sockaddr if function succeed, sockaddr + * representation of address/port + * \param addrlen if function succeed, length of sockaddr + * \return socket descriptor if success, -1 otherwise + */ + int bind(enum TransportProtocol protocol, const std::string& address, uint16_t port, struct sockaddr_storage* sockaddr, socklen_t* addrlen); + +} /* namespace networking */ + +#endif /* NETWORKING_H */ + diff --git a/src/3rd_party-static/message_broker/include/system.h b/src/3rd_party-static/message_broker/include/system.h new file mode 100644 index 0000000000..fac4f7926b --- /dev/null +++ b/src/3rd_party-static/message_broker/include/system.h @@ -0,0 +1,320 @@ +/** + * \file system.h + * \brief System utils. + * \author Sebastien Vincent + */ + +#ifndef SYSTEM_H +#define SYSTEM_H + +#ifdef _WIN32 + +#include + +#else + +#include + +#endif + +/** + * \namespace System + * \brief System related class (thread, ...). + */ +namespace System +{ + + /** + * \brief Sleep for x milliseconds + * \param ms millisecond to sleep + */ + void msleep(unsigned long ms); + + /** + * \class ThreadArg + * \brief Abstract class to represent thread argument. + * \see ThreadArgImpl + * \see Thread + */ + class ThreadArg + { + public: + /** + * \brief Destructor. + */ + virtual ~ThreadArg(); + + /** + * \brief Call the method. + * \note Have to be implemented by subclasses + */ + virtual void* Call() = 0; + }; + + /** + * \class ThreadArgImpl + * \brief Template class that represent thread argument. + * + * This class is used to provide callback function within + * an object. The method which will be called during thread + * execution must be of the form void* MyMethod(void* arg). + * Inside this method you are free to called any method of the object. + * + * \warning As class keep pointer of object reference, you should take + * care at the lifetime of object you pass in ThreadArgImpl constructor, + * else it could lead to crash your program.\n See Thread class documentation + * for an example of how to use ThreadArgImpl class. + * \see Thread + */ + template class ThreadArgImpl : public ThreadArg + { + public: + /** + * \typedef Method + * \brief T method signature. + */ + typedef void* (T::*Method)(void*); + + /** + * \brief Constructor. + * \param obj object + * \param method class method + * \param arg argument to method + */ + ThreadArgImpl(T& obj, Method method, void* arg) + { + m_obj = &obj; + m_method = method; + m_arg = arg; + } + + /** + * \brief Call the method. + */ + virtual void* Call() + { + return (m_obj->*m_method)(m_arg); + } + + private: + /** + * \brief Object pointer. + */ + T* m_obj; + + /** + * \brief Method of T class. + */ + Method m_method; + + /** + * \brief Argument of method. + */ + void* m_arg; + }; + + /** + * \class Thread + * \brief Thread implementation. + * + * Preferred use of this class is to construct ThreadArgImpl inside + * another class and pass *this as obj parameter:\n + * \n + * \code + * class MyClass + * { + * public: + * void MyMethod() + * { + * ThreadArg* arg = new ThreadArgImpl(*this, &MyClass::MethodForThread, NULL); + * Thread th(arg); + * th.Start(); + * } + * + * void* MethodForThread(void * arg) + * { + * // do stuff + * } + * }; + * \endcode + * + */ + class Thread + { + public: + /** + * \brief Constructor. + * \param arg thread argument (MUST be dynamically allocated using new) + * \note System::Thread object takes care of freeing method memory.\n + * The way of calling constructor is: + * + * Thread thread(new ThreadArgImpl(instanceOfMyClass, &MyClass::Method)); + * + * \warning You should take care of the object (instanceOfMyClass) lifetime pass + * into ThreadArgImpl constructor, else it could lead to a crash because ThreadArgImpl + * keep pointer of the reference. + * \warning The "arg" parameter MUST be dynamically allocated (using new). + * \see ThreadArgImpl + */ + Thread(ThreadArg* arg); + + /** + * \brief Destructor. + */ + virtual ~Thread(); + + /** + * \brief Start thread. + * \param detach if set to true, the thread will be in detach state so + * you do not have to call join on this type of thread. + * \return true if success, false otherwise + * \warning Do NOT Join a detached thread. + */ + bool Start(bool detach); + + /** + * \brief Stop thread. + * \return true if success, false otherwise + * \warning Calling this method could lead callback object to an + * incoherent state. You should call it really in desperate situations when + * you really want to stop thread and do not care about the rest. + * \warning With POSIX thread implementation, calling Stop (one or more times) + * will leak 28 bytes of memory. + */ + bool Stop(); + + /** + * \brief Join thread. + * \param ret pointer to return code of the joined thread + * \return true if success, false otherwise + * \warning Do NOT Join a detached thread. + */ + bool Join(void** ret = NULL); + +#ifdef _WIN32 + HANDLE +#else + pthread_t +#endif + GetId() const { + return m_id; + } + + private: + /** + * \brief Entry point of thread before calling specific + * callback. + * \param arg thread argument + * \return result of ThreadArg callback + */ +#ifdef _WIN32 + static DWORD WINAPI Call(LPVOID arg); +#else + static void* Call(void* arg); +#endif + /** + * \brief Thread identifier. + */ +#ifdef _WIN32 /* Win32 thread */ + HANDLE m_id; +#else /* POSIX thread */ + pthread_t m_id; +#endif + + /** + * \brief Thread argument. + */ + ThreadArg* m_arg; + }; + + /** + * \class Mutex + * \brief Mutex implementation. + */ + class Mutex + { + public: + /** + * \brief Constructor. + */ + Mutex(); + + /** + * \brief Destructor. + */ + ~Mutex(); + + /** + * \brief Lock the mutex. + * \return true if mutex is locked, false if error + */ + bool Lock(); + + /** + * \brief Unlock the mutex. + * \return true if mutex is unlocked, false if error + */ + bool Unlock(); + + private: + /** + * \brief The mutex. + */ +#ifdef _WIN32 + HANDLE m_mutex; +#else + pthread_mutex_t m_mutex; +#endif + }; + +#ifdef _WIN32 +#warning "BinarySemaphore is implemented for POSIX systems only" +#else + /** + * \class BinarySemaphore + * \brief Binary semaphore implementation. + */ + class BinarySemaphore { + public: + /** + * \brief Constructor. + */ + BinarySemaphore(); + + /** + * \brief Destructor. + */ + ~BinarySemaphore(); + + /** + * \brief Wait until the semaphore is unlocked. + */ + void Wait(); + + /** + * \brief Notify the semaphore. + */ + void Notify(); + + private: + /** + * \brief Mutex to prevent concurrent access to the flag. + */ + pthread_mutex_t m_mutex; + + /** + * \brief Conditional variable to block threads. + */ + pthread_cond_t m_cond; + + /** + * \brief Semaphore state: false = down, true = up. + */ + bool m_isUp; + }; +#endif /* _WIN32 */ + +} /* namespace System */ + +#endif /* SYSTEM_H */ + diff --git a/src/3rd_party-static/message_broker/include/websocket_handler.hpp b/src/3rd_party-static/message_broker/include/websocket_handler.hpp new file mode 100644 index 0000000000..8bed007436 --- /dev/null +++ b/src/3rd_party-static/message_broker/include/websocket_handler.hpp @@ -0,0 +1,226 @@ +/** + * \file websocket_handler.hpp + * \brief WebSocket Handler. + * Supports RFC6455 standard of protocol + * Protocol specification: + * http://tools.ietf.org/html/rfc6455 + * \author AKara + */ + +#ifndef WEBSOCKET_HANDLER_H +#define WEBSOCKET_HANDLER_H + +#include +#include +#include + +#define MAX_WEBSOCKET_04_KEY_LEN 128 /**< Max WS key length */ + +#define K(t) _K[(t) / 20] /**< K(t) */ +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) /**< F0(b, c, d) */ +#define F1(b, c, d) (((b) ^ (c)) ^ (d)) /**< F1(b, c, d) */ +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) /**< F2(b, c, d) */ +#define F3(b, c, d) (((b) ^ (c)) ^ (d)) /**< F3(b, c, d) */ + +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) /**< S(n, x) */ +#define H(n) (ctxt->h.b32[(n)]) /**< H(n) */ +#define COUNT (ctxt->count) /**< COUNT */ +#define W(n) (ctxt->m.b32[(n)]) /**< W(n) */ + +#define PUTPAD(x) { \ + ctxt->m.b8[(COUNT % 64)] = (x); \ + COUNT++; \ + COUNT %= 64; \ + if (COUNT % 64 == 0) \ + sha1_step(ctxt); \ + } /**< PUTPAD(x) */ + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \brief sha1_ctxt txt structure. + */ + struct sha1_ctxt + { + union { + unsigned char b8[20]; + unsigned int b32[5]; + } h; /**< h */ + union { + unsigned char b8[8]; + unsigned long long b64[1]; + } c; /**< c */ + union { + unsigned char b8[64]; + unsigned int b32[16]; + } m; /**< m */ + unsigned char count; /**< count */ + }; + + + /** + * \brief Constant table. + */ + const unsigned int _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; + + /** + * \brief Constant table. + */ + const char encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz0123456789+/"; + + /** + * \brief Constant table. + */ + const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" + "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; + + /** + * \brief Type to present raw bytes. + */ + typedef std::vector rawBytes; + + + /** + * \class CWebSocketHandler + * \brief WebSocket messages handler. + */ + class CWebSocketHandler + { + public: + /** + * \brief Constructor. + */ + CWebSocketHandler() + { + } + + /** + * \brief Destructor. + */ + ~CWebSocketHandler() + { + } + + /** + * \brief Generates Sec-WebSocket-Accept key + * \param key Sec-WebSocket-Key from client + */ + void handshake_0405(std::string &key); + + /** + * \brief Generates accept key for older (hybi-00) WebSocket protocol version. + * \param key1 The first key of the client's handshake (a string) + * \param key2 The second key of the client's handshake (a string) + * \param key3 The third key of the client's handshake (raw bytes), must be 8 bytes long + * \return Raw bytes of the generated accept key, or no bytes if error + */ + rawBytes handshake_hybi00(const std::string &key1, const std::string &key2, const rawBytes &key3); + + /** + * \brief Parses WebSocket data header to retrieve packet size + * \param Buffer input buffer + * \param b_size buffer size + * \return Packet size + */ + unsigned int parseWebSocketDataLength(const char* Buffer, unsigned int& b_size); + + /** + * \brief Parses WebSocket data + * \param Buffer input buffer + * \param b_size buffer size + * \return -1 in case of issues, data length in case of success + */ + int parseWebSocketData(char* Buffer, unsigned int& b_size); + + /** + * \brief Prepares WebSocket data + * \param Buffer input buffer + * \param b_size buffer size + * \return -1 in case of issues, data length in case of success + */ + int prepareWebSocketDataHeader(unsigned char* Buffer, unsigned long long b_size); + private: + /** + * \brief SHA1 hash calculator. + * \param d input buffer + * \param n size of buffer + * \param md mask buffer + * \return pointer to result + */ + unsigned char * SHA1(const unsigned char *d, size_t n, unsigned char *md); + + /** + * \brief base 64 encode string. + * \param in input buffer + * \param in_len size of buffer + * \param out output buffer + * \param out_size size of buffer + * \return -1 in case of errors + */ + int lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); + + /** + * \brief base 64 decode string. + * \param in input buffer + * \param out output buffer + * \param out_size size of buffer + * \return -1 in case of errors + */ + int lws_b64_decode_string(const char *in, char *out, int out_size); + + /** + * \brief one step of SHA1. + * \param ctxt input txt structure + */ + void sha1_step(struct sha1_ctxt *ctxt); + + /** + * \brief init step of SHA1. + * \param ctxt input txt structure + */ + void sha1_init(struct sha1_ctxt *ctxt); + + /** + * \brief pad step of SHA1. + * \param ctxt input txt structure + */ + void sha1_pad(struct sha1_ctxt *ctxt); + + /** + * \brief loop step of SHA1. + * \param ctxt input txt structure + * \param input input buffer buffer + * \param len length of input buffer + */ + void sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len); + + /** + * \brief result step of SHA1. + * \param ctxt input txt structure + * \param digest0 buffer + */ + void sha1_result(struct sha1_ctxt *ctxt, unsigned char* digest0); + + /** + * \brief base 64 test. + * \return -1 in case of errors + */ + int lws_b64_selftest(void); + + /** + * \brief Extracts and processes the number from key, + * according to the WebSocket hybi-00 specification. + * \param key Key to extract the number from + * \return The number, or 0 if error + */ + unsigned long extractNumber(const std::string &key) const; + }; + +} /* namespace NsMessageBroker */ + +#endif /* WEBSOCKET_HANDLER_H */ diff --git a/src/3rd_party-static/message_broker/src/client/mb_client.cpp b/src/3rd_party-static/message_broker/src/client/mb_client.cpp new file mode 100644 index 0000000000..6342c776a8 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/client/mb_client.cpp @@ -0,0 +1,75 @@ +/** + * \file mb_client.cpp + * \brief MessageBroker client. + * \author AKara + */ + +#include + +#include "mb_client.hpp" + +namespace NsMessageBroker +{ + + Client::Client() + { + } + + Client::Client(const std::string& address, uint16_t port) + { + m_sock = -1; + m_address = address; + m_port = port; + memset(&m_sockaddr, 0x00, sizeof(struct sockaddr_storage)); + m_sockaddrlen = 0; + } + + Client::~Client() + { + if(m_sock != -1) + { + Close(); + } + } + + int Client::GetSocket() const + { + return m_sock; + } + + std::string Client::GetAddress() const + { + return m_address; + } + + void Client::SetAddress(const std::string& address) + { + m_address = address; + } + + void Client::SetPort(uint16_t port) + { + m_port = port; + } + + uint16_t Client::GetPort() const + { + return m_port; + } + + bool Client::Connect() + { + m_sock = networking::connect(m_protocol, GetAddress(), GetPort(), &m_sockaddr, &m_sockaddrlen); + + return (m_sock != -1) ? true : false; + } + + void Client::Close() + { + shutdown(m_sock, SHUT_RDWR); + + close(m_sock); + m_sock = -1; + } + +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/client/mb_controller.cpp b/src/3rd_party-static/message_broker/src/client/mb_controller.cpp new file mode 100644 index 0000000000..8a4a77cf30 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/client/mb_controller.cpp @@ -0,0 +1,352 @@ +/** + * \file mb_controller.cpp + * \brief MessageBroker Controller. + * \author AKara + */ + +#include "mb_controller.hpp" + +#include "MBDebugHelper.h" +#include "CMessageBroker.hpp" + +namespace NsMessageBroker +{ + CMessageBrokerController::CMessageBrokerController(const std::string& address, uint16_t port, std::string name): + TcpClient(address, port), + stop(false), + m_receivingBuffer(""), + mControllersIdStart(-1), + mControllersIdCurrent(0) + { + mControllersName = name; + } + + std::string CMessageBrokerController::getControllersName() + { + return mControllersName; + } + + CMessageBrokerController::~CMessageBrokerController() + { + } + + ssize_t CMessageBrokerController::Recv(std::string& data) + { + DBG_MSG(("CMessageBrokerController::Recv()\n")); + ssize_t recv = TcpClient::Recv(data); + DBG_MSG(("Received message: %s\n", data.c_str())); + m_receivingBuffer += data; + while (!stop) + { + Json::Value root; + if (!m_reader.parse(m_receivingBuffer, root)) + { + DBG_MSG(("Received not JSON string! %s\n", m_receivingBuffer.c_str())); + return recv; + } + std::string wmes = m_receiverWriter.write(root); + DBG_MSG(("Parsed JSON string:%s; length: %d\n", wmes.c_str(), wmes.length())); + DBG_MSG(("Buffer is:%s\n", m_receivingBuffer.c_str())); + ssize_t beginpos = m_receivingBuffer.find(wmes); + if (-1 != beginpos) + { + m_receivingBuffer.erase(0, beginpos + wmes.length()); + DBG_MSG(("Buffer after cut is:%s\n", m_receivingBuffer.c_str())); + } else + { + m_receivingBuffer.clear(); + } + onMessageReceived(root); + } + return recv; + } + + void CMessageBrokerController::onMessageReceived(Json::Value message) + { + // Determine message type and process... + Json::Value error; + if (checkMessage(message, error)) + { + if (isNotification(message)) + { + DBG_MSG(("Message is notification!\n")); + processNotification(message); + } else if (isResponse(message)) + { + std::string id = message["id"].asString(); + std::string method = findMethodById(id); + DBG_MSG(("Message is response on: %s\n", method.c_str())); + if ("" != method) + { + if ("MB.registerComponent" == method) + { // initialize mControllersIdStart + if (message.isMember("result") && message["result"].isInt()) + { + mControllersIdStart = message["result"].asInt(); + } else + { + DBG_MSG_ERROR(("Not possible to initialize mControllersIdStart!\n")); + } + } else if ("MB.subscribeTo" == method || "MB.unregisterComponent" == method || "MB.unsubscribeFrom" == method) + { + //nothing to do for now + } else + { + processResponse(method, message); + } + } else + { + DBG_MSG_ERROR(("Request with id %s has not been found!\n", id.c_str())); + } + } else + { + DBG_MSG(("Message is request!\n")); + processRequest(message); + } + } else + { + DBG_MSG_ERROR(("Message contains wrong data!\n")); + } + } + + ssize_t CMessageBrokerController::Send(const std::string& data) + { + return TcpClient::Send(data); + } + + void CMessageBrokerController::sendJsonMessage(Json::Value& message) + { + DBG_MSG(("CMessageBrokerController::sendJsonMessage()\n")); + sync_primitives::AutoLock auto_lock(queue_lock_); + std::string mes = m_writer.write(message); + if (!isNotification(message) && !isResponse(message)) + {// not notification, not a response, store id and method name to recognize an answer + mWaitResponseQueue.insert(std::map::value_type(message["id"].asString(), message["method"].asString())); + } + int bytesSent = Send(mes); + bytesSent = bytesSent; // to prevent compiler warnings in case DBG_MSG off + DBG_MSG(("Length:%d, Sent: %d bytes\n", mes.length(), bytesSent)); + } + + std::string CMessageBrokerController::findMethodById(std::string id) + { + DBG_MSG(("CMessageBrokerController::findMethodById()\n")); + sync_primitives::AutoLock auto_lock(queue_lock_); + std::string res = ""; + std::map ::iterator it; + it = mWaitResponseQueue.find(id); + if (it != mWaitResponseQueue.end()) + { + res = (*it).second; + mWaitResponseQueue.erase(it); + } + return res; + } + + int CMessageBrokerController::getNextMessageId() + { + if (mControllersIdCurrent < (mControllersIdStart+1000)) + { + return mControllersIdCurrent++; + } else + { + return mControllersIdCurrent = mControllersIdStart; + } + } + + void CMessageBrokerController::prepareMessage(Json::Value& root) + { + root["jsonrpc"] = "2.0"; + root["id"] = getNextMessageId(); + } + + void CMessageBrokerController::prepareErrorMessage(int errCode, std::string errMessage, Json::Value& error) + { + DBG_MSG(("CMessageBrokerController::prepareErrorMessage()\n")); + Json::Value err; + err["code"] = errCode; + err["message"] = errMessage; + error["error"] = err; + } + + std::string CMessageBrokerController::getDestinationComponentName(Json::Value& root) + { + DBG_MSG(("CMessageBrokerController::getDestinationComponentName()\n")); + std::string ret = ""; + std::string method = root["method"].asString(); + int pos = method.find("."); + if (-1 != pos) + { + ret = method.substr(0, pos); + } + DBG_MSG(("Destination component is: %s\n", ret.c_str())); + return ret; + } + + std::string CMessageBrokerController::getMethodName(Json::Value& root) + { + DBG_MSG(("CMessageBrokerController::getMethodName()\n")); + std::string ret = ""; + std::string method = root["method"].asString(); + int pos = method.find("."); + if (-1 != pos) + { + ret = method.substr(pos+1); + } + DBG_MSG(("Method is: %s\n", ret.c_str())); + return ret; + } + + bool CMessageBrokerController::isNotification(Json::Value& root) + { + DBG_MSG(("CMessageBrokerController::isNotification()\n")); + bool ret = false; + if (false == root.isMember("id")) + { + ret = true; + } + DBG_MSG(("Result: %d\n", ret)); + return ret; + } + + bool CMessageBrokerController::isResponse(Json::Value& root) + { + DBG_MSG(("CMessageBrokerController::isResponse()\n")); + bool ret = false; + if ((true == root.isMember("result")) || (true == root.isMember("error"))) + { + ret = true; + } + DBG_MSG(("Result: %d\n", ret)); + return ret; + } + + void CMessageBrokerController::registerController(int id) + { + DBG_MSG(("CMessageBrokerController::registerController()\n")); + Json::Value root; + Json::Value params; + prepareMessage(root); + root["id"] = id; + root["method"] = "MB.registerComponent"; + params["componentName"] = mControllersName; + root["params"] = params; + sendJsonMessage(root); + } + + void CMessageBrokerController::unregisterController() + { + DBG_MSG(("CMessageBrokerController::unregisterController()\n")); + Json::Value root; + Json::Value params; + prepareMessage(root); + root["method"] = "MB.unregisterComponent"; + params["componentName"] = mControllersName; + root["params"] = params; + sendJsonMessage(root); + } + + void CMessageBrokerController::subscribeTo(std::string property) + { + DBG_MSG(("CMessageBrokerController::subscribeTo()\n")); + Json::Value root; + Json::Value params; + prepareMessage(root); + root["method"] = "MB.subscribeTo"; + params["propertyName"] = property; + root["params"] = params; + sendJsonMessage(root); + } + + void CMessageBrokerController::unsubscribeFrom(std::string property) + { + DBG_MSG(("CMessageBrokerController::unsubscribeFrom()\n")); + Json::Value root; + Json::Value params; + prepareMessage(root); + root["method"] = "MB.unsubscribeFrom"; + params["propertyName"] = property; + root["params"] = params; + sendJsonMessage(root); + } + + void* CMessageBrokerController::MethodForReceiverThread(void * arg) + { + stop = false; + arg = arg; // to avoid compiler warnings + while(!stop) + { + std::string data = ""; + Recv(data); + } + return NULL; + } + + bool CMessageBrokerController::checkMessage(Json::Value& root, Json::Value& error) + { + DBG_MSG(("CMessageBrokerController::checkMessage()\n")); + Json::Value err; + + try + { + /* check the JSON-RPC version => 2.0 */ + if (!root.isObject() || !root.isMember("jsonrpc") || root["jsonrpc"] != "2.0") + { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = NsMessageBroker::INVALID_REQUEST; + err["message"] = "Invalid MessageBroker request."; + error["error"] = err; + return false; + } + + if (root.isMember("id") && (root["id"].isArray() || root["id"].isObject())) + { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = NsMessageBroker::INVALID_REQUEST; + err["message"] = "Invalid MessageBroker request."; + error["error"] = err; + return false; + } + + if (root.isMember("result") && root.isMember("error")) + { + /* message can't contain simultaneously result and error*/ + return false; + } + + if (root.isMember("method")) + { + if (!root["method"].isString()) + { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = NsMessageBroker::INVALID_REQUEST; + err["message"] = "Invalid MessageBroker request."; + error["error"] = err; + return false; + } + /* Check the params is an object*/ + if (root.isMember("params") && !root["params"].isObject()) + { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Invalid JSONRPC params."; + error["error"] = err; + return false; + } + } else if (!root.isMember("result") && !root.isMember("error")) + { + return false; + } + return true; + } catch (...) + { + DBG_MSG_ERROR(("CMessageBrokerController::checkMessage() EXCEPTION has been caught!\n")); + return false; + } + } + +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/client/mb_tcpclient.cpp b/src/3rd_party-static/message_broker/src/client/mb_tcpclient.cpp new file mode 100644 index 0000000000..02db417c26 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/client/mb_tcpclient.cpp @@ -0,0 +1,58 @@ +/** + * \file mb_tcpclient.cpp + * \brief MessageBroker TCP client. + * \author AKara + */ + +#include "mb_tcpclient.hpp" +#include "MBDebugHelper.h" + +namespace NsMessageBroker +{ + + TcpClient::TcpClient(const std::string& address, uint16_t port) : Client(address, port) + { + m_protocol = networking::TCP; + } + + TcpClient::~TcpClient() + { + } + + ssize_t TcpClient::Send(const std::string& data) + { + std::string rep = data; + int bytesToSend = rep.length(); + const char* ptrBuffer = rep.c_str(); + do + { + int retVal = send(m_sock, ptrBuffer, bytesToSend, 0); + if(retVal == -1) + { + return -1; + } + bytesToSend -= retVal; + ptrBuffer += retVal; + }while(bytesToSend > 0); + return rep.length(); + } + + ssize_t TcpClient::Recv(std::string& data) + { + char buf[1500]; + ssize_t nb = -1; + + if((nb = ::recv(m_sock, buf, sizeof(buf), 0)) == -1) + { + std::cerr << "Error while receiving" << std::endl; + return -1; + } + + data = std::string(buf, nb); + DBG_MSG(("Received from server: %s\n", data.c_str())); + + return nb; + } + +} /* namespace NsMessageBroker */ + diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.cpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.cpp new file mode 100644 index 0000000000..77ab1ca2c1 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.cpp @@ -0,0 +1,59 @@ +/** + * \file MessageBrokerControllerAVA.cpp + * \brief MessageBroker Controller for Avatar. + * \author AKara + */ + +#include + +#include "MessageBrokerControllerAVA.hpp" + +#include "MBDebugHelper.h" + +extern int start; + +namespace NsMessageBroker +{ + CMessageBrokerControllerAVA::CMessageBrokerControllerAVA(const std::string& address, uint16_t port): + CMessageBrokerController(address, port, "AVA") + { + } + + CMessageBrokerControllerAVA::~CMessageBrokerControllerAVA() + { + } + + void CMessageBrokerControllerAVA::processRequest(Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerAVA::processRequest()\n")); + root=root;//to prevent compiler warning + } + + void CMessageBrokerControllerAVA::processNotification(Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerAVA::processNotification()\n")); + root=root;//to prevent compiler warning + } + + void CMessageBrokerControllerAVA::processResponse(std::string method, Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerAVA::processResponse()\n")); + DWORD stop = GetTickCount(); + int diff = stop - start; + std::string id = root["id"].asString(); + printf("Execution time for id %s is %d ms!\n", id.c_str(), diff); + root=root;//to prevent compiler warning + method=method;//to prevent compiler warning + } + + void CMessageBrokerControllerAVA::makeCall(std::string phoneNumber) + { + DBG_MSG(("CMessageBrokerControllerAVA::makeCall()\n")); + Json::Value request, params; + prepareMessage(request); + request["method"] = "Phone.makeCall"; + params["phoneNumber"] = phoneNumber; + request["params"] = params; + sendJsonMessage(request); + } +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.hpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.hpp new file mode 100644 index 0000000000..47e684a7e4 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerAVA.hpp @@ -0,0 +1,68 @@ +/** + * \file MessageBrokerControllerAVA.hpp + * \brief MessageBroker Controller AVA. + * \author AKara + */ + +#ifndef MB_CONTROLLERAVA_H +#define MB_CONTROLLERAVA_H + +#include + +#include "json/json.h" + +#include "mb_controller.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class CMessageBrokerControllerAVA + * \brief MessageBroker Controller. + */ + class CMessageBrokerControllerAVA : public CMessageBrokerController + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + */ + CMessageBrokerControllerAVA(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + ~CMessageBrokerControllerAVA(); + + /** + * \brief process request. + * \param root JSON message. + */ + void processRequest(Json::Value& root); + + /** + * \brief process notification. + * \param root JSON message. + */ + void processNotification(Json::Value& root); + + /** + * \brief process response. + * \param method method name which has been called. + * \param root JSON message. + */ + void processResponse(std::string method, Json::Value& root); + + /** + * \brief sends message to the phone to make call. + * \param phoneNumber number for call. + */ + void makeCall(std::string phoneNumber); + + }; +}/* namespace NsMessageBroker */ +#endif /* MB_CONTROLLERAVA_H */ \ No newline at end of file diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.cpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.cpp new file mode 100644 index 0000000000..cbbe39492b --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.cpp @@ -0,0 +1,125 @@ +/** + * \file MessageBrokerControllerBackend.cpp + * \brief MessageBroker Controller for Backend. + * \author AKara + */ + +#include "MessageBrokerControllerBackend.hpp" + +#include "MBDebugHelper.h" + +namespace NsMessageBroker +{ + CMessageBrokerControllerBackend::CMessageBrokerControllerBackend(const std::string& address, unsigned short port): +CMessageBrokerController(address, port, std::string("Backend")) + { + } + + CMessageBrokerControllerBackend::~CMessageBrokerControllerBackend() + { + } + + void CMessageBrokerControllerBackend::processRequest(Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerBackend::processRequest()\n")); + if (getControllersName() == getDestinationComponentName(root)) + { + Json::Value response; + response["jsonrpc"] = root["jsonrpc"]; + response["id"] = root["id"]; + if ("isFirstStart" == getMethodName(root)) + { + isFirstStart(response); + } else if ("isFullScreen" == getMethodName(root)) + { + isFullScreen(response); + } else if ("getWindowSize" == getMethodName(root)) + { + getWindowSize(response); + } else if ("getWindowDensity" == getMethodName(root)) + { + getWindowDensity(response); + } else if ("getOSInfo" == getMethodName(root)) + { + getOSInfo(response); + } else if ("logToOS" == getMethodName(root)) + { + logToOS(response); + } else + { + DBG_MSG_ERROR(("Method has not been found!\n")); + Json::Value err; + err["code"] = NsMessageBroker::INVALID_REQUEST; + err["message"] = "Method has not been found."; + response["error"] = err; + } + sendJsonMessage(response); + } else + { + DBG_MSG_ERROR(("Wrong message destination!\n")); + } + } + + void CMessageBrokerControllerBackend::processNotification(Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerBackend::processNotification()\n")); + root=root;//to prevent compiler warning + } + + void CMessageBrokerControllerBackend::processResponse(std::string method, Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerBackend::processResponse()\n")); + root=root;//to prevent compiler warning + method=method;//to prevent compiler warning + } + + void CMessageBrokerControllerBackend::isFirstStart(Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerBackend::isFirstStart()\n")); + Json::Value res; + res["isFirstStart"] = false; + response["result"] = res; + } + + void CMessageBrokerControllerBackend::isFullScreen(Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerBackend::isFullScreen()\n")); + Json::Value res; + res["isFullScreen"] = false; + response["result"] = res; + } + + void CMessageBrokerControllerBackend::getWindowSize(Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerBackend::getWindowSize()\n")); + Json::Value res; + res["width"] = 800; + res["height"] = 480; + response["result"] = res; + } + + void CMessageBrokerControllerBackend::getWindowDensity(Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerBackend::getWindowDensity()\n")); + Json::Value res; + res["windowDensity"] = 1; + response["result"] = res; + } + + void CMessageBrokerControllerBackend::getOSInfo(Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerBackend::getOSInfo()\n")); + Json::Value res; + res["osType"] = ""; + res["osVersion"] = ""; + res["isNativeApplication"] = true; + response["result"] = res; + } + + void CMessageBrokerControllerBackend::logToOS(Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerBackend::logToOS()\n")); + response["result"] = ""; + } + +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.hpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.hpp new file mode 100644 index 0000000000..b79411dc98 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerBackend.hpp @@ -0,0 +1,96 @@ +/** + * \file MessageBrokerControllerBackend.hpp + * \brief MessageBroker Controller Backend. + * \author AKara + */ +#pragma once + +#include + +#include "json/json.h" + +#include "mb_controller.hpp" +#include "CMessageBroker.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class CMessageBrokerControllerBackend + * \brief MessageBroker Controller. + */ + + class CMessageBrokerControllerBackend : public CMessageBrokerController + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + */ + CMessageBrokerControllerBackend(const std::string& address, unsigned short port); + + /** + * \brief Destructor. + */ + ~CMessageBrokerControllerBackend(); + + /** + * \brief process request. + * \param root JSON message. + */ + void processRequest(Json::Value& root); + + /** + * \brief process notification. + * \param root JSON message. + */ + void processNotification(Json::Value& root); + + /** + * \brief process response. + * \param method method name which has been called. + * \param root JSON message. + */ + void processResponse(std::string method, Json::Value& root); + private: + /** + * \brief Checks first start. + * \param response container for response + */ + void isFirstStart(Json::Value& response); + + /** + * \brief Checks first start. + * \param response container for response + */ + void isFullScreen(Json::Value& response); + + /** + * \brief Checks first start. + * \param response container for response + */ + void getWindowSize(Json::Value& response); + + /** + * \brief Checks first start. + * \param response container for response + */ + void getWindowDensity(Json::Value& response); + + /** + * \brief Checks first start. + * \param response container for response + */ + void getOSInfo(Json::Value& response); + + /** + * \brief Checks first start. + * \param response container for response + */ + void logToOS(Json::Value& response); + }; +}/* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.cpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.cpp new file mode 100644 index 0000000000..6f308e71c2 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.cpp @@ -0,0 +1,191 @@ +/** + * \file MessageBrokerControllerPhone.cpp + * \brief MessageBroker Controller for Phone. + * \author AKara + */ + +#include "MessageBrokerControllerPhone.hpp" + +#include "CMessageBroker.hpp" + +#include "MBDebugHelper.h" + +namespace NsMessageBroker +{ + CMessageBrokerControllerPhone::CMessageBrokerControllerPhone(const std::string& address, uint16_t port): + CMessageBrokerController(address, port, "Phone") + { + } + + CMessageBrokerControllerPhone::~CMessageBrokerControllerPhone() + { + } + + void CMessageBrokerControllerPhone::processRequest(Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerPhone::processRequest()\n")); + if (getControllersName() == getDestinationComponentName(root)) + { + Json::Value response; + response["jsonrpc"] = root["jsonrpc"]; + response["id"] = root["id"]; + if ("makeCall" == getMethodName(root)) + { + if (root.isMember("params")) + { + Json::Value params = root["params"]; + if (params.isMember("phoneNumber") && params["phoneNumber"].isString()) + { + makeCall(params["phoneNumber"].asString(), response); + } else + { + DBG_MSG_ERROR(("Wrong params!\n")); + prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params!", response); + } + } else + { + DBG_MSG_ERROR(("Not possible to parse phone number!\n")); + prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Not possible to parse phone number!", response); + } + } else if ("endCall" == getMethodName(root)) + { + endCall(root["params"].asString(), response); + } else if ("holdCall" == getMethodName(root)) + { + holdCall(root["params"].asString(), response); + } else if ("getContacts" == getMethodName(root)) + { + if (root.isMember("params")) + { + Json::Value params = root["params"]; + if (params.isMember("firstLetter") && params["firstLetter"].isString() + && params.isMember("offset") && params["offset"].isInt() + && params.isMember("numberOfItems") && params["numberOfItems"].isInt()) + { + getContacts(params["firstLetter"].asString(), params["offset"].asInt(), params["numberOfItems"].asInt(), response); + } else + { + DBG_MSG_ERROR(("Wrong params of getContacts()!\n")); + prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params of getContacts()!", response); + } + } else + { + DBG_MSG_ERROR(("Params is not an object!\n")); + prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Params is not an object!", response); + } + } else if ("getHistory" == getMethodName(root)) + { + if (root.isMember("params")) + { + Json::Value params = root["params"]; + if (params.isMember("typeOfContacts") && params["typeOfContacts"].isString() + && params.isMember("offset") && params["offset"].isInt() + && params.isMember("numberOfItems") && params["numberOfItems"].isInt()) + { + getHistory(params["typeOfContacts"].asString(), params["offset"].asInt(), params["numberOfItems"].asInt(), response); + } else + { + DBG_MSG_ERROR(("Wrong params of getHistory()!\n")); + prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Wrong params of getHistory()!", response); + } + } else + { + DBG_MSG_ERROR(("Params is not an object!\n")); + prepareErrorMessage(NsMessageBroker::INVALID_PARAMS, "Params is not an object!", response); + } + } else + { + DBG_MSG_ERROR(("Method has not been found!\n")); + Json::Value err; + err["code"] = NsMessageBroker::INVALID_REQUEST; + err["message"] = "Method has not been found."; + response["error"] = err; + } + sendJsonMessage(response); + } else + { + DBG_MSG_ERROR(("Wrong message destination!\n")); + } + } + + void CMessageBrokerControllerPhone::makeCall(std::string phoneNumber, Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerPhone::makeCall()\n")); + phoneNumber = phoneNumber; // to avoid compiler's warning + response["result"] = "OK"; + } + + void CMessageBrokerControllerPhone::endCall(std::string phoneNumber, Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerPhone::endCall()\n")); + phoneNumber = phoneNumber; // to avoid compiler's warning + response["result"] = "OK"; + } + + void CMessageBrokerControllerPhone::holdCall(std::string phoneNumber, Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerPhone::holdCall()\n")); + phoneNumber = phoneNumber; // to avoid compiler's warning + response["result"] = "OK"; + } + + void CMessageBrokerControllerPhone::getContacts(std::string firstLetter, int offset, int numberOfItems, Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerPhone::getContacts()\n")); + firstLetter = firstLetter; // to avoid compiler's warning + offset = offset; // to avoid compiler's warning + numberOfItems = numberOfItems; // to avoid compiler's warning + response["result"] = "OK"; + } + + void CMessageBrokerControllerPhone::getHistory(std::string firstLetter, int offset, int numberOfItems, Json::Value& response) + { + DBG_MSG(("CMessageBrokerControllerPhone::getHistory()\n")); + firstLetter = firstLetter; // to avoid compiler's warning + offset = offset; // to avoid compiler's warning + numberOfItems = numberOfItems; // to avoid compiler's warning + response["result"] = "OK"; + } + + void CMessageBrokerControllerPhone::onCallStatusChanged(int callStatus) + { + DBG_MSG(("CMessageBrokerControllerPhone::onCallStatusChanged()\n")); + Json::Value request, params; + request["jsonrpc"] = "2.0"; + request["method"] = "Phone.onCallStatusChanged"; + params["callStatus"] = callStatus; + request["params"] = params; + sendJsonMessage(request); + } + + void CMessageBrokerControllerPhone::onContactsUpdated() + { + DBG_MSG(("CMessageBrokerControllerPhone::onContactsUpdated()\n")); + Json::Value request; + request["jsonrpc"] = "2.0"; + request["method"] = "Phone.onContactsUpdated"; + sendJsonMessage(request); + } + + void CMessageBrokerControllerPhone::onHistoryUpdated() + { + DBG_MSG(("CMessageBrokerControllerPhone::onHistoryUpdated()\n")); + Json::Value request; + request["jsonrpc"] = "2.0"; + request["method"] = "Phone.onHistoryUpdated"; + sendJsonMessage(request); + } + + void CMessageBrokerControllerPhone::processNotification(Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerPhone::processNotification()\n")); + root=root;//to prevent compiler warning + } + + void CMessageBrokerControllerPhone::processResponse(std::string method, Json::Value& root) + { + DBG_MSG(("CMessageBrokerControllerPhone::processResponse()\n")); + root=root;//to prevent compiler warning + method = method; + } +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.hpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.hpp new file mode 100644 index 0000000000..e6f4898226 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerControllerPhone.hpp @@ -0,0 +1,117 @@ +/** + * \file MessageBrokerControllerPhone.hpp + * \brief MessageBroker Controller Phone. + * \author AKara + */ + +#ifndef MB_CONTROLLERPHONE_H +#define MB_CONTROLLERPHONE_H + +#include + +#include "json/json.h" + +#include "mb_controller.hpp" + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + /** + * \class CMessageBrokerControllerPhone + * \brief MessageBroker Controller Phone. + */ + class CMessageBrokerControllerPhone : public CMessageBrokerController + { + public: + /** + * \brief Constructor. + * \param address remote network address or FQDN + * \param port remote local port + */ + CMessageBrokerControllerPhone(const std::string& address, uint16_t port); + + /** + * \brief Destructor. + */ + ~CMessageBrokerControllerPhone(); + + /** + * \brief process request. + * \param root JSON message. + */ + void processRequest(Json::Value& root); + + /** + * \brief process notification. + * \param root JSON message. + */ + void processNotification(Json::Value& root); + + /** + * \brief process response. + * \param method method name which has been called. + * \param root JSON message. + */ + void processResponse(std::string method, Json::Value& root); + public://Notifications + /** + * \brief Notifies Call Status changing. + * \param callStatus status of current active call + */ + void onCallStatusChanged(int callStatus); + + /** + * \brief Notifies Contacts list updated. + */ + void onContactsUpdated(); + + /** + * \brief Notifies History list updated. + */ + void onHistoryUpdated(); + private: + /** + * \brief Makes call. + * \param phoneNumber number for call. + * \param response container for response + */ + void makeCall(std::string phoneNumber, Json::Value& response); + + /** + * \brief Ends call. + * \param phoneNumber number of call. + * \param response container for response + */ + void endCall(std::string phoneNumber, Json::Value& response); + + /** + * \brief Holds call. + * \param phoneNumber number of call. + * \param response container for response + */ + void holdCall(std::string phoneNumber, Json::Value& response); + + /** + * \brief Gets contacts. + * \param firstLetter first letter of list. + * \param offset offset from first item + * \param numberOfItems number of expected items + * \param response container for response + */ + void getContacts(std::string firstLetter, int offset, int numberOfItems, Json::Value& response); + + /** + * \brief Gets history. + * \param typeOfContacts type of contacts (incoming/outgoing/missed/all calls). + * \param offset offset from first item + * \param numberOfItems number of expected items + * \param response container for response + */ + void getHistory(std::string typeOfContacts, int offset, int numberOfItems, Json::Value& response); + + }; +}/* namespace NsMessageBroker */ +#endif /* MB_CONTROLLERPHONE_H */ \ No newline at end of file diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerServer.cpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerServer.cpp new file mode 100644 index 0000000000..405b3fcbd5 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerServer.cpp @@ -0,0 +1,245 @@ +/** + * \file MessageBrokerServer.cpp + * \brief MessageBrokerServer sources + * \author AKara + */ + +#include +#include +#include +#include +#include + +#include "system.h" + +#include "MBDebugHelper.h" + +#include "mb_tcpserver.hpp" +#include "mb_tcpclient.hpp" +#include "CMessageBroker.hpp" + +#include "MessageBrokerControllerAVA.hpp" +#include "MessageBrokerControllerPhone.hpp" +#include "MessageBrokerControllerBackend.hpp" + +/** + * \brief Signal management. + * \param code signal code + */ + static void signal_handler(int code) + { + switch(code) + { + case SIGINT: + case SIGTERM: + break; + default: + break; + } +} + +/** + * \brief stores start time of test operation. + */ +int start; + +/** + * \brief Entry point of the program. + * \param argc number of argument + * \param argv array of arguments + * \return EXIT_SUCCESS or EXIT_FAILURE + */ +int main(int argc, char** argv) +{ + NsMessageBroker::CMessageBroker* mpMessageBroker = NsMessageBroker::CMessageBroker::getInstance(); + if (!mpMessageBroker) + { + DBG_MSG_ERROR(("NULL pointer\n")); + exit(EXIT_FAILURE); + } + + + NsMessageBroker::TcpServer server(std::string("127.0.0.1"), 8086, mpMessageBroker); + + DBG_MSG(("Start MessageBroker component\n")); + mpMessageBroker->startMessageBroker(&server); + + NsMessageBroker::CMessageBrokerControllerAVA tcpControllerAVA(std::string("127.0.0.1"), 8086); + NsMessageBroker::CMessageBrokerControllerPhone tcpControllerPhone(std::string("127.0.0.1"), 8086); + NsMessageBroker::CMessageBrokerControllerBackend tcpControllerBackend(std::string("127.0.0.1"), 8086); + + /* avoid compilation warnings */ + argc = argc; + argv = argv; + + if(!networking::init()) + { + DBG_MSG_ERROR(("Networking initialization failed!\n")); + + } + + if(signal(SIGTERM, signal_handler) == SIG_ERR) + { + DBG_MSG_ERROR(("Error signal SIGTERM will not be handled!\n")); + } + + if(signal(SIGINT, signal_handler) == SIG_ERR) + { + DBG_MSG_ERROR(("Error signal SIGINT will not be handled!\n")); + } + + if(!server.Bind()) + { + DBG_MSG_ERROR(("Bind failed!\n")); + exit(EXIT_FAILURE); + } else + { + DBG_MSG(("Bind successful!\n")); + } + + if(!server.Listen()) + { + DBG_MSG_ERROR(("Listen failed!\n")); + exit(EXIT_FAILURE); + } else + { + DBG_MSG(("Listen successful!\n")); + } + + if(!tcpControllerAVA.Connect()) + { + DBG_MSG_ERROR(("Cannot connect to remote peer!\n")); + exit(EXIT_FAILURE); + } else + { + DBG_MSG(("ClientAVA connected to the server! SocketID = %d\n", tcpControllerAVA.GetSocket())); + } + + if(!tcpControllerPhone.Connect()) + { + DBG_MSG_ERROR(("Cannot connect to remote peer!\n")); + exit(EXIT_FAILURE); + } else + { + DBG_MSG(("ClientPhone connected to the server! SocketID = %d\n",tcpControllerPhone.GetSocket())); + } + + if(!tcpControllerBackend.Connect()) + { + DBG_MSG_ERROR(("Cannot connect to remote peer!\n")); + exit(EXIT_FAILURE); + } else + { + DBG_MSG(("ClientBackend connected to the server! SocketID = %d\n",tcpControllerBackend.GetSocket())); + } + + DBG_MSG(("Start CMessageBroker thread!\n")); + System::Thread th1(new System::ThreadArgImpl(*mpMessageBroker, &NsMessageBroker::CMessageBroker::MethodForThread, NULL)); + th1.Start(false); + + DBG_MSG(("Start MessageBroker TCP server thread!\n")); + System::Thread th2(new System::ThreadArgImpl(server, &NsMessageBroker::TcpServer::MethodForThread, NULL)); + th2.Start(false); + + DBG_MSG(("Start tcpControllerAVA receiver thread!\n")); + System::Thread th3(new System::ThreadArgImpl(tcpControllerAVA, &NsMessageBroker::CMessageBrokerControllerAVA::MethodForReceiverThread, NULL)); + th3.Start(false); + + DBG_MSG(("Start tcpControllerPhone receiver thread!\n")); + System::Thread th4(new System::ThreadArgImpl(tcpControllerPhone, &NsMessageBroker::CMessageBrokerControllerPhone::MethodForReceiverThread, NULL)); + th4.Start(false); + + DBG_MSG(("Start tcpControllerBackend receiver thread!\n")); + System::Thread th5(new System::ThreadArgImpl(tcpControllerBackend, &NsMessageBroker::CMessageBrokerControllerBackend::MethodForReceiverThread, NULL)); + th5.Start(false); + + bool loop = true; + while(loop) + { + DBG_MSG(("Enter command code:\n")); + int i; + std::cin >> i; + switch(i) + { + case 0: + { + DBG_MSG(("Exit!\n")); + mpMessageBroker->stopMessageBroker(); + th1.Stop(); + th2.Stop(); + th3.Stop(); + th4.Stop(); + server.Close(); + loop = false; + break; + } + case 1:// register component + { + DBG_MSG(("tcpControllerAVA.register()\n")); + tcpControllerAVA.registerController(0); + DBG_MSG(("tcpControllerPhone.register()\n")); + tcpControllerPhone.registerController(1); + DBG_MSG(("tcpControllerBackend.register()\n")); + tcpControllerBackend.registerController(2); + break; + } + case 2:// external message + { + DBG_MSG(("tcpControllerAVA.Phone.Call()\n")); + start = GetTickCount(); + tcpControllerAVA.makeCall("+380677639550"); + break; + } + case 3://subscribe + { + DBG_MSG(("tcpControllerAVA.subscribeTo()\n")); + tcpControllerAVA.subscribeTo("Phone.onContactsUpdated"); + break; + } + case 4://notify + { + DBG_MSG(("tcpControllerPhone.onContactsUpdated()\n")); + tcpControllerPhone.onContactsUpdated(); + break; + } + case 5: //unsubscribe + { + DBG_MSG(("tcpControllerAVA.unsubscribeFrom()\n")); + tcpControllerAVA.unsubscribeFrom("Phone.onContactsUpdated"); + break; + } + case 6: //unregister + { + DBG_MSG(("tcpControllerPhone.unregister()\n")); + tcpControllerPhone.unregisterController(); + break; + } + case 7: //stress test + { + + DBG_MSG(("tcpControllerAVA.Phone.Call() 500 times\n")); + start = GetTickCount(); + for (int c =0; c<1000; c++) + { + tcpControllerAVA.makeCall("+380677639550"); + } + int stop = GetTickCount(); + int diff = stop - start; + printf("Requests execution time is %d ms!\n", diff); + break; + } + case 8: //parser test + { + DBG_MSG(("Parser test\n")); + mpMessageBroker->Test(); + break; + } + default: + { + DBG_MSG(("Entered: %d\n", i)); + break; + } + } + } + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/3rd_party-static/message_broker/src/example/MessageBrokerServer.hpp b/src/3rd_party-static/message_broker/src/example/MessageBrokerServer.hpp new file mode 100644 index 0000000000..884ed0309f --- /dev/null +++ b/src/3rd_party-static/message_broker/src/example/MessageBrokerServer.hpp @@ -0,0 +1,19 @@ +/** + * \file MessageBrokerServer.hpp + * \brief MessageBrokerServer header + * \author AKara + */ + +#ifndef MESSAGEBROKERSERVER_H +#define MESSAGEBROKERSERVER_H + +/** + * \namespace NsMessageBroker + * \brief MessageBroker related functions. + */ +namespace NsMessageBroker +{ + +} /* namespace NsMessageBroker */ + +#endif /* MESSAGEBROKERSERVER_H */ diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBroker.cpp b/src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBroker.cpp new file mode 100644 index 0000000000..3b14489a8c --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBroker.cpp @@ -0,0 +1,958 @@ +/** + * \file CMessageBroker.cpp + * \brief CMessageBroker singletone class implementation. + * \author AKara + */ + +#include +#include +#include + +#include + +#include "CMessageBroker.hpp" +#include "CMessageBrokerRegistry.hpp" + +#include "system.h" + +#include "json/json.h" + +#include "libMBDebugHelper.h" + +namespace NsMessageBroker { +/** + * \class CMessage + * \brief CMessage class implementation. + */ +class CMessage { + public: + /** + * \brief Constructor. + */ + CMessage(int aSenderFp, Json::Value aMessage) { + mSenderFd = aSenderFp; + mMessage = aMessage; + } + + /** + * \brief Destructor. + */ + ~CMessage() { + } + + /** + * \brief getter for Json::Value message. + * \return Json::Value message. + */ + Json::Value getMessage() const { + return mMessage; + } + + /** + * \brief getter for sender FileDescriptor. + * \return sender FileDescriptor. + */ + int getSenderFd() const { + return mSenderFd; + } + private: + /** + * \brief sender FileDescriptor. + */ + int mSenderFd; + + /** + * \brief Json::Value message. + */ + Json::Value mMessage; +}; + + +class CMessageBroker_Private { + public: + /** + * \brief Constructor. + */ + CMessageBroker_Private(); + + /** + * \brief Check if que empty (Thread safe). + * \return True when empty. + */ + bool isEventQueueEmpty(); + + /** + * \brief Pop message from que (Thread safe). + * \return Pointer to CMessage. + */ + CMessage* popMessage(); + + /** + * \brief Push message to que (Thread safe). + * \param pMessage pointer to new CMessage object. + */ + void pushMessage(CMessage* pMessage); + + /** + * \brief gets destination component name. + * \param pMessage JSON message. + * \return string destination component name. + */ + std::string getDestinationComponentName(CMessage* pMessage); + + /** + * \brief gets method name. + * \param pMessage JSON message. + * \return string method name. + */ + std::string getMethodName(CMessage* pMessage); + + /** + * \brief checks is message notification or not. + * \param pMessage JSON message. + * \return true if notification. + */ + bool isNotification(CMessage* pMessage); + + /** + * \brief checks is message response or not. + * \param pMessage JSON message. + * \return true if response. + */ + bool isResponse(CMessage* pMessage); + + /** + * \brief checks message. + * \param pMessage JSON message. + * \param error JSON message to fill in case of any errors. + * \return true if message is good. + */ + bool checkMessage(CMessage* pMessage, Json::Value& error); + + /** + * \brief Process internal MessageBrocker message + * + * \brief Register controller in MessageBroker. + * Use following JSON command to register new component: + * \code + * {"jsonrpc": "2.0", "method": "MB.registerComponent", "params": ""} + * \endcode + * + * \brief Unregister controller in MessageBroker. + * Use following JSON command to unregister component: + * \code + * {"jsonrpc": "2.0", "method": "MB.unregisterComponent", "params": ""} + * \endcode + * + * \brief Subscribe controller on property change. + * Use following JSON command to subscribe to notifications: + * \code + * {"jsonrpc": "2.0", "method": "MB.subscribeTo", "params": "."} + * \endcode + * + * \brief Unsubscribe controller from property change. + * Use following JSON command to unsubscribe from notifications: + * \code + * {"jsonrpc": "2.0", "method": "MB.unsubscribeFrom", "params": "."} + * \endcode + * + * \param pMessage JSON message. + */ + void processInternalMessage(CMessage* pMessage); + + /** + * \brief process external message. + * \param pMessage JSON message. + */ + void processExternalMessage(CMessage* pMessage); + + /** + * \brief process response. + * \param pMessage JSON message. + */ + void processResponse(CMessage* pMessage); + + /** + * \brief Process notification message. + * \brief Notify subscribers about property change. + * expected notification format example: + * \code + * {"jsonrpc": "2.0", "method": ".", "params": } + * \endcode + * \param pMessage JSON message. + */ + void processNotification(CMessage* pMessage); + + /** + * \brief send error message. + * \param pMessage JSON message. + */ + void processError(CMessage* pMessage); + + /** + * \brief send Json message. + * \param fd FileDescriptor of socket. + * \param message JSON message. + */ + void sendJsonMessage(int fd, Json::Value message); + + /** + * \brief push message to wait response que. + * \param pMessage JSON message. + */ + void pushMessageToWaitQue(CMessage* pMessage); + + /** + * \brief Returns start position for Id's generator of controller. + * \return start position for Id's generator of controller (1000 id's). + */ + int getNextControllerIdDiapason() { + return 1000 * mControllersIdCounter++; + } + + /** + * \brief pop message from wait response que. + * \param pMessage JSON message. + */ + int popMessageFromWaitQue(CMessage* pMessage); + + /** + * \brief Tries to remove the parsed part of the buffer + * \param root Parsed JSON value + * \param aJSONData The string buffer + * \return true on success, false on failure + */ + bool cutParsedJSON(const Json::Value& root, std::string& aJSONData); + + /** + * \brief Finds the position just after a JSON object or array in a buffer + * \param isObject Must be true for object, false for array + * \param aJSONData The string buffer + * \return The position in the buffer after the object or array on success, + * std::strin::npos on failure + */ + size_t jumpOverJSONObjectOrArray(bool isObject, const std::string& aJSONData); + + /** + * \brief Finds the position just after a JSON string in a buffer + * \param aJSONData The string buffer + * \return The position in the buffer after the string on success, + * std::strin::npos on failure + */ + size_t jumpOverJSONString(const std::string& aJSONData); + + /** + * \brief Que of messages. + */ + std::deque mMessagesQueue; + + /** + * \brief Counter of messages Id's diapason for the next controllers + * From mControllersIdCounter*1000 to mControllersIdCounter*1000+999. + */ + int mControllersIdCounter; + + /** + * \brief Que of messages which are waiting the response in format: MessageId:SenderFd. + */ + std::map mWaitResponseQueue; + + /** + * \brief Pointer to sender. + */ + CSender* mpSender; + + /** + * \brief Pointer to registry. + */ + CMessageBrokerRegistry* mpRegistry; + + /** + * \brief JSON reader. + */ + Json::Reader m_reader; + + /** + * \brief JSON writer. + */ + Json::FastWriter m_writer; + + /** + * \brief JSON writer for receiver. + */ + Json::FastWriter m_recieverWriter; + + /** + * \brief Messages que mutex. + */ + System::Mutex mMessagesQueueMutex; + + /** + * \brief Binary semaphore that is used to notify the + * messaging thread that a new message is available. + */ + System::BinarySemaphore m_messageQueueSemaphore; +}; + +CMessageBroker_Private::CMessageBroker_Private() : + mControllersIdCounter(1), + mpSender(NULL) { + mpRegistry = CMessageBrokerRegistry::getInstance(); +} + + +CMessageBroker::CMessageBroker() : + p(new CMessageBroker_Private()) { +} + +CMessageBroker::~CMessageBroker() { + delete p, p = 0; +} + +CMessageBroker* CMessageBroker::getInstance() { + static CMessageBroker instance; + return &instance; +} + + +size_t CMessageBroker_Private::jumpOverJSONObjectOrArray(bool isObject, + const std::string& aJSONData) { + const char openBracket = isObject? '{' : '['; + const char closeBracket = isObject? '}' : ']'; + int open_minus_close_brackets(1); + size_t position = aJSONData.find(openBracket); // Find the beginning of the object + + while ((position != std::string::npos) && (open_minus_close_brackets > 0)) { + position = aJSONData.find_first_of(std::string("\"")+openBracket+closeBracket, + position+1); + if (std::string::npos == position) { + break; + } + if ('"' == aJSONData[position]) { + // Ignore string interior, which might contain brackets and escaped "-s + do { + position = aJSONData.find('"', position+1); // Find the closing quote + } while ((std::string::npos != position) && ('\\' == aJSONData[position-1])); + } else if (openBracket == aJSONData[position]) { + ++open_minus_close_brackets; + } else if (closeBracket == aJSONData[position]) { + --open_minus_close_brackets; + } + } + + if ((0 == open_minus_close_brackets) && (std::string::npos != position)) { + ++position; // Move after the closing bracket + } else { + position = std::string::npos; + } + + return position; +} + + +size_t CMessageBroker_Private::jumpOverJSONString(const std::string& aJSONData) { + size_t position = aJSONData.find('"'); // Find the beginning of the string + + do { + position = aJSONData.find('"', position+1); // Find the closing quote + } while ((std::string::npos != position) && ('\\' == aJSONData[position-1])); + + if (std::string::npos != position) { + ++position; // Move after the closing quote + } + + return position; +} + + +bool CMessageBroker_Private::cutParsedJSON(const Json::Value& root, + std::string& aJSONData) { + if (root.isNull() || aJSONData.empty()) { + DBG_MSG_ERROR(("JSON is null or the buffer is empty!\n")); + return false; + } + + std::string parsed_json_str = m_recieverWriter.write(root); + DBG_MSG(("Parsed JSON string: '%s'\n", parsed_json_str.c_str())); + + // Trim front spaces (if any) + const size_t nonempty_position = aJSONData.find_first_not_of(" \t\n\v\f\r"); + aJSONData.erase(0, nonempty_position); + if (std::string::npos == nonempty_position) { + DBG_MSG_ERROR(("Buffer contains only blanks!\n")); + return false; + } + + // JSON writer puts '\n' at the end. Remove it. + const size_t final_lf_pos = parsed_json_str.rfind('\n'); + if (final_lf_pos == parsed_json_str.length()-1) { + parsed_json_str.erase(final_lf_pos, 1); + } + + /* RFC 4627: "A JSON value MUST be an object, array, number, or string, or + * one of the following three literal names: false null true" + * So we will try to find the borders of the parsed part based on its type. */ + + size_t position(std::string::npos); + + if (0 == aJSONData.find(parsed_json_str)) { + // If by chance parsed JSON is the same in the buffer and is at the beginning + position = parsed_json_str.length(); + } else if (root.isObject() || root.isArray()) { + position = jumpOverJSONObjectOrArray(root.isObject(), aJSONData); + } else if (root.isString()) { + position = jumpOverJSONString(aJSONData); + } else if (root.isNumeric()) { + position = aJSONData.find_first_not_of("+-0123456789.eE"); + } else if (root.isBool() || ("null" == parsed_json_str)) { + position = aJSONData.find(parsed_json_str); + if (std::string::npos != position) { + position += parsed_json_str.length(); + } + } else { + DBG_MSG_ERROR(("Unknown JSON type!\n")); + } + + if (std::string::npos == position) { + DBG_MSG_ERROR(("Error finding JSON object boundaries!\n")); + /* This should not happen, because the string is already parsed as a + * valid JSON. If this happens then above code is wrong. It is better + * to assert() than just return here, because otherwise we may enter an + * endless cycle - fail to process one and the same message again and + * again. Or we may clear the buffer and return, but in this way we will + * loose the next messages, miss a bug here, and create another bug. */ + assert(std::string::npos != position); + return false; // For release version + } + + if ((position >= aJSONData.length()) || + ((position == aJSONData.length()-1) && isspace(aJSONData[position]))) { + // No next object. Clear entire aJSONData. + aJSONData = ""; + } else { + // There is another object. Clear the current one. + aJSONData.erase(0, position); + } + + return true; +} + + +void CMessageBroker::onMessageReceived(int fd, std::string& aJSONData, bool tryHard) { + DBG_MSG(("CMessageBroker::onMessageReceived(%d, '%s')\n", fd, aJSONData.c_str())); + + while (! aJSONData.empty()) { + Json::Value root; + if ((! p->m_reader.parse(aJSONData, root)) || root.isNull()) { + DBG_MSG_ERROR(("Unable to parse JSON!")); + if (! tryHard) { + return; + } + uint8_t first_byte = static_cast(aJSONData[0]); + if ((first_byte <= 0x08) || ((first_byte >= 0x80) && (first_byte <= 0x88))) { + DBG_MSG((" There is an unparsed websocket header probably.\n")); + /* Websocket headers can have FIN flag set in the first byte (0x80). + * Then there are 3 zero bits and 4 bits for opcode (from 0x00 to 0x0A). + * But actually we don't use opcodes above 0x08. + * Use this fact to distinguish websocket header from payload text data. + * It can be a coincidence of course, but we have to give it a try. */ + return; + } else if ('{' == aJSONData[0]) { + DBG_MSG_ERROR((" Incomplete JSON object probably.\n")); + return; + } else { + DBG_MSG_ERROR((" Step in the buffer and try again...\n")); + aJSONData.erase(0, 1); + DBG_MSG_ERROR(("Buffer after cut is: '%s'\n", aJSONData.c_str())); + continue; + } + + } else if (! root.isObject()) { + /* JSON RPC 2.0 messages are objects. Batch calls must be pre-rpocessed, + * so no need for "and !root.isArray()" */ + DBG_MSG_ERROR(("Parsed JSON is not an object!\n")); + if (! tryHard) { + return; + } + // Cut parsed data from the buffer below and continue + + } else if ((!root.isMember("jsonrpc")) || (root["jsonrpc"]!="2.0")) { + DBG_MSG_ERROR(("'jsonrpc' is not set correctly in parsed JSON!\n")); + if (! tryHard) { + return; + } + // Cut parsed object from the buffer below and continue + + } else { + // Parsing successful. Pass the message up. + p->pushMessage(new CMessage(fd, root)); + } + + p->cutParsedJSON(root, aJSONData); + + DBG_MSG(("Buffer after cut is: '%s'\n", aJSONData.c_str())); + } +} + +void CMessageBroker::Test() { + Json::Value root, err; + std::string ReceivingBuffer = + "{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"MB.registerComponent\",\"params\":{\"componentName\":\"AVA\"}}123{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"MB.registerComponent\",\"params\":{\"componentName\":\"AVA\"}}"; + DBG_MSG(("String is:%s\n", ReceivingBuffer.c_str())); + while (1) { + if (!p->m_reader.parse(ReceivingBuffer, root)) { + DBG_MSG_ERROR(("Received not JSON string! %s\n", ReceivingBuffer.c_str())); + return; + } + std::string wmes = p->m_recieverWriter.write(root); + DBG_MSG(("Parsed JSON string:%s; length: %d\n", wmes.c_str(), wmes.length())); + DBG_MSG(("Buffer is:%s\n", ReceivingBuffer.c_str())); + ssize_t beginpos = ReceivingBuffer.find(wmes); + ReceivingBuffer.erase(0, beginpos + wmes.length()); + DBG_MSG(("Buffer after cut is:%s\n", ReceivingBuffer.c_str())); + CMessage message(0, root); + if (p->checkMessage(&message, err)) { + //here put message to que + } else { + DBG_MSG_ERROR(("Wrong message:%s\n", wmes.c_str())); + } + } +} + +void CMessageBroker::OnSocketClosed(const int fd) { + DBG_MSG(("CMessageBroker::OnSocketClosed(%d)\n", fd)); + if (p->mpRegistry) { + p->mpRegistry->removeControllersByDescriptor(fd); + } +} + +void CMessageBroker::startMessageBroker(CSender* pSender) { + DBG_MSG(("CMessageBroker::startMessageBroker()\n")); + p->mpSender = pSender; +} + +void CMessageBroker::stopMessageBroker() { + p->mpSender = NULL; + DBG_MSG(("CMessageBroker::stopMessageBroker()\n")); +} + +CMessage* CMessageBroker_Private::popMessage() { + CMessage* ret = NULL; + DBG_MSG(("CMessageBroker::popMessage()\n")); + mMessagesQueueMutex.Lock(); + if (false == mMessagesQueue.empty()) { + ret = mMessagesQueue.front(); + mMessagesQueue.pop_front();// delete message from que + } else { + DBG_MSG(("Que is empty!\n")); + } + mMessagesQueueMutex.Unlock(); + return ret; +} + +void CMessageBroker_Private::pushMessage(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::pushMessage()\n")); + mMessagesQueueMutex.Lock(); + if (pMessage) { + mMessagesQueue.push_back(pMessage); + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } + mMessagesQueueMutex.Unlock(); + + m_messageQueueSemaphore.Notify(); +} + +bool CMessageBroker_Private::isEventQueueEmpty() { + bool bResult = true; + mMessagesQueueMutex.Lock(); + bResult = mMessagesQueue.empty(); + mMessagesQueueMutex.Unlock(); + return bResult; +} + +std::string CMessageBroker_Private::getDestinationComponentName(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::getDestinationComponentName()\n")); + std::string ret = ""; + if (pMessage) { + Json::Value mes = pMessage->getMessage(); + std::string method = mes["method"].asString(); + int pos = method.find("."); + if (-1 != pos) { + ret = method.substr(0, pos); + } + DBG_MSG(("Destination component is: %s\n", ret.c_str())); + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } + return ret; +} + +std::string CMessageBroker_Private::getMethodName(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::getMethodName()\n")); + std::string ret = ""; + if (pMessage) { + Json::Value mes = pMessage->getMessage(); + std::string method = mes["method"].asString(); + int pos = method.find("."); + if (-1 != pos) { + ret = method.substr(pos + 1); + } + DBG_MSG(("Method is: %s\n", ret.c_str())); + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } + return ret; +} + +bool CMessageBroker_Private::isNotification(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::isNotification()\n")); + bool ret = false; + Json::Value mes = pMessage->getMessage(); + if (false == mes.isMember("id")) { + ret = true; + } + DBG_MSG(("Result: %d\n", ret)); + return ret; +} + +bool CMessageBroker_Private::isResponse(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::isResponse()\n")); + bool ret = false; + Json::Value mes = pMessage->getMessage(); + if ((true == mes.isMember("result")) || (true == mes.isMember("error"))) { + ret = true; + } + DBG_MSG(("Result: %d\n", ret)); + return ret; +} + +void CMessageBroker_Private::pushMessageToWaitQue(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::pushMessageToWaitQue()\n")); + if (pMessage) { + Json::Value root = pMessage->getMessage(); + mWaitResponseQueue.insert(std::map::value_type(root["id"].asInt(), pMessage->getSenderFd())); + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } +} + +int CMessageBroker_Private::popMessageFromWaitQue(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::popMessageFromWaitQue()\n")); + int result = -1; + if (pMessage) { + Json::Value root = pMessage->getMessage(); + int messageId = root["id"].asInt(); + std::map ::iterator it; + it = mWaitResponseQueue.find(messageId); + if (it != mWaitResponseQueue.end()) { + result = (*it).second; + mWaitResponseQueue.erase(it); + } + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } + DBG_MSG(("Senders Fd: %d\n", result)); + return result; +} + +void CMessageBroker_Private::processInternalMessage(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::processInternalMessage()\n")); + if (pMessage) { + std::string amethodName = getMethodName(pMessage); + DBG_MSG(("Method: %s\n", amethodName.c_str())); + Json::Value root = pMessage->getMessage(); + if ("registerComponent" == amethodName) { + Json::Value params = root["params"]; + if (params.isMember("componentName") && params["componentName"].isString()) { + std::string controllerName = params["componentName"].asString(); + if (mpRegistry->addController(pMessage->getSenderFd(), controllerName)) { + Json::Value response; + response["id"] = root["id"]; + response["jsonrpc"] = "2.0"; + response["result"] = getNextControllerIdDiapason(); + sendJsonMessage(pMessage->getSenderFd(), response); + } else { + Json::Value error, err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = CONTROLLER_EXISTS; + err["message"] = "Controller has been already registered."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else { + Json::Value error, err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Wrong method parameter."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else if ("subscribeTo" == amethodName) { + Json::Value params = root["params"]; + if (params.isMember("propertyName") && params["propertyName"].isString()) { + std::string propertyName = params["propertyName"].asString(); + if (mpRegistry->addSubscriber(pMessage->getSenderFd(), propertyName)) { + Json::Value response; + response["id"] = root["id"]; + response["jsonrpc"] = "2.0"; + response["result"] = "OK"; + sendJsonMessage(pMessage->getSenderFd(), response); + } else { + Json::Value error, err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = CONTROLLER_EXISTS; + err["message"] = "Subscribe has been already registered."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else { + Json::Value error, err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Wrong method parameter."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else if ("unregisterComponent" == amethodName) { + Json::Value params = root["params"]; + if (params.isMember("componentName") && params["componentName"].isString()) { + std::string controllerName = params["componentName"].asString(); + mpRegistry->deleteController(controllerName); + Json::Value response; + response["id"] = root["id"]; + response["jsonrpc"] = "2.0"; + response["result"] = "OK"; + sendJsonMessage(pMessage->getSenderFd(), response); + } else { + Json::Value error, err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Wrong method parameter."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else if ("unsubscribeFrom" == amethodName) { + Json::Value params = root["params"]; + if (params.isMember("propertyName") && params["propertyName"].isString()) { + std::string propertyName = params["propertyName"].asString(); + mpRegistry->deleteSubscriber(pMessage->getSenderFd(), propertyName); + Json::Value response; + response["id"] = root["id"]; + response["jsonrpc"] = "2.0"; + response["result"] = "OK"; + sendJsonMessage(pMessage->getSenderFd(), response); + } else { + Json::Value error, err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Wrong method parameter."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else { + DBG_MSG(("Unknown method!\n")); + Json::Value error; + Json::Value err; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Invalid MessageBroker method."; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } +} + +void CMessageBroker_Private::processExternalMessage(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::processExternalMessage()\n")); + if (pMessage) { + std::string destComponentName = getDestinationComponentName(pMessage); + int destFd = mpRegistry->getDestinationFd(destComponentName); + Json::Value root = pMessage->getMessage(); + if (0 < destFd) { + sendJsonMessage(destFd, root); + pushMessageToWaitQue(pMessage); + } else { + // error, controller not found in the registry + DBG_MSG(("Unknown method!\n")); + Json::Value error; + Json::Value err; + Json::Value error_data; + error["id"] = root["id"]; + error["jsonrpc"] = "2.0"; + err["code"] = UNSUPPORTED_RESOURCE; + err["message"] = "Destination controller not found!"; + error_data["method"] = root["method"]; + err["data"] = error_data; + error["error"] = err; + processError(new CMessage(pMessage->getSenderFd(), error)); + } + } else { + DBG_MSG_ERROR(("NULL pointer\n")); + } +} + +void CMessageBroker_Private::processResponse(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::processResponse()\n")); + if (pMessage) { + int senderFd = popMessageFromWaitQue(pMessage); + if (-1 != senderFd) { + sendJsonMessage(senderFd, pMessage->getMessage()); + } + } else { + DBG_MSG_ERROR(("NULL pointer\n")); + } +} + +void CMessageBroker_Private::processNotification(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::processNotification()\n")); + if (pMessage) { + Json::Value root = pMessage->getMessage(); + std::string methodName = root["method"].asString(); + DBG_MSG(("Property: %s\n", methodName.c_str())); + std::vector result; + int subscribersCount = mpRegistry->getSubscribersFd(methodName, result); + if (0 < subscribersCount) { + std::vector::iterator it; + for (it = result.begin(); it != result.end(); it++) { + sendJsonMessage(*it, root); + } + } else { + DBG_MSG(("No subscribers for this property!\n")); + } + } else { + DBG_MSG_ERROR(("NULL pointer\n")); + } +} + +void CMessageBroker_Private::processError(CMessage* pMessage) { + DBG_MSG(("CMessageBroker::processError()\n")); + if (pMessage) { + sendJsonMessage(pMessage->getSenderFd(), pMessage->getMessage()); + delete pMessage;// delete CMessage object with error description!!! + } else { + DBG_MSG_ERROR(("NULL pointer\n")); + } +} + +void CMessageBroker_Private::sendJsonMessage(int fd, Json::Value message) { + DBG_MSG(("CMessageBroker::sendJsonMessage(%d)\n", fd)); + if (mpSender) { + std::string mes = m_writer.write(message); + int retVal = mpSender->Send(fd, mes); + if (retVal == -1) { + DBG_MSG_ERROR(("Message hasn't been sent!\n")); + return; + } + DBG_MSG(("Length:%d, Sent: %d bytes\n", mes.length(), retVal)); + } else { + DBG_MSG_ERROR(("mpSender NULL pointer\n")); + } +} + +void* CMessageBroker::MethodForThread(void* arg) { + arg = arg; // to avoid compiler warnings + while (1) { + while (!p->isEventQueueEmpty()) { + CMessage* message = p->popMessage(); + if (message) { + Json::Value error; + if (p->checkMessage(message, error)) { + if (p->isNotification(message)) { + DBG_MSG(("Message is notification!\n")); + p->processNotification(message); + } else if (p->isResponse(message)) { + DBG_MSG(("Message is response!\n")); + p->processResponse(message); + } else { + if ("MB" == p->getDestinationComponentName(message)) { + DBG_MSG(("Internal MessageBroker method!\n")); + p->processInternalMessage(message); + } else { + DBG_MSG(("Not MessageBroker method!\n")); + p->processExternalMessage(message); + } + } + } else { + DBG_MSG_ERROR(("Message contains wrong data!\n")); + CMessage* errMessage = new CMessage(message->getSenderFd(), error); + if (NULL != errMessage) { + p->processError(errMessage); + } else { + DBG_MSG_ERROR(("NULL pointer!\n")); + } + } + delete message;// delete message object + } + } + p->m_messageQueueSemaphore.Wait(); + } + + return NULL; +} + +bool CMessageBroker_Private::checkMessage(CMessage* pMessage, Json::Value& error) { + DBG_MSG(("CMessageBroker::checkMessage()\n")); + Json::Value root; + root = pMessage->getMessage(); + Json::Value err; + + /* check the JSON-RPC version => 2.0 */ + if (!root.isObject() || !root.isMember("jsonrpc") || root["jsonrpc"] != "2.0") { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Invalid JSON RPC version."; + error["error"] = err; + return false; + } + + /* Check the id of message */ + if (root.isMember("id") && (root["id"].isArray() || root["id"].isObject() || root["id"].isString())) { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Invalid ID of message."; + error["error"] = err; + return false; + } + + /* extract "method" attribute */ + if (root.isMember("method")) { + if (!root["method"].isString()) { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Invalid JSONRPC method."; + error["error"] = err; + return false; + } + /* Check the params is an object*/ + if (root.isMember("params") && !root["params"].isObject()) { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Invalid JSONRPC params."; + error["error"] = err; + return false; + } + } else if (!(root.isMember("result") || root.isMember("error"))) { + error["id"] = Json::Value::null; + error["jsonrpc"] = "2.0"; + err["code"] = INVALID_REQUEST; + err["message"] = "Unknwn message type."; + error["error"] = err; + return false; + } + return true; +} +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBrokerRegistry.cpp b/src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBrokerRegistry.cpp new file mode 100644 index 0000000000..fb24d08f1c --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/CMessageBrokerRegistry.cpp @@ -0,0 +1,191 @@ +/** + * \file CMessageBrokerRegistry.cpp + * \brief CMessageBrokerRegistry singletone class implementation. + * \author AKara + */ + +#include "CMessageBrokerRegistry.hpp" +#include "libMBDebugHelper.h" + +#include +#include + +namespace NsMessageBroker +{ + CMessageBrokerRegistry::CMessageBrokerRegistry() + { + } + + CMessageBrokerRegistry::~CMessageBrokerRegistry() + { + } + + CMessageBrokerRegistry* CMessageBrokerRegistry::getInstance() + { + static CMessageBrokerRegistry instance; + return &instance; + } + + bool CMessageBrokerRegistry::addController(int fd, std::string name) + { + DBG_MSG(("CMessageBrokerRegistry::addController()\n")); + bool result = false; + std::map ::iterator it; + + sync_primitives::AutoLock lock(mControllersListLock); + it = mControllersList.find(name); + if (it == mControllersList.end()) + { + mControllersList.insert(std::map ::value_type(name, fd)); + result = true; + } else + { + DBG_MSG(("Controller already exists!\n")); + } + + DBG_MSG(("Count of controllers: %d\n", mControllersList.size())); + return result; + } + + void CMessageBrokerRegistry::deleteController(std::string name) + { + DBG_MSG(("CMessageBrokerRegistry::deleteController()\n")); + std::map ::iterator it; + + int fd; + { + sync_primitives::AutoLock lock(mControllersListLock); + it = mControllersList.find(name); + if (it != mControllersList.end()) + { + fd = it->second; + mControllersList.erase(it); + } else { + DBG_MSG(("No such controller in the list!\n")); + return; + } + DBG_MSG(("Count of controllers: %d\n", mControllersList.size())); + } + removeSubscribersByDescriptor(fd); + } + + void CMessageBrokerRegistry::removeControllersByDescriptor(const int fd) { + DBG_MSG(("CMessageBrokerRegistry::removeControllersByDescriptor(%d)\n", + fd)); + { + sync_primitives::AutoLock lock(mControllersListLock); + std::map ::iterator it = mControllersList.begin(); + for (; it != mControllersList.end();) { + if (it->second == fd) { + mControllersList.erase(it++); + } else { + ++it; + } + } + } + removeSubscribersByDescriptor(fd); + } + + void CMessageBrokerRegistry::removeSubscribersByDescriptor(const int fd) { + DBG_MSG(("CMessageBrokerRegistry::removeSubscribersByDescriptor(%d)\n", + fd)); + sync_primitives::AutoLock lock(mSubscribersListLock); + std::multimap ::iterator it_s = mSubscribersList.begin(); + for (; it_s !=mSubscribersList.end(); ) { + if (it_s->second == fd) { + mSubscribersList.erase(it_s++); + } else { + ++it_s; + } + } + } + + bool CMessageBrokerRegistry::addSubscriber(int fd, std::string name) + { + DBG_MSG(("CMessageBrokerRegistry::addSubscriber()\n")); + bool result = true; + + sync_primitives::AutoLock lock(mSubscribersListLock); + std::pair::iterator, std::multimap ::iterator> p = mSubscribersList.equal_range(name); + if (p.first != p.second) + { + std::multimap ::iterator itr; + for (itr = p.first; itr != p.second; itr++) + { + if (fd == itr->second) + { + result = false; + DBG_MSG(("Subscriber already exists!\n")); + } + } + } + if (result) + { + mSubscribersList.insert(std::map ::value_type(name, fd)); + } + + DBG_MSG(("Count of subscribers: %d\n", mSubscribersList.size())); + return result; + } + + void CMessageBrokerRegistry::deleteSubscriber(int fd, std::string name) + { + DBG_MSG(("CMessageBrokerRegistry::deleteSubscriber()\n")); + + sync_primitives::AutoLock lock(mSubscribersListLock); + std::pair::iterator, std::multimap ::iterator> p = mSubscribersList.equal_range(name); + if (p.first != p.second) { + std::multimap ::iterator itr; + for (itr = p.first; itr != p.second; ) { + DBG_MSG(("My for loop %s, %d", itr->first.c_str() ,itr->second)); + if (fd == itr->second) { + mSubscribersList.erase(itr++); + } else { + ++itr; + } + } + } + + DBG_MSG(("Count of subscribers: %d\n", mSubscribersList.size())); + } + + int CMessageBrokerRegistry::getDestinationFd(std::string name) + { + DBG_MSG(("CMessageBrokerRegistry::getDestinationFd()\n")); + int result = -1; + std::map ::iterator it; + + sync_primitives::AutoLock lock(mControllersListLock); + it = mControllersList.find(name); + if (it != mControllersList.end()) + { + result = it->second; + } + + DBG_MSG(("Controllers Fd: %d\n", result)); + return result; + } + + int CMessageBrokerRegistry::getSubscribersFd(std::string name, std::vector& result) + { + DBG_MSG(("CMessageBrokerRegistry::getSubscribersFd()\n")); + int res = 0; + std::map ::iterator it; + + sync_primitives::AutoLock lock(mSubscribersListLock); + std::pair::iterator, std::multimap ::iterator> p = mSubscribersList.equal_range(name); + if (p.first != p.second) + { + std::multimap ::iterator itr; + for (itr = p.first; itr != p.second; itr++) + { + result.push_back(itr->second); + DBG_MSG(("Controllers Fd: %d\n", itr->second)); + } + } + + res = result.size(); + DBG_MSG(("Result vector size: %d\n", res)); + return res; + } +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/libMBDebugHelper.h b/src/3rd_party-static/message_broker/src/lib_messagebroker/libMBDebugHelper.h new file mode 100644 index 0000000000..0d5260cdda --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/libMBDebugHelper.h @@ -0,0 +1,43 @@ +/** + * \file libMBDebugHelper.h + * \brief DebugHelper. + * \author AKara + */ + +#ifndef MB_DEBUG_HELPER_H +#define MB_DEBUG_HELPER_H + +#include + +/** +* \def DEBUG_MB_ON +* \brief Switches on MessageBroker debug messages. +*/ +#ifdef DEBUG_MB_ON + +/** +* \def DBG_MSG +* \brief Debug message output with file name and line number. +* \param x formatted debug message. +* \return printf construction. +*/ +#define DBG_MSG(x) printf("%s:%d_lib ", __FILE__, __LINE__);\ + printf x + +/** + * \def DBG_MSG_ERROR + * \brief Debug ERROR message output with file name and line number. + * \param x formatted debug message. + * \return printf construction. + */ +#define DBG_MSG_ERROR(x) printf("ERROR!!! %s:%d_lib ", __FILE__, __LINE__);\ + printf x + +#else + +#define DBG_MSG(x) +#define DBG_MSG_ERROR(x) + +#endif + +#endif /*MB_DEBUG_HELPER_H*/ diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/md5.cpp b/src/3rd_party-static/message_broker/src/lib_messagebroker/md5.cpp new file mode 100644 index 0000000000..b3e347d9d7 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/md5.cpp @@ -0,0 +1,373 @@ +/* MD5 + converted to C++ class by Frank Thilo (thilo@unix-ag.org) + for bzflag (http://www.bzflag.org) + + based on: + + md5.h and md5.c + reference implemantion of RFC 1321 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + + */ + +/* interface header */ +#include "md5.h" + +/* system implementation headers */ +#include +#include + +// Constants for MD5Transform routine. +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +/////////////////////////////////////////////// + +// F, G, H and I are basic MD5 functions. +inline MD5::uint4 MD5::F(uint4 x, uint4 y, uint4 z) { + return (x&y) | (~x&z); +} + +inline MD5::uint4 MD5::G(uint4 x, uint4 y, uint4 z) { + return (x&z) | (y&~z); +} + +inline MD5::uint4 MD5::H_(uint4 x, uint4 y, uint4 z) { + return x^y^z; +} + +inline MD5::uint4 MD5::I(uint4 x, uint4 y, uint4 z) { + return y ^ (x | ~z); +} + +// rotate_left rotates x left n bits. +inline MD5::uint4 MD5::rotate_left(uint4 x, int n) { + return (x << n) | (x >> (32-n)); +} + +// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +// Rotation is separate from addition to prevent recomputation. +inline void MD5::FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a+ F(b,c,d) + x + ac, s) + b; +} + +inline void MD5::GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + G(b,c,d) + x + ac, s) + b; +} + +inline void MD5::HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + H_(b,c,d) + x + ac, s) + b; +} + +inline void MD5::II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) { + a = rotate_left(a + I(b,c,d) + x + ac, s) + b; +} + +////////////////////////////////////////////// + +// default ctor, just initailize +MD5::MD5() +{ + init(); +} + +////////////////////////////////////////////// + +// nifty shortcut ctor, compute MD5 for string and finalize it right away +MD5::MD5(const std::string &text) +{ + init(); + update(text.c_str(), text.length()); + finalize(); +} + +////////////////////////////// + +void MD5::init() +{ + finalized=false; + + count[0] = 0; + count[1] = 0; + + // load magic initialization constants. + state[0] = 0x67452301; + state[1] = 0xefcdab89; + state[2] = 0x98badcfe; + state[3] = 0x10325476; +} + +////////////////////////////// + +// decodes input (unsigned char) into output (uint4). Assumes len is a multiple of 4. +void MD5::decode(uint4 output[], const uint1 input[], size_type len) +{ + for (unsigned int i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | + (((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24); +} + +////////////////////////////// + +// encodes input (uint4) into output (unsigned char). Assumes len is +// a multiple of 4. +void MD5::encode(uint1 output[], const uint4 input[], size_type len) +{ + for (size_type i = 0, j = 0; j < len; i++, j += 4) { + output[j] = input[i] & 0xff; + output[j+1] = (input[i] >> 8) & 0xff; + output[j+2] = (input[i] >> 16) & 0xff; + output[j+3] = (input[i] >> 24) & 0xff; + } +} + +////////////////////////////// + +// apply MD5 algo on a block +void MD5::transform(const uint1 block[blocksize]) +{ + uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + decode (x, block, blocksize); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + // Zeroize sensitive information. + memset(x, 0, sizeof x); +} + +////////////////////////////// + +// MD5 block update operation. Continues an MD5 message-digest +// operation, processing another message block +void MD5::update(const unsigned char input[], size_type length) +{ + // compute number of bytes mod 64 + size_type index = count[0] / 8 % blocksize; + + // Update number of bits + if ((count[0] += (length << 3)) < (length << 3)) + count[1]++; + count[1] += (length >> 29); + + // number of bytes we need to fill in buffer + size_type firstpart = 64 - index; + + size_type i; + + // transform as many times as possible. + if (length >= firstpart) + { + // fill buffer first, transform + memcpy(&buffer[index], input, firstpart); + transform(buffer); + + // transform chunks of blocksize (64 bytes) + for (i = firstpart; i + blocksize <= length; i += blocksize) + transform(&input[i]); + + index = 0; + } + else + i = 0; + + // buffer remaining input + memcpy(&buffer[index], &input[i], length-i); +} + +////////////////////////////// + +// for convenience provide a verson with signed char +void MD5::update(const char input[], size_type length) +{ + update((const unsigned char*)input, length); +} + +////////////////////////////// + +// MD5 finalization. Ends an MD5 message-digest operation, writing the +// the message digest and zeroizing the context. +MD5& MD5::finalize() +{ + static unsigned char padding[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + if (!finalized) { + // Save number of bits + unsigned char bits[8]; + encode(bits, count, 8); + + // pad out to 56 mod 64. + size_type index = count[0] / 8 % 64; + size_type padLen = (index < 56) ? (56 - index) : (120 - index); + update(padding, padLen); + + // Append length (before padding) + update(bits, 8); + + // Store state in digest + encode(digest, state, 16); + + // Zeroize sensitive information. + memset(buffer, 0, sizeof buffer); + memset(count, 0, sizeof count); + + finalized=true; + } + + return *this; +} + +////////////////////////////// + +void MD5::getdigest(char *digest) const +{ + if (!finalized) + return; + + if (digest == NULL) + return; + + memcpy(digest, this->digest, 16); +} + +// return hex representation of digest as string +std::string MD5::hexdigest() const +{ + if (!finalized) + return ""; + + char buf[33]; + for (int i=0; i<16; i++) + sprintf(buf+i*2, "%02x", digest[i]); + buf[32]=0; + + return std::string(buf); +} + +////////////////////////////// + +std::ostream& operator<<(std::ostream& out, MD5 md5) +{ + return out << md5.hexdigest(); +} + +////////////////////////////// + +std::string md5(const std::string str) +{ + MD5 md5 = MD5(str); + + return md5.hexdigest(); +} \ No newline at end of file diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/md5.h b/src/3rd_party-static/message_broker/src/lib_messagebroker/md5.h new file mode 100644 index 0000000000..2c54c03b1b --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/md5.h @@ -0,0 +1,93 @@ +/* MD5 + converted to C++ class by Frank Thilo (thilo@unix-ag.org) + for bzflag (http://www.bzflag.org) + + based on: + + md5.h and md5.c + reference implementation of RFC 1321 + + Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + rights reserved. + + License to copy and use this software is granted provided that it + is identified as the "RSA Data Security, Inc. MD5 Message-Digest + Algorithm" in all material mentioning or referencing this software + or this function. + + License is also granted to make and use derivative works provided + that such works are identified as "derived from the RSA Data + Security, Inc. MD5 Message-Digest Algorithm" in all material + mentioning or referencing the derived work. + + RSA Data Security, Inc. makes no representations concerning either + the merchantability of this software or the suitability of this + software for any particular purpose. It is provided "as is" + without express or implied warranty of any kind. + + These notices must be retained in any copies of any part of this + documentation and/or software. + + */ + +#ifndef BZF_MD5_H +#define BZF_MD5_H + +#include +#include + +// a small class for calculating MD5 hashes of strings or byte arrays +// it is not meant to be fast or secure +// +// usage: 1) feed it blocks of uchars with update() +// 2) finalize() +// 3) get hexdigest() string +// or +// MD5(std::string).hexdigest() +// +// assumes that char is 8 bit and int is 32 bit +class MD5 +{ +public: + typedef unsigned int size_type; // must be 32bit + + MD5(); + MD5(const std::string& text); + void update(const unsigned char *buf, size_type length); + void update(const char *buf, size_type length); + MD5& finalize(); + void getdigest(char *digest) const; // digest must be 16 bytes long + std::string hexdigest() const; + friend std::ostream& operator<<(std::ostream&, MD5 md5); + +private: + void init(); + typedef unsigned char uint1; // 8bit + typedef unsigned int uint4; // 32bit + enum {blocksize = 64}; // VC6 won't eat a const static int here + + void transform(const uint1 block[blocksize]); + static void decode(uint4 output[], const uint1 input[], size_type len); + static void encode(uint1 output[], const uint4 input[], size_type len); + + bool finalized; + uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk + uint4 count[2]; // 64bit counter for number of bits (lo, hi) + uint4 state[4]; // digest so far + uint1 digest[16]; // the result + + // low level logic operations + static inline uint4 F(uint4 x, uint4 y, uint4 z); + static inline uint4 G(uint4 x, uint4 y, uint4 z); + static inline uint4 H_(uint4 x, uint4 y, uint4 z); + static inline uint4 I(uint4 x, uint4 y, uint4 z); + static inline uint4 rotate_left(uint4 x, int n); + static inline void FF(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void GG(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void HH(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); + static inline void II(uint4 &a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac); +}; + +std::string md5(const std::string str); + +#endif \ No newline at end of file diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp b/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp new file mode 100644 index 0000000000..456362f9d8 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/system.cpp @@ -0,0 +1,267 @@ +/* + * JsonRpc-Cpp - JSON-RPC implementation. + * Copyright (C) 2008-2011 Sebastien Vincent + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * \file system.cpp + * \brief System utils. + * \author Sebastien Vincent + */ + +#include +#include + +#include "system.h" + +namespace System { + +void msleep(unsigned long ms) { +#ifdef _WIN32 + Sleep(ms); +#else + /* Unix */ + struct timespec req; + req.tv_sec = ms / 1000; + req.tv_nsec = (ms % 1000) * 1000000; + nanosleep(&req, NULL); +#endif +} + +ThreadArg::~ThreadArg() { +} + +#ifndef WIN32 + +/* POSIX specific part for thread and mutex */ + +Thread::Thread(ThreadArg* arg) { + m_arg = arg; +} + +Thread::~Thread() { + delete m_arg; +} + +bool Thread::Start(bool detach) { + pthread_attr_t attr; + int ret = -1; + + /* must have valid object argument */ + if (m_arg == NULL) { + return false; + } + + /* set the detach state value */ + if (pthread_attr_init(&attr) != 0) { + return false; + } + + if (pthread_attr_setdetachstate(&attr, detach ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE) != 0) { + pthread_attr_destroy(&attr); + return false; + } + + /* create thread */ + ret = pthread_create(&m_id, &attr, &Thread::Call, this); + pthread_setname_np(m_id, "MB Thread"); + pthread_attr_destroy(&attr); + return ret == 0; +} + +bool Thread::Stop() { + pthread_cancel(m_id); + return false;// Android does not support 'pthread_cancel'; +} + +bool Thread::Join(void** ret) { + return pthread_join(m_id, ret) == 0; +} + +void* Thread::Call(void* arg) { + // Disable system signals receiving in thread + // by setting empty signal mask + // (system signals processes only in the main thread) + sigset_t set; + sigfillset(&set); + pthread_sigmask(SIG_SETMASK, &set, NULL); + + Thread* thread = static_cast(arg); + + /* call our specific object method */ + return thread->m_arg->Call(); +} + +Mutex::Mutex() { + pthread_mutexattr_t attr; + + pthread_mutexattr_init(&attr); + pthread_mutex_init(&m_mutex, &attr); + pthread_mutexattr_destroy(&attr); +} + +Mutex::~Mutex() { + pthread_mutex_destroy(&m_mutex); +} + +bool Mutex::Lock() { + return !pthread_mutex_lock(&m_mutex); +} + +bool Mutex::Unlock() { + return !pthread_mutex_unlock(&m_mutex); +} + + +// Based on Binary Semaphores example at +// http://www.mathcs.emory.edu/~cheung/Courses/455/Syllabus/5c-pthreads/sync.html +BinarySemaphore::BinarySemaphore() : + m_mutex(PTHREAD_MUTEX_INITIALIZER), + m_cond(PTHREAD_COND_INITIALIZER), + m_isUp(false) { + pthread_mutex_init(&m_mutex, NULL); + pthread_cond_init(&m_cond, NULL); +} + +BinarySemaphore::~BinarySemaphore() { + pthread_cond_destroy(&m_cond); + pthread_mutex_destroy(&m_mutex); +} + +void BinarySemaphore::Wait() { + // try to get exclusive access to the flag + pthread_mutex_lock(&m_mutex); + // success: no other thread can get here unless + // the current thread unlocks the mutex + + // wait until the flag is up + while (!m_isUp) { + pthread_cond_wait(&m_cond, &m_mutex); + // when the current thread executes this, it will be + // blocked on m_cond, and automatically unlocks the + // mutex! Unlocking the mutex will let other threads + // in to test the flag. + } + + // here we know that flag is upand this thread has now + // successfully passed the semaphore + + // this will cause all other threads that execute the Wait() + // call to wait in the above loop + m_isUp = false; + + // release the exclusive access to the flag + pthread_mutex_unlock(&m_mutex); +} + +void BinarySemaphore::Notify() { + // try to get exclusive access to the flag + pthread_mutex_lock(&m_mutex); + + // this call may resume a thread that is blocked on m_cond + // (in the Wait() call). if there was none, this does nothing + pthread_cond_signal(&m_cond); + + // up the flag + m_isUp = true; + + // release the exclusive access to the flag + pthread_mutex_unlock(&m_mutex); +} + +#else + +/* Windows specific part for thread and mutex */ + +Thread::Thread(ThreadArg* arg) { + m_arg = arg; +} + +Thread::~Thread() { + delete m_arg; +} + +bool Thread::Start(bool detach) { + detach = detach; /* unused parameter */ + + m_id = CreateThread(NULL, /* default security attributes */ + 0, /* use default stack size */ + &Thread::Call, /* thread function name */ + this, /* argument to thread function */ + 0, /* use default creation flags */ + NULL); /* returns the thread identifier */ + + return m_id != NULL; +} + +bool Thread::Stop() { + return TerminateThread(m_id, (DWORD) - 1); +} + +bool Thread::Join(void** ret) { + DWORD val = 0; + WaitForSingleObject(m_id, INFINITE); + GetExitCodeThread(m_id, &val); + CloseHandle(m_id); + m_id = NULL; + *ret = (void*)val; + return true; +} + +DWORD WINAPI Thread::Call(LPVOID arg) { + Thread* thread = static_cast(arg); + + /* call our specific object method */ +#ifdef _WIN64 + return (DWORD64)thread->m_arg->Call(); +#else + return (DWORD)thread->m_arg->Call(); +#endif +} + +Mutex::Mutex() { + m_mutex = CreateMutex(NULL, /* no security attribute */ + 0, /* not initial owner (i.e. no first lock) */ + NULL); /* no name */ +} + +Mutex::~Mutex() { + /* free mutex */ + if (m_mutex) { + CloseHandle(m_mutex); + } +} + +bool Mutex::Lock() { + if (!m_mutex) { + return false; + } + + return (WaitForSingleObject(m_mutex, INFINITE) == WAIT_OBJECT_0); +} + +bool Mutex::Unlock() { + if (!m_mutex) { + return false; + } + + return ReleaseMutex(m_mutex); +} + +#endif + +} /* namespace System */ + diff --git a/src/3rd_party-static/message_broker/src/lib_messagebroker/websocket_handler.cpp b/src/3rd_party-static/message_broker/src/lib_messagebroker/websocket_handler.cpp new file mode 100644 index 0000000000..7d3890b7a8 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/lib_messagebroker/websocket_handler.cpp @@ -0,0 +1,667 @@ +/** + * \file websocket_handler.cpp + * \brief WebSocket Handler. + * \author AKara + */ + +#include + +#include +#include +#include + +#ifdef _WIN32 +#include +#endif//_WIN32 + +#include "websocket_handler.hpp" + +#include "libMBDebugHelper.h" +#include "md5.h" + +namespace NsMessageBroker +{ + + unsigned int CWebSocketHandler::parseWebSocketDataLength( + const char* Buffer, unsigned int& b_size) { + + unsigned char payload = + (unsigned char)((Buffer[1] & 0x40) | (Buffer[1] & 0x20) | + (Buffer[1] & 0x10) | (Buffer[1] & 0x08) | (Buffer[1] & 0x04) | + (Buffer[1] & 0x02) | (Buffer[1] & 0x01)); + unsigned long length = 0; + unsigned char position = 2; // current buffer position + + switch(payload) { + case 126: + { + length = (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + break; + } + case 127: + { + length = (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + length <<=8; + length |= (unsigned char)Buffer[position++]; + break; + } + default: + { + length = payload; + return length; + } + } + + return length; + } + + int CWebSocketHandler::parseWebSocketData(char* Buffer, unsigned int& b_size) { + // Please see RFC6455 standard protocol specification: + //http://tools.ietf.org/html/rfc6455 + // Chapter 5.2 + DBG_MSG(("CWebSocketHandler::parseWebSocketData()b_size = %d\n", b_size)); + char* recBuffer = Buffer; + unsigned int parsedBufferPosition = 0; + unsigned char position = 0; // current buffer position + unsigned int size = b_size; + + static uint32_t minimum_heade_size = 4; + while (minimum_heade_size < size) { + + bool fin = ((recBuffer[0] & 0x80) | (recBuffer[0] & 0x01)) == 0x81; + bool rsv1 = (recBuffer[0] & 0x40) == 0x40; + bool rsv2 = (recBuffer[0] & 0x20) == 0x20; + bool rsv3 = (recBuffer[0] & 0x10) == 0x10; + unsigned char opCode = ((recBuffer[0] & 0x08) | (recBuffer[0] & 0x04) | + (recBuffer[0] & 0x02) | (recBuffer[0] & 0x01)); + + bool mask = (recBuffer[1] & 0x80) == 0x80; + + DBG_MSG(("CWebSocketHandler::fin = %d recBuffer[0] = 0x%02X\n" + " parsedlength = %d b_size= %d parsedBufferPosition = %d\n" + "rsv1 = %d, rsv2 = %d, rsv3 = %d, opCode = %u\n", + fin, recBuffer[0], parsedBufferPosition + position, + size, parsedBufferPosition, rsv1, rsv2, rsv3, opCode)); + + if ((rsv1)|(rsv2)|(rsv3)) { + DBG_MSG(("rsv1 or rsv2 or rsv3 is 0 \n")); + break; + } + + switch(opCode) { + case 0x0: break; //Continuation frame + case 0x1: break; //Text Frame + case 0x2: break; //Binary Frame + case 0x8: break; //Connection close Frame + case 0x9: break; //ping Frame + case 0xA: break; //Pong Frame + default: break; //Unknown frame + } + + if (false == fin) { + break; + } + + unsigned char payload = (unsigned char) + ((recBuffer[1] & 0x40) | (recBuffer[1] & 0x20) | (recBuffer[1] & 0x10) | + (recBuffer[1] & 0x08) | (recBuffer[1] & 0x04) | (recBuffer[1] & 0x02) | + (recBuffer[1] & 0x01)); + + unsigned long length = parseWebSocketDataLength(recBuffer, size); + position = 2; + + if (length > size) { + DBG_MSG_ERROR(("Incomplete message")); + break; + } + + switch(payload) { + case 126: { + position +=2; + break; + } + case 127: { + position +=8; + break; + } + default: { + break; + } + } + + if (mask) { + unsigned char maskKeys[4]; + maskKeys[0] = recBuffer[position++]; + maskKeys[1] = recBuffer[position++]; + maskKeys[2] = recBuffer[position++]; + maskKeys[3] = recBuffer[position++]; + DBG_MSG(("CWebSocketHandler::parseWebSocketData()maskKeys[0]:0x%02X;" + "maskKeys[1]:0x%02X; maskKeys[2]:0x%02X; maskKeys[3]:0x%02X\n" + , maskKeys[0], maskKeys[1], maskKeys[2], maskKeys[3])); + for (unsigned long i = position; i < position+length; i++) + { + recBuffer[i] = recBuffer[i] ^ maskKeys[(i-position)%4]; + } + } + DBG_MSG(("CWebSocketHandler::parseWebSocketData()length:%d; size:%d;" + " position:%d\n", (int)length, size, position)); + + for (unsigned long i = 0; (i < size); i++) { + Buffer[parsedBufferPosition + i] = recBuffer[i+position]; + } + b_size -= position; + parsedBufferPosition += length; + recBuffer += length; + size -= length+position; + } + return b_size; + } + + int CWebSocketHandler::prepareWebSocketDataHeader(unsigned char* Buffer, + unsigned long long b_size) + { + unsigned int headerLength = 2; + unsigned char payload; + + memset(Buffer, 0, headerLength); + Buffer[0] = 0x81; // 129 + + if (b_size <= 125) + { + payload = b_size; + Buffer[1] = b_size; // string length + } else if (b_size >= 126 && b_size <= 65535) + { + headerLength += 2; + payload = 126; + Buffer[1] = 0x7E; // 126 + } else + { + headerLength += 8; + payload = 127; + Buffer[1] = 0x7F; // 127 + } + + + if (payload == 126) + { + Buffer[2] = (b_size>>8); + Buffer[3] = b_size; + } else if (payload == 127) + { + Buffer[9] = (b_size & 0xFF); + Buffer[8] = ((b_size>>8) & 0xFF); + Buffer[7] = ((b_size>>16) & 0xFF); + Buffer[6] = ((b_size>>24) & 0xFF); + Buffer[5] = ((b_size>>32) & 0xFF); + Buffer[4] = ((b_size>>40) & 0xFF); + Buffer[3] = ((b_size>>48) & 0xFF); + Buffer[2] = ((b_size>>56) & 0xFF); + } + return headerLength; +} + + void CWebSocketHandler::handshake_0405(std::string &key) + { + static const char *websocket_magic_guid_04 = + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + char accept_buf[MAX_WEBSOCKET_04_KEY_LEN + 37]; + unsigned char hash[20] = {0xb3, 0x7a, 0x4f, 0x2c, 0xc0, 0x62, 0x4f, 0x16, 0x90, 0xf6, 0x46, 0x06, 0xcf, 0x38, 0x59, 0x45, 0xb2, 0xbe, 0xc4, 0xea}; + int accept_len; + + strncpy(accept_buf, key.c_str(), MAX_WEBSOCKET_04_KEY_LEN + 37); + strncpy(accept_buf + key.length(), websocket_magic_guid_04, + MAX_WEBSOCKET_04_KEY_LEN + 37 - strlen(key.c_str())); + + SHA1((unsigned char *)accept_buf, key.length() + strlen(websocket_magic_guid_04), hash); + + accept_len = lws_b64_encode_string((char *)hash, 20, accept_buf, sizeof accept_buf); + if (accept_len < 0) + { + fprintf(stderr, "Base64 encoded hash too long\n"); + } + fprintf(stderr, "accept_buf: %s\n", accept_buf); + key = accept_buf; + } + + void CWebSocketHandler::sha1_step(struct sha1_ctxt *ctxt) + { + unsigned int a, b, c, d, e; + size_t t, s; + unsigned int tmp; + + struct sha1_ctxt tctxt; + + memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2]; + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0]; + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6]; + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4]; + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10]; + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8]; + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14]; + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12]; + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18]; + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16]; + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22]; + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20]; + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26]; + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24]; + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30]; + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28]; + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34]; + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32]; + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38]; + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36]; + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42]; + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40]; + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46]; + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44]; + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50]; + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48]; + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54]; + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52]; + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58]; + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56]; + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62]; + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60]; + + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4); + + for (t = 0; t < 20; t++) + { + s = t & 0x0f; + if (t >= 16) + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ + W((s+2) & 0x0f) ^ W(s)); + + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); + e = d; d = c; c = S(30, b); b = a; a = tmp; + } + for (t = 20; t < 40; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ + W((s+2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); + e = d; d = c; c = S(30, b); b = a; a = tmp; + } + for (t = 40; t < 60; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ + W((s+2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); + e = d; d = c; c = S(30, b); b = a; a = tmp; + } + for (t = 60; t < 80; t++) + { + s = t & 0x0f; + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ + W((s+2) & 0x0f) ^ W(s)); + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); + e = d; d = c; c = S(30, b); b = a; a = tmp; + } + + H(0) = H(0) + a; + H(1) = H(1) + b; + H(2) = H(2) + c; + H(3) = H(3) + d; + H(4) = H(4) + e; + + memset(&ctxt->m.b8[0], 0, 64); + } + + void CWebSocketHandler::sha1_init(struct sha1_ctxt *ctxt) + { + memset(ctxt, 0, sizeof(struct sha1_ctxt)); + H(0) = 0x67452301; + H(1) = 0xefcdab89; + H(2) = 0x98badcfe; + H(3) = 0x10325476; + H(4) = 0xc3d2e1f0; + } + + void CWebSocketHandler::sha1_pad(struct sha1_ctxt *ctxt) + { + size_t padlen; /*pad length in bytes*/ + size_t padstart; + + PUTPAD(0x80); + + padstart = COUNT % 64; + padlen = 64 - padstart; + if (padlen < 8) + { + memset(&ctxt->m.b8[padstart], 0, padlen); + COUNT += padlen; + COUNT %= 64; + sha1_step(ctxt); + padstart = COUNT % 64; /* should be 0 */ + padlen = 64 - padstart; /* should be 64 */ + } + memset(&ctxt->m.b8[padstart], 0, padlen - 8); + COUNT += (padlen - 8); + COUNT %= 64; + + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]); + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]); + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]); + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]); + } + + void CWebSocketHandler::sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len) + { + size_t gaplen; + size_t gapstart; + size_t off; + size_t copysiz; + + off = 0; + + while (off < len) + { + gapstart = COUNT % 64; + gaplen = 64 - gapstart; + + copysiz = (gaplen < len - off) ? gaplen : len - off; + memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); + COUNT += copysiz; + COUNT %= 64; + ctxt->c.b64[0] += copysiz * 8; + if (COUNT % 64 == 0) + sha1_step(ctxt); + off += copysiz; + } + } + + void CWebSocketHandler::sha1_result(struct sha1_ctxt *ctxt, unsigned char* digest0) + { + unsigned char *digest; + + digest = (unsigned char *)digest0; + sha1_pad(ctxt); + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2]; + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0]; + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6]; + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4]; + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10]; + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8]; + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14]; + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12]; + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18]; + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16]; + } + + /* + * This should look and work like the libcrypto implementation + */ + + unsigned char * CWebSocketHandler::SHA1(const unsigned char *d, size_t n, unsigned char *md) + { + struct sha1_ctxt ctx; + + sha1_init(&ctx); + sha1_loop(&ctx, d, n); + sha1_result(&ctx, (unsigned char*)md); + + return md; + } + + int CWebSocketHandler::lws_b64_encode_string(const char *in, int in_len, char *out, int out_size) + { + unsigned char triple[3]; + int i; + int len; + int line = 0; + int done = 0; + + while (in_len) + { + len = 0; + for (i = 0; i < 3; i++) + { + if (in_len) + { + triple[i] = *in++; + len++; + in_len--; + } else + triple[i] = 0; + } + if (len) + { + + if (done + 4 >= out_size) + return -1; + + *out++ = encode[triple[0] >> 2]; + *out++ = encode[((triple[0] & 0x03) << 4) | + ((triple[1] & 0xf0) >> 4)]; + *out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) | + ((triple[2] & 0xc0) >> 6)] : '='); + *out++ = (len > 2 ? encode[triple[2] & 0x3f] : '='); + + done += 4; + line += 4; + } + if (line >= 72) + { + + if (done + 2 >= out_size) + return -1; + + *out++ = '\r'; + *out++ = '\n'; + done += 2; + line = 0; + } + } + + if (done + 1 >= out_size) + return -1; + + *out++ = '\0'; + + return done; + } + + /* + * returns length of decoded string in out, or -1 if out was too small + * according to out_size + */ + + int CWebSocketHandler::lws_b64_decode_string(const char *in, char *out, int out_size) + { + int len; + int i; + int done = 0; + unsigned char v; + unsigned char quad[4]; + + while (*in) + { + + len = 0; + for (i = 0; i < 4 && *in; i++) + { + + v = 0; + while (*in && !v) + { + + v = *in++; + v = (v < 43 || v > 122) ? 0 : decode[v - 43]; + if (v) + v = (v == '$') ? 0 : v - 61; + if (*in) + { + len++; + if (v) + quad[i] = v - 1; + } else + quad[i] = 0; + } + } + if (!len) + continue; + + if (out_size < (done + len - 1)) + /* out buffer is too small */ + return -1; + + if (len >= 2) + *out++ = quad[0] << 2 | quad[1] >> 4; + if (len >= 3) + *out++ = quad[1] << 4 | quad[2] >> 2; + if (len >= 4) + *out++ = ((quad[2] << 6) & 0xc0) | quad[3]; + + done += len - 1; + } + + if (done + 1 >= out_size) + return -1; + + *out++ = '\0'; + + return done; + } + + int CWebSocketHandler::lws_b64_selftest(void) + { + char buf[64]; + int n; + unsigned int test; + static const char *plaintext[] = {"sanity check base 64"}; + static const char *coded[] = {"c2FuaXR5IGNoZWNrIGJhc2UgNjQ="}; + + for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) + { + + buf[sizeof(buf) - 1] = '\0'; + n = lws_b64_encode_string(plaintext[test], + strlen(plaintext[test]), buf, sizeof buf); + if (n != (int)strlen(coded[test]) || strcmp(buf, coded[test])) + { + fprintf(stderr, "Failed lws_b64 encode selftest " + "%d result '%s' %d\n", test, buf, n); + return -1; + } + + buf[sizeof(buf) - 1] = '\0'; + n = lws_b64_decode_string(coded[test], buf, sizeof buf); + if (n != (int)strlen(plaintext[test]) || + strcmp(buf, plaintext[test])) + { + fprintf(stderr, "Failed lws_b64 decode selftest " + "%d result '%s' %d\n", test, buf, n); + return -1; + } + } + + return 0; + } + + rawBytes CWebSocketHandler::handshake_hybi00(const std::string &key1, const std::string &key2, const rawBytes &key3) + { + if (key3.size() < 8) + { + DBG_MSG_ERROR(("key3's size is %d, less than 8 bytes\n", key3.size())); + return rawBytes(); + } + + unsigned long number1 = extractNumber(key1); + unsigned long number2 = extractNumber(key2); + DBG_MSG(("number1 is %ld, number2 is %ld\n", number1, number2)); + + if ((number1 == 0) || (number2 == 0)) + { + return rawBytes(); + } + + // represent the numbers in big-endian format (network-byte order) + unsigned long bigEndianNumber1 = htonl(number1); + unsigned long bigEndianNumber2 = htonl(number2); + + // the temporary key consists of bytes of the first and second numbers + // and the key3 + rawBytes key(8); + memcpy(&key[0], &bigEndianNumber1, 4); + memcpy(&key[4], &bigEndianNumber2, 4); + key.insert(key.end(), key3.begin(), key3.begin() + 8); + + MD5 md5(std::string(key.begin(), key.end())); + char digest[16]; + md5.getdigest(digest); + rawBytes resultBytes(&digest[0], &digest[16]); + + return resultBytes; + } + + unsigned long CWebSocketHandler::extractNumber(const std::string &key) const + { + // leave digits only + // and count the number of spaces in the key + std::string keyDigits; + int spacesCountKey = 0; + for (unsigned int index = 0; index < key.length(); ++index) + { + char keyChar = key[index]; + if (keyChar == ' ') + { + ++spacesCountKey; + } + else if (isdigit(keyChar)) + { + keyDigits += keyChar; + } + } + + unsigned long result = 0; + + // convert string to number + long long numberKey; + if (std::stringstream(keyDigits) >> numberKey) + { + if (spacesCountKey != 0) + { + if (numberKey % spacesCountKey == 0) + { + // divide the number by the count + result = numberKey / spacesCountKey; + } + else + { + // key is not an integral multiple of spaces count + } + } + else + { + // the denominator is 0 + } + } + else + { + // couldn't convert + } + + return result; + } + +} /* namespace NsMessageBroker */ + diff --git a/src/3rd_party-static/message_broker/src/server/mb_server.cpp b/src/3rd_party-static/message_broker/src/server/mb_server.cpp new file mode 100644 index 0000000000..25ec7fc9f3 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/server/mb_server.cpp @@ -0,0 +1,46 @@ +/** + * \file mb_server.cpp + * \brief MessageBroker server. + * \author AKara + */ + +#include "mb_server.hpp" + +namespace NsMessageBroker { + +Server::Server(const std::string& address, uint16_t port) { + m_sock = -1; + m_address = address; + m_port = port; +} + +Server::~Server() { + if (m_sock != -1) { + Close(); + } +} + +int Server::GetSocket() const { + return m_sock; +} + +std::string Server::GetAddress() const { + return m_address; +} + +uint16_t Server::GetPort() const { + return m_port; +} + +bool Server::Bind() { + m_sock = networking::bind(m_protocol, m_address, m_port, NULL, NULL); + + return (m_sock != -1) ? true : false; +} + +void Server::Close() { + ::close(m_sock); + m_sock = -1; +} + +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/server/mb_tcpserver.cpp b/src/3rd_party-static/message_broker/src/server/mb_tcpserver.cpp new file mode 100644 index 0000000000..bdd7b2bfdf --- /dev/null +++ b/src/3rd_party-static/message_broker/src/server/mb_tcpserver.cpp @@ -0,0 +1,331 @@ +/** + * \file mb_tcpserver.cpp + * \brief MessageBroker TCP server. + * \author AKara + */ + +#include +#include +#include +#include +#include +#include + +#include "MBDebugHelper.h" + +#include "mb_tcpserver.hpp" +#include "CMessageBroker.hpp" + +namespace NsMessageBroker { + +TcpServer::TcpServer(const std::string& address, uint16_t port, NsMessageBroker::CMessageBroker* pMessageBroker) : + Server(address, port) { + m_protocol = networking::TCP; + mpMessageBroker = pMessageBroker; +} + +TcpServer::~TcpServer() { + if (m_sock != -1) { + Close(); + } +} + +ssize_t TcpServer::Send(int fd, const std::string& data) { + DBG_MSG(("Send to %d: %s\n", fd, data.c_str())); + std::string rep = data; + if (isWebSocket(fd)) { + unsigned char buf[10] = {'\0'}; + ssize_t headerlen = mWebSocketHandler.prepareWebSocketDataHeader( + (unsigned char*)buf, (unsigned long)rep.length()); + std::string header = std::string((char*)buf, headerlen); + rep = header + rep; + } + int bytesToSend = rep.length(); + const char* ptrBuffer = rep.c_str(); + do { + int retVal = send(fd, ptrBuffer, bytesToSend, MSG_NOSIGNAL); + if (retVal == -1) { + if (EPIPE == errno) { + m_purge.push_back(fd); + } + return -1; + } + bytesToSend -= retVal; + ptrBuffer += retVal; + } while (bytesToSend > 0); + return rep.length(); +} + +bool TcpServer::Recv(int fd) { + DBG_MSG(("TcpServer::Recv(%d)\n", fd)); + + std::string* pReceivingBuffer = getBufferFor(fd); + bool buffer_was_not_empty = pReceivingBuffer->size() > 0; + + std::vector buf; + buf.reserve(RECV_BUFFER_LENGTH + pReceivingBuffer->size()); + DBG_MSG(("Left in pReceivingBuffer: %d \n", + pReceivingBuffer->size())); + buf.assign(pReceivingBuffer->c_str(), + pReceivingBuffer->c_str() + pReceivingBuffer->size()); + buf.resize(RECV_BUFFER_LENGTH + pReceivingBuffer->size()); + + int received_bytes = recv(fd, &buf[pReceivingBuffer->size()], MAX_RECV_DATA, 0); + if (received_bytes <= 0) { + DBG_MSG(("Received %d bytes from %d; error = %d\n", + received_bytes, fd, errno)); + m_purge.push_back(fd); + return false; + } + + unsigned int nb = received_bytes; + std::vector last_msg_buf(buf.begin()+pReceivingBuffer->size(), + buf.begin()+pReceivingBuffer->size()+nb); + DBG_MSG(("Recieved %d from %d\n", nb, fd)); + nb += static_cast(pReceivingBuffer->size()); + DBG_MSG(("Recieved with buffer %d from %d\n", nb, fd)); + + if (nb > 0) { // This is redundant + if (isWebSocket(fd)) { + const unsigned int data_length = + mWebSocketHandler.parseWebSocketDataLength(&buf[0], nb); + + DBG_MSG(("Received %d actual data length %d\n", nb, data_length)); + + if (data_length > nb) { + DBG_MSG_ERROR(("Received %d actual data length %d\n", nb, data_length)); + DBG_MSG_ERROR(("Incomplete message")); + *pReceivingBuffer = std::string(&buf[0], nb); + return false; + } + mWebSocketHandler.parseWebSocketData(&buf[0], nb); + } + + *pReceivingBuffer = std::string(&buf[0], nb); + DBG_MSG(("pReceivingBuffer before onMessageReceived:%d : %s\n", + pReceivingBuffer->size(), pReceivingBuffer->c_str())); + + // we need to check for websocket handshake + if (!checkWebSocketHandShake(fd, pReceivingBuffer)) + { //JSON MESSAGE received. Send data in CMessageBroker. + if (mpMessageBroker) { + size_t buffer_size_before = pReceivingBuffer->size(); + mpMessageBroker->onMessageReceived(fd, *pReceivingBuffer, true); + + if (buffer_was_not_empty && (pReceivingBuffer->size() == buffer_size_before)) { + /* We couldn't parse the buffer (with the last message at the end) + * Try to parse ONLY the last message */ + DBG_MSG_ERROR(("Couldn't parse the whole buffer! Try only the last message.\n")); + + nb = static_cast(last_msg_buf.size()); + if (isWebSocket(fd)) { + const unsigned int data_length = + mWebSocketHandler.parseWebSocketDataLength(&last_msg_buf[0], nb); + if (data_length > nb) { + DBG_MSG_ERROR(("The last message may be incomplete. Don't do anything.\n")); + /* Should we replace the buffer with the last message? + * Probably not. It may not be a real websocket message. + * Wait for a full message. */ + return false; + } + mWebSocketHandler.parseWebSocketData(&last_msg_buf[0], nb); + } + + std::string last_message = std::string(&last_msg_buf[0], nb); + buffer_size_before = last_message.size(); + mpMessageBroker->onMessageReceived(fd, last_message, false); + if ( last_message.size() < buffer_size_before ) { + /* Parsing last message successful! Discard the old data and + * keep only what is left from the last message */ + DBG_MSG_ERROR(("Parsing last message successful! Discard the old data.\n")); + *pReceivingBuffer = last_message; + } + } + } else { + return false; + } + } else { // message is a websocket handshake + ssize_t webSocketKeyPos = pReceivingBuffer->find("Sec-WebSocket-Key: "); + if (-1 != webSocketKeyPos) { + std::string handshakeResponse = + "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\n" + "Connection: Upgrade\r\nSec-WebSocket-Accept: "; + std::string wsKey = pReceivingBuffer->substr(webSocketKeyPos + 19, 24); + mWebSocketHandler.handshake_0405(wsKey); + handshakeResponse += wsKey; + handshakeResponse += "\r\n\r\n"; + pReceivingBuffer->clear(); + std::list::iterator acceptedClientIt = + find(m_AcceptedClients.begin(), m_AcceptedClients.end(), fd); + if (m_AcceptedClients.end() != acceptedClientIt) { + m_AcceptedClients.erase(acceptedClientIt); + } + Send(fd, handshakeResponse); + m_WebSocketClients.push_back(fd); + } + } + } + return true; +} + +bool TcpServer::checkWebSocketHandShake(int fd, std::string* pReceivingBuffer) { + bool result = false; + std::list::iterator acceptedClientIt = find(m_AcceptedClients.begin(), m_AcceptedClients.end(), fd); + if (m_AcceptedClients.end() != acceptedClientIt) { + ssize_t httpheader = pReceivingBuffer->find("GET / HTTP/1.1"); + if (-1 != httpheader) { // here is a header + DBG_MSG(("HTTP header detected!\n")); + result = true; + } else { // not winsocket client + m_AcceptedClients.erase(acceptedClientIt); + } + } + DBG_MSG(("TcpServer::checkWebSocket(): %d!\n", result)); + return result; +} + +bool TcpServer::isWebSocket(int fd) { + bool result = false; + std::list::iterator wsClientIt = find(m_WebSocketClients.begin(), m_WebSocketClients.end(), fd); + if (m_WebSocketClients.end() != wsClientIt) { + result = true; + } + return result; +} + +std::string* TcpServer::getBufferFor(int fd) { + std::string* res = 0; + std::map ::iterator it; + it = m_receivingBuffers.find(fd); + if (it != m_receivingBuffers.end()) { + res = (*it).second; + } else { // create a new buffer... + res = new std::string(""); + printf("getBufferFor method!\n"); + m_receivingBuffers.insert(std::map::value_type(fd, res)); + } + + return res; +} + +void TcpServer::WaitMessage(uint32_t ms) { + fd_set fdsr; + struct timeval tv; + int max_sock = m_sock; + + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) / 1000; + + FD_ZERO(&fdsr); + +#ifdef _WIN32 + /* on Windows, a socket is not an int but a SOCKET (unsigned int) */ + FD_SET((SOCKET)m_sock, &fdsr); +#else + FD_SET(m_sock, &fdsr); +#endif + + for (std::map::iterator it = m_receivingBuffers.begin(); + it != m_receivingBuffers.end() ; it++) { +#ifdef _WIN32 + FD_SET((SOCKET)((*it).first), &fdsr); +#else + FD_SET(((*it).first), &fdsr); +#endif + + if (((*it).first) > max_sock) { + max_sock = ((*it).first); + } + } + + max_sock++; + + if (select(max_sock, &fdsr, NULL, NULL, ms ? &tv : NULL) > 0) { + if (FD_ISSET(m_sock, &fdsr)) { + Accept(); + } + + for (std::map::iterator it = m_receivingBuffers.begin(); + it != m_receivingBuffers.end() ; it++) { + if (FD_ISSET(((*it).first), &fdsr)) { + Recv((*it).first); + } + } + + /* remove disconnect socket descriptor */ + for (std::list::iterator it = m_purge.begin(); + it != m_purge.end() ; it++) { + std::map ::iterator itr; + itr = m_receivingBuffers.find((*it)); + if (itr != m_receivingBuffers.end()) + { // delete receiving buffer of disconnected client + mpMessageBroker->OnSocketClosed(itr->first); + delete itr->second; + m_receivingBuffers.erase(itr); + } + } + + /* purge disconnected list */ + m_purge.erase(m_purge.begin(), m_purge.end()); + } + else { + /* error */ + } +} + +bool TcpServer::Listen() const { + if (m_sock == -1) { + return false; + } + + if (listen(m_sock, 5) == -1) { + return false; + } + + return true; +} + +bool TcpServer::Accept() { + + int client = -1; + socklen_t addrlen = sizeof(struct sockaddr_storage); + + if (m_sock == -1) { + return false; + } + + client = accept(m_sock, 0, &addrlen); + + if (client == -1) { + return false; + } + + std::string* res = new std::string(""); + m_receivingBuffers.insert(std::map::value_type(client, res)); + m_AcceptedClients.push_back(client); + return true; +} + +void TcpServer::Close() { + /* close all client sockets */ + for (std::map::iterator it = m_receivingBuffers.begin(); + it != m_receivingBuffers.end() ; it++) { + ::close((*it).first); + if ((*it).second) { + delete(*it).second; + } + } + m_receivingBuffers.clear(); + Server::Close(); + /* listen socket should be closed in Server destructor */ +} + +void* TcpServer::MethodForThread(void* arg) { + arg = arg; + while (1) { + WaitMessage(1000); + } + return NULL; +} + +} /* namespace NsMessageBroker */ diff --git a/src/3rd_party-static/message_broker/src/server/networking.cpp b/src/3rd_party-static/message_broker/src/server/networking.cpp new file mode 100644 index 0000000000..f054431690 --- /dev/null +++ b/src/3rd_party-static/message_broker/src/server/networking.cpp @@ -0,0 +1,189 @@ +/* + * JsonRpc-Cpp - JSON-RPC implementation. + * Copyright (C) 2008-2011 Sebastien Vincent + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +/** + * \file networking.cpp + * \brief Networking utils. + * \author Sebastien Vincent + */ + +#include +#include + +#include "networking.h" + +namespace networking { +#ifdef _WIN32 +/** + * \var wsaData + * \brief MS Windows object to start + * networking stuff. + */ +static WSAData wsaData; +#endif + +bool init() { + bool ret = false; + +#ifdef _WIN32 + ret = (WSAStartup(MAKEWORD(2, 0), &wsaData) == 0); +#else + /* unix-like */ + ret = true; +#endif + + return ret; +} + +void cleanup() { +#ifdef _WIN32 + WSACleanup(); +#endif +} + +int connect(enum TransportProtocol protocol, + const std::string& address, + uint16_t port, struct sockaddr_storage* sockaddr, + socklen_t* addrlen) { + struct addrinfo hints; + struct addrinfo* res = NULL; + struct addrinfo* p = NULL; + char service[8]; + int sock = -1; + + if (!port || address == "") { + return -1; + } + + snprintf(service, sizeof(service), "%u", port); + service[sizeof(service) - 1] = 0x00; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = protocol == UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = protocol; + hints.ai_flags = 0; + + if (getaddrinfo(address.c_str(), + service, &hints, &res) != 0) { + return -1; + } + + for (p = res ; p ; p = p->ai_next) { + sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + + if (sock == -1) { + continue; + } + + if (protocol == TCP && ::connect(sock, (struct sockaddr*)p->ai_addr, p->ai_addrlen) == -1) { + ::close(sock); + sock = -1; + continue; + } + + if (sockaddr) { + memcpy(sockaddr, p->ai_addr, p->ai_addrlen); + } + + if (addrlen) { + *addrlen = p->ai_addrlen; + } + + /* ok so now we have a socket bound, break the loop */ + break; + } + + freeaddrinfo(res); + p = NULL; + + return sock; +} + +int bind(enum TransportProtocol protocol, + const std::string& address, uint16_t port, + struct sockaddr_storage* sockaddr, socklen_t* addrlen) { + struct addrinfo hints; + struct addrinfo* res = NULL; + struct addrinfo* p = NULL; + char service[8]; + int sock = -1; + + if (!port || address == "") { + return -1; + } + + snprintf(service, sizeof(service), "%u", port); + service[sizeof(service) - 1] = 0x00; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = protocol == UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = protocol; + hints.ai_flags = AI_PASSIVE; + + if (getaddrinfo(address.c_str(), service, &hints, &res) != 0) { + return -1; + } + + for (p = res ; p ; p = p->ai_next) { + int on = 1; + on = on; + + sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + + if (sock == -1) { + continue; + } + +#ifndef _WIN32 + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)); + + /* accept IPv6 OR IPv4 on the same socket */ + on = 1; + setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)); +#else + on = 0; +#endif + + if (::bind(sock, p->ai_addr, p->ai_addrlen) == -1) { + ::close(sock); + sock = -1; + continue; + } + + if (sockaddr) { + memcpy(sockaddr, p->ai_addr, p->ai_addrlen); + } + + if (addrlen) { + *addrlen = p->ai_addrlen; + } + + /* ok so now we have a socket bound, break the loop */ + break; + } + + freeaddrinfo(res); + p = NULL; + + return sock; +} + +} /* namespace networking */ + diff --git a/src/3rd_party-static/test/CMakeLists.txt b/src/3rd_party-static/test/CMakeLists.txt index 33bcd82694..a38a392a01 100644 --- a/src/3rd_party-static/test/CMakeLists.txt +++ b/src/3rd_party-static/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,21 +28,16 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) -include_directories ( +include_directories( ${GMOCK_INCLUDE_DIRECTORY} ${JSONCPP_INCLUDE_DIRECTORY} ) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") + set(LIBRARIES gmock jsoncpp ) -set (SOURCES - json_reader_test.cc -) - -add_library("test_JSONCPPTest" ${SOURCES}) -create_test("test_JSONCPP" "${SOURCES}" "${LIBRARIES}") -endif() \ No newline at end of file +create_test(jsoncpp_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/3rd_party/CMakeLists.txt b/src/3rd_party/CMakeLists.txt index c7965992f4..0886186624 100644 --- a/src/3rd_party/CMakeLists.txt +++ b/src/3rd_party/CMakeLists.txt @@ -28,7 +28,10 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -INCLUDE("./set_3rd_party_paths.cmake") +include("./set_3rd_party_paths.cmake") + +set(3RD_PARTY_SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) +set(3RD_PARTY_BINARY_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) if(ENABLE_LOG OR HMI_DBUS_API) # --- libexpat @@ -37,14 +40,110 @@ if(ENABLE_LOG OR HMI_DBUS_API) endif() if(ENABLE_LOG) + if(NO_REBUILD_3RD_PARTY_LOGGER) + message(STATUS "Not rebuilding logger.") + else() + if(FORCE_3RD_PARTY_LOGGER) + message(STATUS "Force to rebuild logger.") + + #build logger + add_custom_target(3rd_party_logger + make + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + + #install logger + #install either to default place with sudo or non-default plase without sudo. + #to install with sudo to non-default place use manual installation + add_custom_target(install-3rd_party_logger + COMMAND /bin/bash -c \"USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; + if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then + sudo -k \; + sudo make install\; + else + make install\; + fi\" + DEPENDS 3rd_party_logger + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + else() + #build logger + add_custom_target(3rd_party_logger + COMMAND /bin/bash -c \"cd ${CMAKE_CURRENT_SOURCE_DIR} && + grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]\; then + VAR1=\\$$\( readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 2>/dev/null\)\; + VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; + VAR2=-1\; + cd ${CMAKE_CURRENT_SOURCE_DIR}\; + git log . 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]; then + VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/apache-log4cxx-0.10.0\)\; + fi\; + if [ \\$$VAR1 != \\$$VAR2 ]\; then + echo " Need to rebuild logger. " \; + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make\; + else + echo " Logger is actual. " \; + fi\; + else + echo " Need to build logger. " \; + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make\; + fi\" + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + + #install logger + #install either to default place with sudo or non-default plase without sudo. + #to install with sudo to non-default place use manual installation + add_custom_target(install-3rd_party_logger + COMMAND /bin/bash -c \"cd ${CMAKE_CURRENT_SOURCE_DIR} && + grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]\; then + VAR1=\\$$\( readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/liblog4cxx.so 2>/dev/null\)\; + VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; + VAR2=-1\; + cd ${CMAKE_CURRENT_SOURCE_DIR}\; + git log . 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]; then + VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/apache-log4cxx-0.10.0\)\; + fi\; + if [ \\$$VAR1 != \\$$VAR2 ]\; then + USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; + if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + sudo -k \; + sudo make install\; + else + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make install\; + fi\; + fi\; + else + USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; + if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + sudo -k \; + sudo make install\; + else + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make install\; + fi\; + fi\" + DEPENDS 3rd_party_logger + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + endif() + endif() + set(APR_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib PARENT_SCOPE) set(APR_INCLUDE_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/include PARENT_SCOPE) set(APR_UTIL_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib PARENT_SCOPE) set(LOG4CXX_INCLUDE_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX}/include PARENT_SCOPE) set(LOG4CXX_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib PARENT_SCOPE) -endif() -if(ENABLE_LOG) # --- libapr-1 add_subdirectory(apr-cmake) @@ -57,14 +156,108 @@ endif() # --- D-Bus if(HMI_DBUS_API) + if(NO_REBUILD_3RD_PARTY_DBUS) + message(STATUS "Not rebuilding D-Bus.") + else() + if(FORCE_3RD_PARTY_DBUS) + message(STATUS "Force to rebuild D-Bus.") + + #build d-bus + add_custom_target(3rd_party_dbus + make + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + + #install d-bus + #install either to default place with sudo or non-default plase without sudo. + #to install with sudo to non-default place use manual installation + add_custom_target(install-3rd_party_dbus + COMMAND /bin/bash -c \"USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; + if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then + sudo -k \; + sudo make install\; + else + make install\; + fi\" + DEPENDS 3rd_party_dbus + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + else() + #build d-bus + add_custom_target(3rd_party_dbus + COMMAND /bin/bash -c \"grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]\; then + VAR1=\\$$\(readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 2>/dev/null\)\; + VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; + VAR2=-1\; + cd ${CMAKE_CURRENT_SOURCE_DIR}\; + git log . 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]; then + VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/dbus-1.7.8\)\; + fi\; + if [ \\$$VAR1 != \\$$VAR2 ]\; then + echo " Need to rebuild D-Bus. " \; + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make\; + else + echo " D-Bus is actual. " \; + fi\; + else + echo " Need to build D-Bus. " \; + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make\; + fi\" + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + + #install d-bus + #install either to default place with sudo or non-default plase without sudo. + #to install with sudo to non-default place use manual installation + add_custom_target(install-3rd_party_dbus + COMMAND /bin/bash -c \"grep .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]\; then + VAR1=\\$$\(readelf -p .commit_hash ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib/libdbus-1.so 2>/dev/null\)\; + VAR1=\\$$\(echo \\$$VAR1 | awk '{print \\$$NF}'\)\; + VAR2=-1\; + cd ${CMAKE_CURRENT_SOURCE_DIR}\; + git log . 1>/dev/null 2>&1\; + if [ \\$$? == 0 ]; then + VAR2=\\$$\(git log --pretty=\"format:%H\" -1 ${3RD_PARTY_SOURCE_DIRECTORY}/dbus-1.7.8\)\; + fi\; + if [ \\$$VAR1 != \\$$VAR2 ]\; then + USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; + if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + sudo -k \; + sudo make install\; + else + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make install\; + fi\; + fi\; + else + USE_DEFAULT_3RD_PARTY_PATH=${USE_DEFAULT_3RD_PARTY_PATH}\; + if [ \\$$USE_DEFAULT_3RD_PARTY_PATH == "true" ]\; then + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + sudo -k \; + sudo make install\; + else + cd ${3RD_PARTY_BINARY_DIRECTORY}\; + make install\; + fi\; + fi\" + DEPENDS 3rd_party_dbus + WORKING_DIRECTORY ${3RD_PARTY_BINARY_DIRECTORY} + ) + endif() + endif() + + # --- D-Bus set(DBUS_INCLUDE_DIR ${3RD_PARTY_INSTALL_PREFIX}/include) set(DBUS_INCLUDE_DIR_ARCH ${3RD_PARTY_INSTALL_PREFIX_ARCH}/include) set(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIR} ${DBUS_INCLUDE_DIR_ARCH}) set(DBUS_INCLUDE_DIRS ${DBUS_INCLUDE_DIRS} PARENT_SCOPE) set(DBUS_LIBS_DIRECTORY ${3RD_PARTY_INSTALL_PREFIX_ARCH}/lib PARENT_SCOPE) -endif() -if(HMI_DBUS_API) add_subdirectory(dbus-cmake) endif() - diff --git a/src/3rd_party/apache-log4cxx-cmake/CMakeLists.txt b/src/3rd_party/apache-log4cxx-cmake/CMakeLists.txt index a3dd48d1f7..57291f88a4 100644 --- a/src/3rd_party/apache-log4cxx-cmake/CMakeLists.txt +++ b/src/3rd_party/apache-log4cxx-cmake/CMakeLists.txt @@ -74,7 +74,7 @@ add_custom_target(liblog4cxx ALL make cd ${CMAKE_CURRENT_SOURCE_DIR} && git log --pretty=\\"format:%H\\" -1 ${LOG4CXX_SOURCE_DIRECTORY} > /tmp/commit_hash 2>/dev/null && echo \\"Adding .commit_hash section\\" && - ${objcopy} --add-section .commit_hash=/tmp/commit_hash ${LOG4CXX_LIBS_DIRECTORY}/liblog4cxx.so ${LOG4CXX_LIBS_DIRECTORY}/liblog4cxx.so 1>/dev/null 2>&1\; + objcopy --add-section .commit_hash=/tmp/commit_hash ${LOG4CXX_LIBS_DIRECTORY}/liblog4cxx.so ${LOG4CXX_LIBS_DIRECTORY}/liblog4cxx.so 1>/dev/null 2>&1\; fi; fi\" DEPENDS ${LOG4CXX_BUILD_DIRECTORY}/Makefile diff --git a/src/3rd_party/iap.armv7-qnx.runtime.tar.bz2 b/src/3rd_party/iap.armv7-qnx.runtime.tar.bz2 deleted file mode 100644 index 3d6028c6ec..0000000000 Binary files a/src/3rd_party/iap.armv7-qnx.runtime.tar.bz2 and /dev/null differ diff --git a/src/3rd_party/iap.build.tar.bz2 b/src/3rd_party/iap.build.tar.bz2 deleted file mode 100644 index 19aa8b7ae5..0000000000 Binary files a/src/3rd_party/iap.build.tar.bz2 and /dev/null differ diff --git a/src/appMain/CMakeLists.txt b/src/appMain/CMakeLists.txt index 84b2c847bd..a0f053fbd2 100644 --- a/src/appMain/CMakeLists.txt +++ b/src/appMain/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,12 +28,43 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -IF (HMIADAPTER STREQUAL "messagebroker") -set (BROKER_LIBRARIES - MessageBrokerClient - MessageBrokerServer +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + +find_package(SDLOpenSSL REQUIRED) + +include_directories( + ${COMPONENTS_DIR}/protocol_handler/include + ${COMPONENTS_DIR}/application_manager/include + ${COMPONENTS_DIR}/formatters/include + ${COMPONENTS_DIR}/transport_manager/include + ${COMPONENTS_DIR}/security_manager/include + ${COMPONENTS_DIR}/security_manager/include + ${COMPONENTS_DIR}/config_profile/include + ${COMPONENTS_DIR}/utils/include + ${COMPONENTS_DIR}/connection_handler/include + ${COMPONENTS_DIR}/hmi_message_handler/include + ${COMPONENTS_DIR}/request_watchdog/include + ${COMPONENTS_DIR}/smart_objects/include + ${COMPONENTS_DIR}/media_manager/include + ${COMPONENTS_DIR}/telemetry_monitor/include + ${COMPONENTS_DIR}/policy/include + ${COMPONENTS_DIR}/resumption/include + ${COMPONENTS_DIR}/dbus/include + ${CMAKE_BINARY_DIR}/src/components + ${JSONCPP_INCLUDE_DIRECTORY} + ${LOG4CXX_INCLUDE_DIRECTORY} + ${OPENSSL_INCLUDE_DIRECTORY} + ${MESSAGE_BROKER_INCLUDE_DIRECTORY} ) -ENDIF () + +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") + +if (HMIADAPTER STREQUAL "messagebroker") + set (BROKER_LIBRARIES + message_broker_client + message_broker_server + ) +endif() cmake_policy(PUSH) # make link_directories() treat paths relative to the source dir @@ -43,18 +74,18 @@ link_directories(${LIBUSB_LIBS_DIRECTORY}) cmake_policy(POP) if (EXTENDED_MEDIA_MODE) -set(default_media_inc -${GSTREAMER_gst_INCLUDE_DIR} -${GSTREAMER_gstconfig_INCLUDE_DIR} -) + set(default_media_inc + ${GSTREAMER_gst_INCLUDE_DIR} + ${GSTREAMER_gstconfig_INCLUDE_DIR} + ) else(EXTENDED_MEDIA_MODE) -set(default_media_inc -) + set(default_media_inc) endif() if (TELEMETRY_MONITOR) - set(TELEMETRY_MONITOR_LIB - TelemetryMonitor) + set(TELEMETRY_MONITOR_LIB + TelemetryMonitor + ) endif() set(LIBRARIES @@ -73,7 +104,7 @@ set(LIBRARIES TransportManager ${SecurityManagerLibrary} HMIMessageHandler - MessageBroker + message_broker ${BROKER_LIBRARIES} Utils jsoncpp @@ -87,12 +118,15 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") endif() if (BUILD_BT_SUPPORT) - list(APPEND LIBRARIES bluetooth) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND LIBRARIES bluetooth) + endif() endif() + if (BUILD_USB_SUPPORT) -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - list(APPEND LIBRARIES Libusb-1.0.16) -endif() + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND LIBRARIES Libusb-1.0.16) + endif() endif() if(ENABLE_LOG) @@ -102,44 +136,6 @@ if(ENABLE_LOG) list(APPEND LIBRARIES expat -L${EXPAT_LIBS_DIRECTORY}) endif() -include_directories ( - ./ - ${COMPONENTS_DIR}/protocol_handler/include/ - ${JSONCPP_INCLUDE_DIRECTORY} - ${COMPONENTS_DIR}/application_manager/include - ${COMPONENTS_DIR}/formatters/include - ${COMPONENTS_DIR}/transport_manager/include - ${COMPONENTS_DIR}/security_manager/include - ${SecurityManagerIncludeDir} - ${COMPONENTS_DIR}/security_manager/include - ${COMPONENTS_DIR}/config_profile/include - ${COMPONENTS_DIR}/utils/include/ - ${COMPONENTS_DIR}/connection_handler/include/ - ${COMPONENTS_DIR}/hmi_message_handler/include - ${COMPONENTS_DIR}/request_watchdog/include - ${COMPONENTS_DIR}/smart_objects/include/ - ${COMPONENTS_DIR}/media_manager/include/ - ${COMPONENTS_DIR}/telemetry_monitor/include - ${COMPONENTS_DIR}/policy/include/ - ${COMPONENTS_DIR}/resumption/include/ - ${MESSAGE_BROKER_INCLUDE_DIRECTORY} - ${ENCRYPTION_INCLUDE_DIRECTORY} - ${COMPONENTS_DIR} - ${CMAKE_BINARY_DIR}/src/components/ - ${COMPONENTS_DIR}/dbus/include/ - ${CMAKE_SOURCE_DIR} - ${default_media_inc} - ${LOG4CXX_INCLUDE_DIRECTORY} - ${CMAKE_SOURCE_DIR}/src/3rd_party/dbus-1.7.8 - ${CMAKE_SOURCE_DIR}/src/3rd_party/dbus-1.7.8/dbus/ -) - -set (SOURCES - main.cc - life_cycle.cc - signal_handlers.cc -) - if( NOT CMAKE_BUILD_TYPE ) set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build. Options are: None, Debug, Release, RelWithDebInfo, MinSizeRel." FORCE) endif() @@ -147,7 +143,6 @@ endif() add_executable(${PROJECT} ${SOURCES}) target_link_libraries(${PROJECT} ${LIBRARIES}) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/log4cxx.properties DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/audio.8bit.wav DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test.txt DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/components/CMakeLists.txt b/src/components/CMakeLists.txt index d31141b36c..28c8e68b54 100644 --- a/src/components/CMakeLists.txt +++ b/src/components/CMakeLists.txt @@ -29,68 +29,64 @@ # POSSIBILITY OF SUCH DAMAGE. set(COMPONENTS_DIR ${CMAKE_SOURCE_DIR}/src/components) +set(COMPONENTS_DIR ${COMPONENTS_DIR} PARENT_SCOPE) -# --- HMI_API interfaces +# --- HMI, MOBILE Interfaces add_subdirectory(./interfaces) -# --- ProtocolHandler +# --- Protocol Handler add_subdirectory(./protocol) -# --- TransportManager +# --- Transport Manager add_subdirectory(./transport_manager) -# --- Policies +# --- Resumption add_subdirectory(./resumption) -# --- formatters +# --- Formatters add_subdirectory(./formatters) -# --- ProtocolHandler +# --- Protocol Handler add_subdirectory(./protocol_handler) -# --- ConnectionHandler +# --- Connection Handler add_subdirectory(./connection_handler) # --- Utils add_subdirectory(./utils) -# --- Security manager +# --- Security Manager if(ENABLE_SECURITY) add_subdirectory(./security_manager) endif() -# -# --- Policy_impl + +# --- Policy add_subdirectory(./policy) -# --- Validated types +# --- Validated Types add_subdirectory(./rpc_base) -# --- SmartObjects +# --- Smart Objects add_subdirectory(./smart_objects) -# --- Application manager +# --- Application Manager add_subdirectory(./application_manager) # --- HMI Message Handler add_subdirectory(./hmi_message_handler) -# --- Config +# --- Config Profile add_subdirectory(./config_profile) -# --- AudioManager +# --- Media Manager add_subdirectory(./media_manager) -if (TELEMETRY_MONITOR) - add_subdirectory(./telemetry_monitor) +# --- Telemetry Monitor +if(TELEMETRY_MONITOR) + add_subdirectory(./telemetry_monitor) endif() - -if (${HMI_DBUS_API}) # --- DBus - add_subdirectory(./dbus) -endif () -if (${QT_HMI}) -# --- Qt HMI - add_subdirectory(./qt_hmi) -endif () - +if(HMI_DBUS_API) + add_subdirectory(./dbus) +endif() diff --git a/src/components/HMI/IVSU/PROPRIETARY_REQUEST~ b/src/components/HMI/IVSU/PROPRIETARY_REQUEST~ deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/components/application_manager/CMakeLists.txt b/src/components/application_manager/CMakeLists.txt index 32848b1c6d..591b2063b9 100644 --- a/src/components/application_manager/CMakeLists.txt +++ b/src/components/application_manager/CMakeLists.txt @@ -28,6 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) set (AM_SOURCE_DIR ${COMPONENTS_DIR}/application_manager) set (AM_TEST_DIR ${AM_SOURCE_DIR}/test) @@ -41,16 +43,14 @@ include_directories ( ${COMPONENTS_DIR}/protocol_handler/include/ ${COMPONENTS_DIR}/smart_objects/include/ ${COMPONENTS_DIR}/hmi_message_handler/include - ${COMPONENTS_DIR}/media_manager/include/ - ${COMPONENTS_DIR}/connection_handler/include/ - ${COMPONENTS_DIR}/config_profile/include/ - ${COMPONENTS_DIR}/request_watchdog/include/ - ${COMPONENTS_DIR}/resumption/include/ - ${COMPONENTS_DIR}/app_launch/include/ - ${COMPONENTS_DIR}/rpc_base/include/ - ${COMPONENTS_DIR}/interfaces - ${CMAKE_BINARY_DIR}/src/components/ - ${COMPONENTS_DIR}/policy/include/ + ${COMPONENTS_DIR}/media_manager/include + ${COMPONENTS_DIR}/connection_handler/include + ${COMPONENTS_DIR}/config_profile/include + ${COMPONENTS_DIR}/request_watchdog/include + ${COMPONENTS_DIR}/resumption/include + ${COMPONENTS_DIR}/rpc_base/include + ${COMPONENTS_DIR}/policy/include + ${CMAKE_BINARY_DIR}/src/components ${JSONCPP_INCLUDE_DIRECTORY} ${ENCRYPTION_INCLUDE_DIRECTORY} ${MESSAGE_BROKER_INCLUDE_DIRECTORY} @@ -69,48 +69,60 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") ) endif() -file (GLOB SOURCES - ${AM_SOURCE_DIR}/src/* +set (MESSAGE_HELPER_SOURCE_DIR + ${AM_SOURCE_DIR}/src/message_helper ) -set (MESSAGE_HELPER_SOURCES - ${AM_SOURCE_DIR}/src/message_helper/message_helper.cc +set (MESSAGE_HELPER_PATHS + ${MESSAGE_HELPER_SOURCE_DIR} ) +collect_sources(MESSAGE_HELPER_SOURCES "${MESSAGE_HELPER_PATHS}") -set (POLICIES_MANAGER -${AM_SOURCE_DIR}/src/policies/policy_handler.cc -${AM_SOURCE_DIR}/src/usage_statistics.cc -${AM_SOURCE_DIR}/src/policies/policy_event_observer.cc -${AM_SOURCE_DIR}/src/policies/delegates/app_permission_delegate.cc -${AM_SOURCE_DIR}/src/policies/delegates/statistics_delegate.cc + +set (POLICIES_SOURCE_DIR + ${AM_SOURCE_DIR}/src/policies ) - include_directories( - ${COMPONENTS_DIR}/policy/src/policy/policy_table/table_struct - ) -file (GLOB EVENT_ENGINE - ${AM_SOURCE_DIR}/src/event_engine/* +set (POLICIES_MANAGER_SOURCES + ${POLICIES_SOURCE_DIR}/policy_handler.cc + ${POLICIES_SOURCE_DIR}/policy_event_observer.cc + ${POLICIES_SOURCE_DIR}/delegates/app_permission_delegate.cc + ${POLICIES_SOURCE_DIR}/delegates/statistics_delegate.cc + ${CMAKE_CURRENT_SOURCE_DIR}/src/usage_statistics.cc ) -file (GLOB RESUMPTION - ${AM_SOURCE_DIR}/src/resumption/* +include_directories( + ${COMPONENTS_DIR}/policy/src/policy/policy_table/table_struct ) -file (GLOB APP_LAUNCH - ${AM_SOURCE_DIR}/src/app_launch/* +set (EVENT_ENGINE_SOURCE_DIR + ${AM_SOURCE_DIR}/src/event_engine ) +set (EVENT_ENGINE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/application_manager/event_engine + ${EVENT_ENGINE_SOURCE_DIR} +) +collect_sources(EVENT_ENGINE_SOURCES "${EVENT_ENGINE_PATHS}") + set (COMMANDS_SOURCE_DIR ${AM_SOURCE_DIR}/src/commands ) +collect_sources(POLICIES_SOURCES "${POLICIES_PATHS}") -file (GLOB MOBILE_COMMANDS_SOURCES - ${COMMANDS_SOURCE_DIR}/* - ${COMMANDS_SOURCE_DIR}/mobile/* +set(MOBILE_COMMANDS_EXCLUDE_PATHS + ${COMMANDS_SOURCE_DIR}/hmi ) +set (MOBILE_COMMANDS_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/application_manager/commands + ${CMAKE_CURRENT_SOURCE_DIR}/include/application_manager/commands/mobile + ${COMMANDS_SOURCE_DIR} + ${COMMANDS_SOURCE_DIR}/mobile +) +collect_sources(MOBILE_COMMANDS_SOURCES "${MOBILE_COMMANDS_PATHS}" "${MOBILE_COMMANDS_EXCLUDE_PATHS}") - set (HMI_COMMANDS_SOURCES +set (HMI_COMMANDS_SOURCES ${COMMANDS_SOURCE_DIR}/hmi/request_to_hmi.cc ${COMMANDS_SOURCE_DIR}/hmi/response_from_hmi.cc ${COMMANDS_SOURCE_DIR}/hmi/request_from_hmi.cc @@ -357,7 +369,20 @@ if (${HMI_DBUS_API}) set (HMI_COMMANDS_SOURCES ${HMI_COMMANDS_SOURCES} ${HMI_COMMANDS_SOURCES_DBUS}) endif (${HMI_DBUS_API}) -SET (LIBRARIES +set(EXCLUDE_PATHS + ${COMMANDS_SOURCE_DIR} + ${EVENT_ENGINE_SOURCE_DIR} + ${MESSAGE_HELPER_SOURCE_DIR} + ${POLICIES_SOURCE_DIR} +) + +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") + +set(LIBRARIES HMI_API MOBILE_API v4_protocol_v1_2_no_extra @@ -373,15 +398,14 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND LIBRARIES sqlite3) endif () -IF(${CMAKE_SYSTEM_NAME} MATCHES "QNX") +if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") list(REMOVE_ITEM LIBRARIES dl) endif() -add_library("AMEventEngine" ${EVENT_ENGINE}) +add_library("AMEventEngine" ${EVENT_ENGINE_SOURCES}) target_link_libraries("AMEventEngine" ${LIBRARIES}) - -add_library("AMPolicyLibrary" ${POLICIES_MANAGER} ) +add_library("AMPolicyLibrary" ${POLICIES_MANAGER_SOURCES} ) target_link_libraries("AMPolicyLibrary" ${LIBRARIES} AMEventEngine) add_library("AMHMICommandsLibrary" ${HMI_COMMANDS_SOURCES}) @@ -392,18 +416,21 @@ add_library("MessageHelper" ${MESSAGE_HELPER_SOURCES}) add_library("AMMobileCommandsLibrary" ${MOBILE_COMMANDS_SOURCES} ) target_link_libraries("AMMobileCommandsLibrary" ${LIBRARIES} AMEventEngine) -add_library("ApplicationManager" ${SOURCES} ${RESUMPTION} ${APP_LAUNCH}) +add_library("ApplicationManager" ${SOURCES}) -target_link_libraries("ApplicationManager" ${LIBRARIES} AMHMICommandsLibrary - AMMobileCommandsLibrary - AMEventEngine - AMPolicyLibrary) +list(APPEND LIBRARIES + AMEventEngine + AMPolicyLibrary + AMHMICommandsLibrary + AMMobileCommandsLibrary +) if(ENABLE_LOG) - target_link_libraries("ApplicationManager" log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) + list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() +target_link_libraries("ApplicationManager" ${LIBRARIES}) + if(BUILD_TESTS) add_subdirectory(test) - add_subdirectory(test/message_helper) endif() diff --git a/src/components/application_manager/test/CMakeLists.txt b/src/components/application_manager/test/CMakeLists.txt index ba5d684df8..a81aa162cb 100644 --- a/src/components/application_manager/test/CMakeLists.txt +++ b/src/components/application_manager/test/CMakeLists.txt @@ -28,42 +28,44 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + # TODO{ALeshin}: APPLINK-10792. Do not write tests which use # application manager(AM) singleton while refactoring of AM is finished. -if (BUILD_TESTS) - - include_directories( - ${GMOCK_INCLUDE_DIRECTORY} - ${CMAKE_BINARY_DIR}/src/components/ - ${COMPONENTS_DIR}/application_manager/include/ - ${COMPONENTS_DIR}/utils/include/ - ${COMPONENTS_DIR}/resumption/include/ - ${COMPONENTS_DIR}/utils/include/ - ${COMPONENTS_DIR}/policy/include/ - ${COMPONENTS_DIR}/media_manager/include/ - ${COMPONENTS_DIR}/security_manager/include/ - ${COMPONENTS_DIR}/policy/test/include/ - ${COMPONENTS_DIR}/application_manager/test/include/ - ) - - set(testSources - ${AM_TEST_DIR}/mobile_message_handler_test.cc - ${AM_TEST_DIR}/mobile_message_handler_v1_test.cc - ${AM_TEST_DIR}/request_info_test.cc - ${AM_TEST_DIR}/resumption_sql_queries_test.cc - ${AM_TEST_DIR}/event_engine_test.cc - ${AM_TEST_DIR}/policy_event_observer_test.cc - ${AM_TEST_DIR}/application_impl_test.cc - ${AM_TEST_DIR}/hmi_capabilities_test.cc - ${AM_TEST_DIR}/application_state_test.cc - ${AM_TEST_DIR}/usage_statistics_test.cc - ${AM_TEST_DIR}/policy_handler_test.cc - ${AM_TEST_DIR}/mock_message_helper.cc - ) - set (request_controller_SOURCES - ${AM_TEST_DIR}/request_controller/request_controller_test.cc - ) +include_directories( + ${GMOCK_INCLUDE_DIRECTORY} + ${CMAKE_BINARY_DIR}/src/components/ + ${COMPONENTS_DIR}/application_manager/include/ + ${COMPONENTS_DIR}/utils/include/ + ${COMPONENTS_DIR}/resumption/include/ + ${COMPONENTS_DIR}/utils/include/ + ${COMPONENTS_DIR}/policy/include/ + ${COMPONENTS_DIR}/media_manager/include/ + ${COMPONENTS_DIR}/security_manager/include/ + ${COMPONENTS_DIR}/policy/test/include/ + ${COMPONENTS_DIR}/application_manager/test/include/ +) + +set(testSources + ${AM_TEST_DIR}/mobile_message_handler_test.cc + ${AM_TEST_DIR}/mobile_message_handler_v1_test.cc + ${AM_TEST_DIR}/request_info_test.cc + ${AM_TEST_DIR}/resumption_sql_queries_test.cc + ${AM_TEST_DIR}/event_engine_test.cc + ${AM_TEST_DIR}/policy_event_observer_test.cc + ${AM_TEST_DIR}/application_impl_test.cc + ${AM_TEST_DIR}/hmi_capabilities_test.cc + ${AM_TEST_DIR}/application_state_test.cc + ${AM_TEST_DIR}/usage_statistics_test.cc + ${AM_TEST_DIR}/policy_handler_test.cc + ${AM_TEST_DIR}/mock_message_helper.cc +) + +set(request_controller_SOURCES + ${AM_TEST_DIR}/request_controller/request_controller_test.cc +) set(testLibraries ApplicationManager @@ -104,72 +106,74 @@ set(test_exec_libraries Resumption ) -IF(${CMAKE_SYSTEM_NAME} MATCHES "QNX") +if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") + list(REMOVE_ITEM test_exec_libraries dl) +endif() + +set(testLibraries + Utils + ApplicationManager + jsoncpp + Policy + connectionHandler + HMI_API + MOBILE_API + v4_protocol_v1_2_no_extra + SmartObjects + formatters + gmock_main + UsageStatistics + dl + ProtocolLibrary + ConfigProfile + MediaManager + Resumption + ProtocolHandler + SecurityManager +) + +if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") list(REMOVE_ITEM test_exec_libraries dl) endif() - set(testLibraries - Utils - ApplicationManager - jsoncpp - Policy - connectionHandler - HMI_API - MOBILE_API - v4_protocol_v1_2_no_extra - SmartObjects - formatters - gmock_main - UsageStatistics - dl - ProtocolLibrary - ConfigProfile - MediaManager - Resumption - ProtocolHandler - SecurityManager - ) - - if (${CMAKE_SYSTEM_NAME} MATCHES "QNX") - list(REMOVE_ITEM test_exec_libraries dl) - endif() - - if (ENABLE_LOG) - list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) - list(APPEND LIBRARIES apr-1 -L${APR_LIBS_DIRECTORY}) - list(APPEND LIBRARIES aprutil-1 -L${APR_UTIL_LIBS_DIRECTORY}) - list(APPEND LIBRARIES expat -L${EXPAT_LIBS_DIRECTORY}) - endif() - - file(COPY smartDeviceLink_test2.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY sdl_preloaded_pt.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY sdl_pt_update.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +if (ENABLE_LOG) + list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) + list(APPEND LIBRARIES apr-1 -L${APR_LIBS_DIRECTORY}) + list(APPEND LIBRARIES aprutil-1 -L${APR_UTIL_LIBS_DIRECTORY}) + list(APPEND LIBRARIES expat -L${EXPAT_LIBS_DIRECTORY}) +endif() + +file(COPY smartDeviceLink_test2.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +file(COPY sdl_preloaded_pt.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +file(COPY sdl_pt_update.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) add_custom_command( -OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libPolicy.so - COMMAND ${CMAKE_COMMAND} -E - copy ${COMPONENTS_DIR}/policy/libPolicy.so ${CMAKE_CURRENT_BINARY_DIR}) - set(CMAKE_EXE_LINKER_FLAGS - "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}") - create_test("application_manager_test" "${testSources}" "${testLibraries}" ) + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libPolicy.so + COMMAND ${CMAKE_COMMAND} -E + copy ${COMPONENTS_DIR}/policy/libPolicy.so ${CMAKE_CURRENT_BINARY_DIR} +) +set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}" +) +create_test("application_manager_test" "${testSources}" "${testLibraries}") + # TODO [AKozoriz] : Fix not buildable tests - set(ResumptionData_SOURCES - ${AM_TEST_DIR}/resumption/resumption_data_test.cc - ${AM_TEST_DIR}/resumption/resumption_data_db_test.cc - ${AM_TEST_DIR}/resumption/resumption_data_json_test.cc - ${AM_TEST_DIR}/resumption/resume_ctrl_test.cc - ${AM_TEST_DIR}/mock_message_helper.cc - ) - - file(COPY hmi_capabilities.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/resumption) - file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/resumption) - create_test("resumption/data_resumption_test" "${ResumptionData_SOURCES}" "${testLibraries}") - - add_subdirectory(state_controller) -endif() +set(ResumptionData_SOURCES + ${AM_TEST_DIR}/resumption/resumption_data_test.cc + ${AM_TEST_DIR}/resumption/resumption_data_db_test.cc + ${AM_TEST_DIR}/resumption/resumption_data_json_test.cc + ${AM_TEST_DIR}/resumption/resume_ctrl_test.cc + ${AM_TEST_DIR}/mock_message_helper.cc +) + +file(COPY hmi_capabilities.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/resumption) +file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/resumption) +create_test("resumption/data_resumption_test" "${ResumptionData_SOURCES}" "${testLibraries}") +add_subdirectory(message_helper) +add_subdirectory(state_controller) add_subdirectory(app_launch) add_subdirectory(commands) diff --git a/src/components/application_manager/test/commands/CMakeLists.txt b/src/components/application_manager/test/commands/CMakeLists.txt index 068823fcfa..e5a083b5b2 100644 --- a/src/components/application_manager/test/commands/CMakeLists.txt +++ b/src/components/application_manager/test/commands/CMakeLists.txt @@ -28,7 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -include(sources) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( ${GMOCK_INCLUDE_DIRECTORY} diff --git a/src/components/application_manager/test/commands/mobile/alert_request_test.cc b/src/components/application_manager/test/commands/mobile/alert_request_test.cc index e8ebcd0f60..b384cd9f11 100644 --- a/src/components/application_manager/test/commands/mobile/alert_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/alert_request_test.cc @@ -210,4 +210,4 @@ TEST_F(AlertRequestTest, OnEvent_UI_HmiSendSuccess_UNSUPPORTED_RESOURCE) { } // namespace mobile_commands_test } // namespace commands_test } // namespace components -} // namespace tests +} // namespace test diff --git a/src/components/application_manager/test/commands/mobile/read_did_request_test.cc b/src/components/application_manager/test/commands/mobile/read_did_request_test.cc index 111dbf4e27..334f559ae6 100644 --- a/src/components/application_manager/test/commands/mobile/read_did_request_test.cc +++ b/src/components/application_manager/test/commands/mobile/read_did_request_test.cc @@ -46,7 +46,7 @@ #include "interfaces/MOBILE_API.h" #include "interfaces/HMI_API.h" #include "application_manager/smart_object_keys.h" -#include "event_engine/event.h" +#include "application_manager/event_engine/event.h" namespace test { namespace components { diff --git a/src/components/application_manager/test/message_helper/CMakeLists.txt.user b/src/components/application_manager/test/message_helper/CMakeLists.txt.user deleted file mode 100755 index e7522c1793..0000000000 --- a/src/components/application_manager/test/message_helper/CMakeLists.txt.user +++ /dev/null @@ -1,189 +0,0 @@ - - - - - - EnvironmentId - {6965f0e8-9b58-4b26-8426-81354d6c3400} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - true - false - 0 - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Desktop Qt 5.5.1 GCC 64bit - Desktop Qt 5.5.1 GCC 64bit - qt.55.gcc_64_kit - 0 - 0 - 0 - - false - /home/oherasym/sdl_panasonic/src/components/application_manager/test/message_helper-build - - - - - false - - true - Make - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - clean - - true - - true - Make - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - all - - CMakeProjectManager.CMakeBuildConfiguration - - 1 - - - 0 - Deploy - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deploy locally - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - 2 - - - - %{buildDir} - Custom Executable - - ProjectExplorer.CustomExecutableRunConfiguration - 3768 - false - true - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 1 - - - ProjectExplorer.Project.Updater.FileVersion - 18 - - - Version - 18 - - diff --git a/src/components/application_manager/test/resumption/resume_ctrl_test.cc b/src/components/application_manager/test/resumption/resume_ctrl_test.cc index 14f6cf58cd..b62830aeff 100644 --- a/src/components/application_manager/test/resumption/resume_ctrl_test.cc +++ b/src/components/application_manager/test/resumption/resume_ctrl_test.cc @@ -49,6 +49,10 @@ #include "application_manager/mock_event_dispatcher.h" #include "application_manager/mock_state_controller.h" +#if defined(_MSC_VER) +#define snprintf _snprintf_s +#endif + namespace test { namespace components { namespace resumption_test { @@ -187,7 +191,7 @@ TEST_F(ResumeCtrlTest, StartResumption_AppWithFiles) { char numb[max_size]; for (uint32_t i = 0; i < count_of_files; i++) { file_types[i] = i; - std::snprintf(numb, max_size, "%d", i); + snprintf(numb, max_size, "%d", i); file_names[i] = "test_file" + std::string(numb); } @@ -318,7 +322,7 @@ TEST_F(ResumeCtrlTest, StartResumption_AppWithChoiceSet) { const size_t max_size = 12; char numb[max_size]; for (uint32_t i = 0; i < count_of_choice; ++i) { - std::snprintf(numb, max_size, "%d", i); + snprintf(numb, max_size, "%d", i); choice[application_manager::strings::vr_commands] = "VrCommand" + std::string(numb); choice[application_manager::strings::choice_id] = i; @@ -435,7 +439,7 @@ TEST_F(ResumeCtrlTest, StartResumption_AppWithSubscriptionToIVI) { smart_objects::SmartObject app_vi; int vtype = application_manager::VehicleDataType::GPS; - uint i = 0; + uint32_t i = 0; for (; vtype < application_manager::VehicleDataType::STEERINGWHEEL; ++i, ++vtype) { app_vi[i] = vtype; diff --git a/src/components/config_profile/CMakeLists.txt b/src/components/config_profile/CMakeLists.txt index 107fd58127..2f8561fc2d 100644 --- a/src/components/config_profile/CMakeLists.txt +++ b/src/components/config_profile/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include @@ -35,13 +36,18 @@ include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) -set (SOURCES - ${COMPONENTS_DIR}/config_profile/src/profile.cc - ${COMPONENTS_DIR}/config_profile/src/ini_file.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) +set(LIBRARIES + Utils +) + +collect_sources(SOURCES "${PATHS}") add_library("ConfigProfile" ${SOURCES}) -target_link_libraries("ConfigProfile" Utils) +target_link_libraries("ConfigProfile" ${LIBRARIES}) if(BUILD_TESTS) add_subdirectory(test) diff --git a/src/components/config_profile/test/CMakeLists.txt b/src/components/config_profile/test/CMakeLists.txt index 1246bff066..597be8fe00 100644 --- a/src/components/config_profile/test/CMakeLists.txt +++ b/src/components/config_profile/test/CMakeLists.txt @@ -28,23 +28,20 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( ${GMOCK_INCLUDE_DIRECTORY} ${COMPONENTS_DIR}/config_profile/include ) - -set(testSources - profile_test.cc - ini_file_test.cc -) - -set(testLibraries +set(LIBRARIES gmock ConfigProfile ) + +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") +create_test(config_profile_test "${SOURCES}" "${LIBRARIES}") file(COPY smartDeviceLink.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) @@ -52,6 +49,3 @@ file(COPY smartDeviceLink_invalid_pairs.ini DESTINATION ${CMAKE_CURRENT_BINARY_D file(COPY smartDeviceLink_invalid_string.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY smartDeviceLink_invalid_int.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY smartDeviceLink_invalid_boolean.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -create_test("config_profile_test" "${testSources}" "${testLibraries}") - -endif() diff --git a/src/components/connection_handler/CMakeLists.txt b/src/components/connection_handler/CMakeLists.txt index dc1b2d24d6..2cdfec91f2 100644 --- a/src/components/connection_handler/CMakeLists.txt +++ b/src/components/connection_handler/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,8 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. - -set(CH_SRC_DIR ${COMPONENTS_DIR}/connection_handler/src) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include @@ -39,20 +38,20 @@ include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) -set (SOURCES - ${CH_SRC_DIR}/connection_handler_impl.cc - ${CH_SRC_DIR}/connection.cc - ${CH_SRC_DIR}/device.cc - ${CH_SRC_DIR}/heartbeat_monitor.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) set(LIBRARIES ProtocolLibrary + encryption ) +collect_sources(SOURCES "${PATHS}") add_library(connectionHandler ${SOURCES}) -target_link_libraries(connectionHandler encryption) +target_link_libraries(connectionHandler ${LIBRARIES}) if(BUILD_TESTS) - add_subdirectory(test) + add_subdirectory(test) endif() diff --git a/src/components/connection_handler/test/CMakeLists.txt b/src/components/connection_handler/test/CMakeLists.txt index 32da4bdcd8..033a45e97d 100644 --- a/src/components/connection_handler/test/CMakeLists.txt +++ b/src/components/connection_handler/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,9 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) - -set(appMain_DIR ${CMAKE_SOURCE_DIR}/src/appMain) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( ${GMOCK_INCLUDE_DIRECTORY} @@ -46,15 +44,7 @@ set(LIBRARIES ProtocolHandler ) -set(SOURCES - connection_handler_impl_test.cc - connection_test.cc - device_test.cc - heart_beat_monitor_test.cc -) - -file(COPY ${appMain_DIR}/smartDeviceLink.ini DESTINATION "./") - -create_test("connection_handler_test" "${SOURCES}" "${LIBRARIES}") +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") +create_test(connection_handler_test "${SOURCES}" "${LIBRARIES}") -endif() +file(COPY ${CMAKE_SOURCE_DIR}/src/appMain/smartDeviceLink.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/components/dbus/CMakeLists.txt b/src/components/dbus/CMakeLists.txt index 7e7f2af787..cb1ce30a6d 100644 --- a/src/components/dbus/CMakeLists.txt +++ b/src/components/dbus/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( ${DBUS_INCLUDE_DIRS} @@ -40,17 +41,17 @@ include_directories ( ${CMAKE_BINARY_DIR}/src/components/ ) -set (SOURCES +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/introspection_xml.cc ${CMAKE_CURRENT_BINARY_DIR}/message_descriptions.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/dbus_adapter.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/dbus_message.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/dbus_message_controller.cc - ${CMAKE_CURRENT_SOURCE_DIR}/src/schema.cc ) +collect_sources(SOURCES "${PATHS}") -set (LIBRARIES dbus-1 -L${DBUS_LIBS_DIRECTORY}) - +set(LIBRARIES + dbus-1 -L${DBUS_LIBS_DIRECTORY} +) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/message_descriptions.cc @@ -71,7 +72,7 @@ add_custom_command( ) add_library("DBus" ${SOURCES}) -ADD_DEPENDENCIES("DBus" Utils install-3rd_party_dbus) +add_dependecnies("DBus" Utils install-3rd_party_dbus) target_link_libraries("DBus" "${LIBRARIES}") diff --git a/src/components/dbus/test/CMakeLists.txt b/src/components/dbus/test/CMakeLists.txt index d96f2388fb..1b3df2c0e7 100644 --- a/src/components/dbus/test/CMakeLists.txt +++ b/src/components/dbus/test/CMakeLists.txt @@ -28,13 +28,20 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( ${GMOCK_INCLUDE_DIRECTORY} ${COMPONENTS_DIR}/dbus/include/ ) +#FIXME: exclude some tests +set (EXCLUDE_PATHS + test_dbus_message_controller.cc +) + +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" ${EXCLUDE_PATHS}) + set (LIBRARIES gmock DBus @@ -42,12 +49,4 @@ set (LIBRARIES SmartObjects ) -set(testSources - ${COMPONENTS_DIR}/dbus/test/test_schema.cc - ${COMPONENTS_DIR}/dbus/test/test_dbus_adapter.cc -) - -create_test("test_DBus_test" "${testSources}" "${LIBRARIES}") - -endif() - +create_test(test_DBus_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/formatters/CMakeLists.txt b/src/components/formatters/CMakeLists.txt index 1858342ff3..02a337e278 100644 --- a/src/components/formatters/CMakeLists.txt +++ b/src/components/formatters/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,8 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. - -set(FORMATTERS_SRC_DIR ${COMPONENTS_DIR}/formatters/src) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include/ @@ -41,22 +40,13 @@ include_directories ( ${COMPONENTS_DIR}/utils/include ) -set (SOURCES - ${FORMATTERS_SRC_DIR}/CSmartFactory.cc -) - -set (FORMATTER_SOURCES - ${FORMATTERS_SRC_DIR}/CFormatterJsonBase.cc - ${FORMATTERS_SRC_DIR}/CFormatterJsonSDLRPCv1.cc - ${FORMATTERS_SRC_DIR}/CFormatterJsonSDLRPCv2.cc - ${FORMATTERS_SRC_DIR}/formatter_json_rpc.cc - ${FORMATTERS_SRC_DIR}/meta_formatter.cc - ${FORMATTERS_SRC_DIR}/generic_json_formatter.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) -add_library("formatters" ${SOURCES} - ${FORMATTER_SOURCES} -) +collect_sources(SOURCES "${PATHS}") +add_library(formatters ${SOURCES}) if(BUILD_TESTS) add_subdirectory(test) diff --git a/src/components/formatters/test/CMakeLists.txt b/src/components/formatters/test/CMakeLists.txt index d245626dae..c80c3d0e40 100644 --- a/src/components/formatters/test/CMakeLists.txt +++ b/src/components/formatters/test/CMakeLists.txt @@ -29,7 +29,7 @@ # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( ${GMOCK_INCLUDE_DIRECTORY} @@ -49,19 +49,15 @@ set(LIBRARIES jsoncpp ) -set(SOURCES - ${COMPONENTS_DIR}/formatters/test/src/SmartFactoryTestHelper.cc - ${COMPONENTS_DIR}/formatters/test/CSmartFactory_test.cc - ${COMPONENTS_DIR}/formatters/test/CFormatterJsonBase_test.cc - ${COMPONENTS_DIR}/formatters/test/generic_json_formatter_test.cc - ${COMPONENTS_DIR}/formatters/test/formatter_json_rpc_test.cc - ${COMPONENTS_DIR}/formatters/test/src/create_smartSchema.cc - ${COMPONENTS_DIR}/formatters/test/cFormatterJsonSDLRPCv1_test.cc - ${COMPONENTS_DIR}/formatters/test/cFormatterJsonSDLRPCv2_test.cc - ${COMPONENTS_DIR}/formatters/test/src/meta_formatter_test_helper.cc - ${COMPONENTS_DIR}/formatters/test/meta_formatter_test.cc +set (SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src + ${CMAKE_CURRENT_SOURCE_DIR} ) -create_test("formatters_test" "${SOURCES}" "${LIBRARIES}") +set (EXCLUDE_PATHS +) + +collect_sources(SOURCES "") +create_test(formatters_test "${SOURCES}" "${LIBRARIES}") -endif() diff --git a/src/components/hmi_message_handler/CMakeLists.txt b/src/components/hmi_message_handler/CMakeLists.txt index 49aea93bda..c1dfca5e67 100644 --- a/src/components/hmi_message_handler/CMakeLists.txt +++ b/src/components/hmi_message_handler/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,6 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include/ @@ -46,29 +48,36 @@ include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) -IF (HMIADAPTER STREQUAL "dbus") - set (DBUS_SOURCE ./src/dbus_message_adapter.cc) - set (DBUS_ADAPTER DBus) -ENDIF () +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +if (HMIADAPTER STREQUAL "dbus") + set(EXCLUDE_PATHS) + set(DBUS_ADAPTER DBus) +else() + set(EXCLUDE_PATHS dbus_message_adapter.cc) + set(DBUS_ADAPTER) +endif () -set (SOURCES - ${COMPONENTS_DIR}/hmi_message_handler/src/hmi_message_handler_impl.cc - ${COMPONENTS_DIR}/hmi_message_handler/src/messagebroker_adapter.cc - ${COMPONENTS_DIR}/hmi_message_handler/src/hmi_message_adapter_impl.cc - ${DBUS_SOURCE} +list(APPEND EXCLUDE_PATHS + mqueue_adapter.cc ) +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") + set(LIBRARIES - Utils - ${DBUS_ADAPTER} - ${RTLIB} + Utils + ${DBUS_ADAPTER} + ${RTLIB} ) add_library("HMIMessageHandler" ${SOURCES}) target_link_libraries("HMIMessageHandler" ${LIBRARIES}) if(ENABLE_LOG) - target_link_libraries("HMIMessageHandler" log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) + target_link_libraries("HMIMessageHandler" log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() # Tests temporary are inactivated. For details please check diff --git a/src/components/hmi_message_handler/test/CMakeLists.txt b/src/components/hmi_message_handler/test/CMakeLists.txt index 98e9fd5653..0d7ccd9ee1 100644 --- a/src/components/hmi_message_handler/test/CMakeLists.txt +++ b/src/components/hmi_message_handler/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,7 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( ${GMOCK_INCLUDE_DIRECTORY} @@ -36,27 +37,31 @@ include_directories ( ${COMPONENTS_DIR}/hmi_message_handler/test/include ) +if (HMIADAPTER STREQUAL "messagebroker") + set (BROKER_LIBRARIES + message_broker_client + message_broker_server + ) +endif() + +set(EXCLUDE_PATHS) + set(LIBRARIES gmock ApplicationManager HMIMessageHandler jsoncpp - MessageBrokerClient - MessageBrokerServer + ${BROKER_LIBRARIES} ConfigProfile ) -set(SOURCES -${COMPONENTS_DIR}/hmi_message_handler/test/hmi_message_handler_impl_test.cc -${COMPONENTS_DIR}/hmi_message_handler/test/hmi_message_adapter_test.cc -) - -if(${QT_HMI}) - list (APPEND SOURCES - ${COMPONENTS_DIR}/hmi_message_handler/test/mock_subscriber.cc - ${COMPONENTS_DIR}/hmi_message_handler/test/dbus_message_adapter_test.cc +if(NOT HMI_DBUS_API}) + list (APPEND EXCLUDE_PATHS + mock_subscriber.cc + dbus_message_adapter_test.cc ) endif() -create_test("hmi_message_handler_test" "${SOURCES}" "${LIBRARIES}") -endif() +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") + +create_test(hmi_message_handler_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/include/utils/threads/CMakeLists.txt b/src/components/include/utils/threads/CMakeLists.txt deleted file mode 100644 index f97039c21b..0000000000 --- a/src/components/include/utils/threads/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(UtilsIncludeDir ${COMPONENTS_DIR/utils/include) - -include_directories ( - ${UtilsIncludeDir} -) \ No newline at end of file diff --git a/src/components/interfaces/CMakeLists.txt b/src/components/interfaces/CMakeLists.txt index bcb47976ea..2c84e48235 100644 --- a/src/components/interfaces/CMakeLists.txt +++ b/src/components/interfaces/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,54 +28,46 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/generators.cmake) include_directories ( - ${COMPONENTS_DIR}/utils/include/ + ${COMPONENTS_DIR}/include + ${COMPONENTS_DIR}/utils/include ${COMPONENTS_DIR}/formatters/include + ${COMPONENTS_DIR}/smart_objects/include + ${CMAKE_BINARY_DIR} ) - -GenerateInterface("v4_protocol_v1_2_no_extra.xml" "NsSmartDeviceLinkRPC::V1" "sdlrpcv1") -GenerateInterface("MOBILE_API.xml" "mobile_apis" "sdlrpcv2") - -IF (${HMI_JSON_API}) - GenerateInterface("HMI_API.xml" "hmi_apis" "jsonrpc") -ENDIF (${HMI_JSON_API}) -IF (${HMI_DBUS_API}) - set(hpp_file - "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API.h" - "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.h" - ) +generate_interface("v4_protocol_v1_2_no_extra.xml" "NsSmartDeviceLinkRPC::V1" "sdlrpcv1") +add_library(v4_protocol_v1_2_no_extra ${CMAKE_CURRENT_BINARY_DIR}/v4_protocol_v1_2_no_extra_schema.cc) - set(cpp_file "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.cc") - set(full_xml_name "${CMAKE_CURRENT_SOURCE_DIR}/QT_HMI_API.xml") +generate_interface("MOBILE_API.xml" "mobile_apis" "sdlrpcv2") +add_library(MOBILE_API ${CMAKE_CURRENT_BINARY_DIR}/MOBILE_API_schema.cc) - add_custom_command( OUTPUT ${hpp_file} ${cpp_file} - COMMAND ${INTEFRACE_GENERATOR_CMD} ${full_xml_name} hmi_apis ${CMAKE_CURRENT_BINARY_DIR} "--parser-type" "jsonrpc" - DEPENDS ${INTERFACE_GENERATOR_DEPENDENCIES} ${full_xml_name} - COMMENT "Generating files:\n ${hpp_file}\n ${cpp_file}\nfrom:\n QT_HMI_API.xml ..." - VERBATIM - ) +if(HMI_JSON_API) + generate_interface("HMI_API.xml" "hmi_apis" "jsonrpc") + add_library(HMI_API ${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.cc) +endif() - include_directories ( - ${COMPONENTS_DIR}/smart_objects/include - ${COMPONENTS_DIR}/formatters/include/ - ${CMAKE_BINARY_DIR} - ) +if(HMI_DBUS_API) + generate_interface("QT_HMI_API.xml" "hmi_apis" "jsonrpc") - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HMI_API.h" + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HMI_API.h" COMMAND sed "-e" "s/QT_HMI_API/HMI_API/g" "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API.h" > "${CMAKE_CURRENT_BINARY_DIR}/HMI_API.h" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API.h") - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.h" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API.h" + ) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.h" COMMAND sed "-e" "s/QT_HMI_API/HMI_API/g" "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.h" > "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.h" - DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.h") - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.cc" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.h" + ) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.cc" COMMAND sed "-e" "s/QT_HMI_API/HMI_API/g" "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.cc" > "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.cc" DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/QT_HMI_API_schema.cc" "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.h" "${CMAKE_CURRENT_BINARY_DIR}/HMI_API.h") - add_library(HMI_API "${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.cc") -ENDIF (${HMI_DBUS_API}) + + add_library(HMI_API ${CMAKE_CURRENT_BINARY_DIR}/HMI_API_schema.cc) +endif() add_dependencies(HMI_API Utils) diff --git a/src/components/media_manager/CMakeLists.txt b/src/components/media_manager/CMakeLists.txt index 3ca02357ab..c143a7979e 100644 --- a/src/components/media_manager/CMakeLists.txt +++ b/src/components/media_manager/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2014-2015, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,63 +28,10 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) -if (EXTENDED_MEDIA_MODE) -find_package(Gstreamer-1.0 REQUIRED) -find_package(Glib-2.0 REQUIRED) -find_package(PkgConfig) -pkg_check_modules(GLIB2 REQUIRED glib-2.0) -add_definitions(${GLIB2_CFLAGS}) -set(default_includes - ${GSTREAMER_gst_INCLUDE_DIR} - ${GSTREAMER_gstconfig_INCLUDE_DIR} - ${GLIB_glib_2_INCLUDE_DIR} -) -set(default_sources - ${COMPONENTS_DIR}/media_manager/src/audio/a2dp_source_player_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/audio/from_mic_recorder_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/audio/from_mic_to_file_recorder_thread.cc - ${COMPONENTS_DIR}/media_manager/src/audio/socket_audio_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/audio/pipe_audio_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/audio/file_audio_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/video/socket_video_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/video/pipe_video_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/video/file_video_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/pipe_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/socket_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/file_streamer_adapter.cc -) -set(LIBRARIES - ${GSTREAMER_gstreamer_LIBRARY} - ApplicationManager - pulse-simple - pulse - gobject-2.0 - glib-2.0 -) -else(EXTENDED_MEDIA_MODE) -set(default_includes -) - -set(default_sources - ${COMPONENTS_DIR}/media_manager/src/audio/socket_audio_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/audio/pipe_audio_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/audio/file_audio_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/video/socket_video_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/video/pipe_video_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/video/file_video_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/pipe_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/socket_streamer_adapter.cc - ${COMPONENTS_DIR}/media_manager/src/file_streamer_adapter.cc -) -set(LIBRARIES - ProtocolLibrary -) -endif() - -include_directories ( +include_directories( include ${COMPONENTS_DIR}/media_manager/include/audio/ ${COMPONENTS_DIR}/media_manager/include/video/ @@ -99,22 +46,60 @@ include_directories ( ${JSONCPP_INCLUDE_DIRECTORY} ${CMAKE_BINARY_DIR}/src/components/ ${COMPONENTS_DIR}/policy/include/ - ${default_includes} ${LOG4CXX_INCLUDE_DIRECTORY} ) -set (SOURCES - ${COMPONENTS_DIR}/media_manager/src/media_adapter_impl.cc - ${COMPONENTS_DIR}/media_manager/src/audio/from_mic_recorder_listener.cc - ${COMPONENTS_DIR}/media_manager/src/audio/audio_stream_sender_thread.cc - ${COMPONENTS_DIR}/media_manager/src/streamer_listener.cc - ${COMPONENTS_DIR}/media_manager/src/media_manager_impl.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) -add_library("MediaManager" ${SOURCES} ${default_sources}) +set(EXCLUDE_PATHS + video_stream_to_file_adapter.cc +) + +set(LIBRARIES + ProtocolLibrary +) + +if(EXTENDED_MEDIA_MODE) + find_package(Gstreamer-1.0 REQUIRED) + find_package(Glib-2.0 REQUIRED) + find_package(PkgConfig) + pkg_check_modules(GLIB2 REQUIRED glib-2.0) + add_definitions(${GLIB2_CFLAGS}) + + include_directories( + ${GSTREAMER_gst_INCLUDE_DIR} + ${GSTREAMER_gstconfig_INCLUDE_DIR} + ${GLIB_glib_2_INCLUDE_DIR} + ) + list(APPEND EXCLUDE_PATHS + + ) + list(APPEND LIBRARIES + ${GSTREAMER_gstreamer_LIBRARY} + pulse-simple + pulse + gobject-2.0 + glib-2.0 + ) +else() + list(APPEND EXCLUDE_PATHS + a2dp_source_player_adapter.cc + from_mic_recorder_adapter.cc + from_mic_to_file_recorder_thread.cc + ) +endif() + +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") +add_library("MediaManager" ${SOURCES}) target_link_libraries("MediaManager" ${LIBRARIES}) -if(BUILD_TESTS) - add_subdirectory(test) +if(ENABLE_LOG) + target_link_libraries("MediaManager" log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() +if(BUILD_TESTS) + add_subdirectory(test) +endif() diff --git a/src/components/media_manager/test/CMakeLists.txt b/src/components/media_manager/test/CMakeLists.txt index ede6f27f95..f5d596f681 100644 --- a/src/components/media_manager/test/CMakeLists.txt +++ b/src/components/media_manager/test/CMakeLists.txt @@ -28,7 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( ${GMOCK_INCLUDE_DIRECTORY} @@ -46,9 +46,7 @@ if(EXTENDED_MEDIA_MODE) ) endif() -set(SOURCES - ${COMPONENTS_DIR}/media_manager/test/media_manager_impl_test.cc -) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") set(LIBRARIES SmartObjects @@ -74,7 +72,3 @@ create_test("media_manager_test" "${SOURCES}" "${LIBRARIES}") if(ENABLE_LOG) target_link_libraries("media_manager_test" log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() - -endif() - -# vim: set ts=2 sw=2 et: diff --git a/src/components/policy/CMakeLists.txt b/src/components/policy/CMakeLists.txt index 3a2b0829dc..ce6d7c227c 100644 --- a/src/components/policy/CMakeLists.txt +++ b/src/components/policy/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2013, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,12 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -set(target Policy) -set(install_destination bin) -set(copy_destination ${CMAKE_BINARY_DIR}/src/appMain) -set(library_name ${CMAKE_SHARED_LIBRARY_PREFIX}${target}${CMAKE_SHARED_LIBRARY_SUFFIX}) - -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( ${COMPONENTS_DIR}/policy/include @@ -44,37 +40,43 @@ include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) -set(SOURCES - ${COMPONENTS_DIR}/policy/src/policy_manager_impl.cc - ${COMPONENTS_DIR}/policy/src/policy_helper.cc - ${COMPONENTS_DIR}/policy/src/policy_table.cc - ${COMPONENTS_DIR}/policy/src/sql_pt_queries.cc - ${COMPONENTS_DIR}/policy/src/sql_pt_representation.cc - ${COMPONENTS_DIR}/policy/src/update_status_manager.cc - ${COMPONENTS_DIR}/policy/src/cache_manager.cc - ${COMPONENTS_DIR}/rpc_base/src/rpc_base/rpc_base.cc +set(POLICY_TABLE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/policy/policy_table + ${CMAKE_CURRENT_SOURCE_DIR}/src/policy_table ) +collect_sources(POLICY_TABLE_SOURCES "${POLICY_TABLE_PATHS}") +add_library(policy_struct ${POLICY_TABLE_SOURCES}) +target_link_libraries(policy_struct Utils) -# --- Table struct section -set(policy_struct_target policy_struct) -set(POLICY_TABLE_SOURCES - ${COMPONENTS_DIR}/policy/src/policy_table/enums.cc - ${COMPONENTS_DIR}/policy/src/policy_table/types.cc - ${COMPONENTS_DIR}/policy/src/policy_table/validation.cc +set(USAGE_STATISTICS_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/policy/usage_statistics + ${CMAKE_CURRENT_SOURCE_DIR}/src/usage_statistics ) +collect_sources(USAGE_STATISTICS_SOURCES "${USAGE_STATISTICS_PATHS}") +add_library(UsageStatistics ${USAGE_STATISTICS_SOURCES}) -add_library(${policy_struct_target} ${POLICY_TABLE_SOURCES}) -target_link_libraries(${policy_struct_target} Utils) -# --- end of Table struct section +set(EXCLUDE_PATHS + ${POLICY_TABLE_PATHS} + ${USAGE_STATISTICS_PATHS} + sql_pt_ext_queries.cc + sql_pt_ext_representation.cc +) -# --- Usage statistics section -set(USAGE_STATISTICS_SOURCES - ${COMPONENTS_DIR}/policy/src/usage_statistics/counter.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/src/ + ${COMPONENTS_DIR}/rpc_base/src/rpc_base/rpc_base.cc +) +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") + +set(LIBRARIES + ConfigProfile + policy_struct + dbms + jsoncpp + Utils ) -add_library(UsageStatistics ${USAGE_STATISTICS_SOURCES}) -# --- end of Usage statistics section -set(LIBRARIES ConfigProfile policy_struct dbms jsoncpp Utils) if (CMAKE_SYSTEM_NAME STREQUAL "QNX") # --- QDB Wrapper include_directories (${COMPONENTS_DIR}/utils/include/utils) @@ -84,22 +86,28 @@ else () list(APPEND LIBRARIES sqlite3) endif () -add_library(${target} SHARED ${SOURCES}) -target_link_libraries(${target} ${LIBRARIES} ) +add_library(Policy SHARED ${SOURCES}) +target_link_libraries(Policy ${LIBRARIES}) if(ENABLE_LOG) - target_link_libraries(${target} log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) + target_link_libraries(Policy log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() -add_custom_target(copy_library_${target} ALL - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_CURRENT_BINARY_DIR}/${library_name} - ${copy_destination} - DEPENDS ${target} - COMMENT "Copying library ${library_name}") +set(LIBRARY_NAME ${CMAKE_SHARED_LIBRARY_PREFIX}Policy${CMAKE_SHARED_LIBRARY_SUFFIX}) +set(TARGET_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/${LIBRARY_NAME}) +set(INSTALL_DESTINATION bin) +set(COPY_DESTINATION ${CMAKE_BINARY_DIR}/src/appMain) -install(TARGETS ${target} - DESTINATION ${install_destination} +add_custom_target(copy_policy_library ALL + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${TARGET_LOCATION} + ${COPY_DESTINATION}/${LIBRARY_NAME} + DEPENDS Policy + COMMENT "Copying library ${LIBRARY_NAME}" +) + +install(TARGETS Policy + DESTINATION ${INSTALL_DESTINATION} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE @@ -107,4 +115,4 @@ install(TARGETS ${target} if(BUILD_TESTS) add_subdirectory(test) -endif() # BUILD_TESTS +endif() diff --git a/src/components/policy/test/CMakeLists.txt b/src/components/policy/test/CMakeLists.txt index 95a61f92ff..4f6abf2992 100644 --- a/src/components/policy/test/CMakeLists.txt +++ b/src/components/policy/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,6 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + include_directories( include ${COMPONENTS_DIR} @@ -40,26 +42,17 @@ include_directories( ${COMPONENTS_DIR}/policy/test/include/ ) -set(testLibraries +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") + +set(LIBRARIES gmock + dbms Utils Policy UsageStatistics ) -set(testSources - counter_test.cc - shared_library_test.cc - generated_code_test.cc - policy_manager_impl_test.cc - update_status_manager_test.cc -) - -list (APPEND testSources - sql_pt_representation_test.cc -) - -create_test("policy_test" "${testSources}" "${testLibraries}") +create_test(policy_test "${SOURCES}" "${LIBRARIES}") file(COPY valid_sdl_pt_update.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY sdl_preloaded_pt.json DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/src/components/protocol/CMakeLists.txt b/src/components/protocol/CMakeLists.txt index 8524ff4f44..7d8579bdbc 100644 --- a/src/components/protocol/CMakeLists.txt +++ b/src/components/protocol/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,18 +28,18 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( - ./include - ${APR_INCLUDE_DIRECTORY} + ${COMPONENTS_DIR}/include + ${COMPONENTS_DIR}/utils/include ) -set(SOURCES - ${COMPONENTS_DIR}/protocol/src/raw_message.cc - ${COMPONENTS_DIR}/protocol/src/service_type.cc - ${COMPONENTS_DIR}/protocol/src/message_priority.cc - ${COMPONENTS_DIR}/protocol/src/rpc_type.cc +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") + +set(LIBRARIES + Utils ) add_library(ProtocolLibrary ${SOURCES}) -target_link_libraries(ProtocolLibrary Utils) +target_link_libraries(ProtocolLibrary ${LIBRARIES}) diff --git a/src/components/protocol_handler/CMakeLists.txt b/src/components/protocol_handler/CMakeLists.txt index a09a565844..559acf8956 100644 --- a/src/components/protocol_handler/CMakeLists.txt +++ b/src/components/protocol_handler/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( include @@ -37,13 +38,11 @@ include_directories( ${LOG4CXX_INCLUDE_DIRECTORY} ) -set(SOURCES - ${COMPONENTS_DIR}/protocol_handler/src/incoming_data_handler.cc - ${COMPONENTS_DIR}/protocol_handler/src/protocol_handler_impl.cc - ${COMPONENTS_DIR}/protocol_handler/src/protocol_packet.cc - ${COMPONENTS_DIR}/protocol_handler/src/protocol_payload.cc - ${COMPONENTS_DIR}/protocol_handler/src/multiframe_builder.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) +collect_sources(SOURCES "${PATHS}") set(LIBRARIES ProtocolLibrary diff --git a/src/components/protocol_handler/test/CMakeLists.txt b/src/components/protocol_handler/test/CMakeLists.txt index 87d91bfd54..ca079dcc7e 100644 --- a/src/components/protocol_handler/test/CMakeLists.txt +++ b/src/components/protocol_handler/test/CMakeLists.txt @@ -28,7 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if (BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include @@ -38,9 +38,12 @@ include_directories ( ${COMPONENTS_DIR}/protocol_handler/test/include ${COMPONENTS_DIR}/include/protocol ${JSONCPP_INCLUDE_DIRECTORY} + ${GMOCK_INCLUDE_DIRECTORY} ) -set (LIBRARIES +collect_sources(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}) + +set(LIBRARIES gmock ProtocolHandler connectionHandler @@ -49,15 +52,4 @@ set (LIBRARIES ProtocolLibrary ) -set (SOURCES - incoming_data_handler_test.cc - protocol_header_validator_test.cc - protocol_handler_tm_test.cc - protocol_packet_test.cc - protocol_payload_test.cc - multiframe_builder_test.cc -) - -create_test ("protocol_handler_test" "${SOURCES}" "${LIBRARIES}") - -endif () +create_test(protocol_handler_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/qt_hmi/test/CMakeLists.txt b/src/components/qt_hmi/test/CMakeLists.txt index b0c48a4348..91ec2cd20c 100644 --- a/src/components/qt_hmi/test/CMakeLists.txt +++ b/src/components/qt_hmi/test/CMakeLists.txt @@ -29,8 +29,6 @@ # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) - cmake_minimum_required(VERSION 2.8.11) set(QT_HMI_TESTS_LIST @@ -67,4 +65,3 @@ foreach( file_i ${QT_HMI_TESTS_LIST}) file(COPY ${file_i} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) endforeach( file_i ) -endif() \ No newline at end of file diff --git a/src/components/resumption/CMakeLists.txt b/src/components/resumption/CMakeLists.txt index b8fa277cae..f142f59b1e 100644 --- a/src/components/resumption/CMakeLists.txt +++ b/src/components/resumption/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,6 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include @@ -37,9 +38,11 @@ include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) -set (SOURCES - ${COMPONENTS_DIR}/resumption/src/last_state.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) +collect_sources(SOURCES "${PATHS}") add_library("Resumption" ${SOURCES}) diff --git a/src/components/resumption/test/CMakeLists.txt b/src/components/resumption/test/CMakeLists.txt index 6fa1c07381..a131470cd2 100644 --- a/src/components/resumption/test/CMakeLists.txt +++ b/src/components/resumption/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,7 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( ${LOG4CXX_INCLUDE_DIRECTORY} @@ -41,6 +41,8 @@ include_directories( ${CMAKE_BINARY_DIR} ) +collect_sources(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}) + set(LIBRARIES gmock ConfigProfile @@ -50,13 +52,4 @@ set(LIBRARIES ConfigProfile ) -set(SOURCES - ${COMPONENTS_DIR}/resumption/test/last_state_test.cc -) - -#file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -#file(COPY app_info.dat DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - -create_test("resumption_test" "${SOURCES}" "${LIBRARIES}") - -endif() +create_test(resumption_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/rpc_base/CMakeLists.txt b/src/components/rpc_base/CMakeLists.txt index 94e67cc985..700cec72bb 100644 --- a/src/components/rpc_base/CMakeLists.txt +++ b/src/components/rpc_base/CMakeLists.txt @@ -28,31 +28,27 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. - -set(RPC_BASE_INCLUDE_DIR ${COMPONENTS_DIR}/rpc_base/include) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( - include + ${COMPONENTS_DIR}/rpc_base/include + ${COMPONENTS_DIR}/utils/include ${JSONCPP_INCLUDE_DIRECTORY} ) -set (SOURCES - ${COMPONENTS_DIR}/rpc_base/src/rpc_base/rpc_base.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) +collect_sources(SOURCES "${PATHS}") -set (HEADERS - ${RPC_BASE_INCLUDE_DIR}/rpc_base/gtest_support.h - ${RPC_BASE_INCLUDE_DIR}/rpc_base/rpc_base_dbus_inl.h - ${RPC_BASE_INCLUDE_DIR}/rpc_base/rpc_base.h - ${RPC_BASE_INCLUDE_DIR}/rpc_base/rpc_base_inl.h - ${RPC_BASE_INCLUDE_DIR}/rpc_base/rpc_base_json_inl.h - ${RPC_BASE_INCLUDE_DIR}/rpc_base/rpc_message.h - ${RPC_BASE_INCLUDE_DIR}/rpc_base/validation_report.h +set(LIBRARIES + jsoncpp ) -add_library(rpc_base ${HEADERS} ${SOURCES}) -target_link_libraries(rpc_base jsoncpp) +add_library(rpc_base ${SOURCES}) +target_link_libraries(rpc_base ${LIBRARIES}) if(BUILD_TESTS) add_subdirectory(test) -endif() \ No newline at end of file +endif() diff --git a/src/components/rpc_base/test/CMakeLists.txt b/src/components/rpc_base/test/CMakeLists.txt index 76cf738f46..566f0ddcde 100644 --- a/src/components/rpc_base/test/CMakeLists.txt +++ b/src/components/rpc_base/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,8 +28,9 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if (BUILD_TESTS) - include_directories ( +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + +include_directories( ${COMPONENTS_DIR}/dbus/include ${COMPONENTS_DIR}/dbus/src ${COMPONENTS_DIR}/rpc_base/include @@ -43,20 +44,16 @@ set(LIBRARIES jsoncpp ) -set(SOURCES - rpc_base_json_test.cc - rpc_base_test.cc - validation_report_test.cc -) - -if (${HMI_DBUS_API}) - # Build dbus tests +if(${HMI_DBUS_API}) include_directories(${DBUS_INCLUDE_DIRS}) - set (LIBRARIES ${LIBRARIES} DBus) - set (SOURCES ${SOURCES} rpc_base_dbus_test.cc) -endif () - -create_test("rpc_base_test" "${SOURCES}" "${LIBRARIES}") - + list(APPEND LIBRARIES + DBus + ) +else() + set(EXCLUDE_PATHS + rpc_base_dbus_test.cc + ) endif() +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") +create_test(rpc_base_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/security_manager/CMakeLists.txt b/src/components/security_manager/CMakeLists.txt index 3cc6178931..bb50ad50c9 100644 --- a/src/components/security_manager/CMakeLists.txt +++ b/src/components/security_manager/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2015, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -27,7 +27,9 @@ # 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. - + + +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( include/ @@ -41,15 +43,22 @@ include_directories( ${APR_INCLUDE_DIRECTORY} ) -set (SOURCES - ${COMPONENTS_DIR}/security_manager/src/security_manager_impl.cc - ${COMPONENTS_DIR}/security_manager/src/security_query.cc - ${COMPONENTS_DIR}/security_manager/src/crypto_manager_impl.cc - ${COMPONENTS_DIR}/security_manager/src/ssl_context_impl.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) +collect_sources(SOURCES "${PATHS}") + +set(LIBRARIES + crypto + ssl + ProtocolHandler + jsoncpp + ProtocolLibrary ) add_library(SecurityManager ${SOURCES}) -target_link_libraries(SecurityManager crypto ssl ProtocolHandler jsoncpp ProtocolLibrary) +target_link_libraries(SecurityManager ${LIBRARIES}) if(BUILD_TESTS) add_subdirectory(test) diff --git a/src/components/security_manager/test/CMakeLists.txt b/src/components/security_manager/test/CMakeLists.txt index 6707e5ea5a..ba1fbcca8b 100644 --- a/src/components/security_manager/test/CMakeLists.txt +++ b/src/components/security_manager/test/CMakeLists.txt @@ -28,8 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if (BUILD_TESTS) - +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + include_directories( ${GMOCK_INCLUDE_DIRECTORY} ${COMPONENTS_DIR}/protocol_handler/test/include @@ -39,20 +39,15 @@ include_directories( ${JSONCPP_INCLUDE_DIRECTORY} ) -set(SOURCES - ${COMPONENTS_DIR}/security_manager/test/crypto_manager_impl_test.cc - ${COMPONENTS_DIR}/security_manager/test/security_manager_test.cc - ${COMPONENTS_DIR}/security_manager/test/security_query_test.cc - ${COMPONENTS_DIR}/security_manager/test/security_query_matcher.cc - ${COMPONENTS_DIR}/security_manager/test/ssl_context_test.cc - ${COMPONENTS_DIR}/security_manager/test/ssl_certificate_handshake_test.cc - ) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") set(LIBRARIES gmock ${SecurityManagerLibrary} ) +create_test (security_manager_test "${SOURCES}" "${LIBRARIES}") + set(CERT_LIST ${CMAKE_SOURCE_DIR}/mycert.pem ${CMAKE_SOURCE_DIR}/mykey.pem @@ -64,11 +59,8 @@ add_custom_target(generate_certificates WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) -foreach( file_i ${CERT_LIST}) - file(COPY ${file_i} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -endforeach( file_i ) +foreach(CERT_ENTRY ${CERT_LIST}) + file(COPY ${CERT_ENTRY} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +endforeach() -create_test (security_manager_test "${SOURCES}" "${LIBRARIES}") add_dependencies(security_manager_test generate_certificates) - -endif () diff --git a/src/components/smart_objects/CMakeLists.txt b/src/components/smart_objects/CMakeLists.txt index c1d599db67..339cf90ea4 100644 --- a/src/components/smart_objects/CMakeLists.txt +++ b/src/components/smart_objects/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,28 +28,19 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) -set(SMART_OBJECTS_SRC_DIR ${COMPONENTS_DIR}/smart_objects/src) - -include_directories ( - include - ${COMPONENTS_DIR}/utils/include/ +include_directories( + ${COMPONENTS_DIR}/include + ${COMPONENTS_DIR}/smart_objects/include + ${COMPONENTS_DIR}/utils/include ) -set (SOURCES - ${SMART_OBJECTS_SRC_DIR}/smart_object.cc - ${SMART_OBJECTS_SRC_DIR}/smart_schema.cc - ${SMART_OBJECTS_SRC_DIR}/schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/always_false_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/always_true_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/default_shema_item.cc - ${SMART_OBJECTS_SRC_DIR}/bool_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/number_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/enum_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/string_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/object_schema_item.cc - ${SMART_OBJECTS_SRC_DIR}/array_schema_item.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src ) +collect_sources(SOURCES "${PATHS}") add_library("SmartObjects" ${SOURCES}) @@ -60,4 +51,3 @@ endif() if(BUILD_TESTS) add_subdirectory(test) endif() - diff --git a/src/components/smart_objects/test/CMakeLists.txt b/src/components/smart_objects/test/CMakeLists.txt index e8bc20b6b8..e0cc37e104 100644 --- a/src/components/smart_objects/test/CMakeLists.txt +++ b/src/components/smart_objects/test/CMakeLists.txt @@ -28,8 +28,11 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) + if(BUILD_TESTS) -add_definitions(-DUNIT_TESTS) + add_definitions(-DUNIT_TESTS) +endif() include_directories ( ${GMOCK_INCLUDE_DIRECTORY} @@ -45,22 +48,10 @@ set(LIBRARIES jsoncpp ) -set(SOURCES - ${COMPONENTS_DIR}/smart_objects/test/SmartObjectDraft_test.cc - ${COMPONENTS_DIR}/smart_objects/test/SmartObjectInvalid_test.cc - ${COMPONENTS_DIR}/smart_objects/test/SmartObjectStress_test.cc - ${COMPONENTS_DIR}/smart_objects/test/SmartObjectUnit_test.cc - ${COMPONENTS_DIR}/smart_objects/test/smart_object_performance_test.cc - ${COMPONENTS_DIR}/smart_objects/test/map_performance_test.cc - ${COMPONENTS_DIR}/smart_objects/test/BoolSchemaItem_test.cc - ${COMPONENTS_DIR}/smart_objects/test/NumberSchemaItem_test.cc - ${COMPONENTS_DIR}/smart_objects/test/StringSchemaItem_test.cc - ${COMPONENTS_DIR}/smart_objects/test/ArraySchemaItem_test.cc - ${COMPONENTS_DIR}/smart_objects/test/CObjectSchemaItem_test.cc - ${COMPONENTS_DIR}/smart_objects/test/AlwaysTrueSchemaItem_test.cc - ${COMPONENTS_DIR}/smart_objects/test/AlwaysFalseSchemaItem_test.cc +set(EXCLUDE_PATHS + EnumSchemaItem_test.cc + SmartObjectConvertionTime_test.cc ) -create_test("smart_object_test" "${SOURCES}" "${LIBRARIES}") - -endif() +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") +create_test(smart_object_test "${SOURCES}" "${LIBRARIES}") diff --git a/src/components/telemetry_monitor/CMakeLists.txt b/src/components/telemetry_monitor/CMakeLists.txt index f3004dc61e..594b56abc5 100644 --- a/src/components/telemetry_monitor/CMakeLists.txt +++ b/src/components/telemetry_monitor/CMakeLists.txt @@ -28,8 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. - -set(TELEMETRY_MONITOR_SRC_DIR ${COMPONENTS_DIR}/telemetry_monitor/src) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include @@ -49,15 +48,15 @@ include_directories ( ${LOG4CXX_INCLUDE_DIRECTORY} ) -set(SOURCES - ${TELEMETRY_MONITOR_SRC_DIR}/metric_wrapper.cc - ${TELEMETRY_MONITOR_SRC_DIR}/telemetry_monitor.cc - ${TELEMETRY_MONITOR_SRC_DIR}/application_manager_observer.cc - ${TELEMETRY_MONITOR_SRC_DIR}/transport_manager_observer.cc - ${TELEMETRY_MONITOR_SRC_DIR}/protocol_handler_observer.cc - ${TELEMETRY_MONITOR_SRC_DIR}/application_manager_metric_wrapper.cc - ${TELEMETRY_MONITOR_SRC_DIR}/transport_manager_metric_wrapper.cc - ${TELEMETRY_MONITOR_SRC_DIR}/protocol_handler_metric_wrapper.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) +collect_sources(SOURCES "${PATHS}") + +set(LIBRARIES + HMI_API + MOBILE_API ) add_library("TelemetryMonitor" ${SOURCES}) diff --git a/src/components/telemetry_monitor/test/CMakeLists.txt b/src/components/telemetry_monitor/test/CMakeLists.txt index 7d2de19854..ea2698dfb2 100644 --- a/src/components/telemetry_monitor/test/CMakeLists.txt +++ b/src/components/telemetry_monitor/test/CMakeLists.txt @@ -28,7 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( include @@ -40,20 +40,10 @@ include_directories( ${COMPONENTS_DIR}/resumption/include ${JSONCPP_INCLUDE_DIRECTORY} ) - -set(testSources - metric_wrapper_test.cc - telemetry_monitor_test.cc - protocol_handler_metric_test.cc - protocol_handler_observer_test.cc - transport_manager_metric_test.cc - transport_manager_observer_test.cc - application_manager_metric_test.cc - application_manager_observer_test.cc -) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") -set(testLibraries +set(LIBRARIES gmock TelemetryMonitor jsoncpp @@ -68,7 +58,7 @@ set(testLibraries MessageHelper Resumption jsoncpp - transport_manager + TransportManager MediaManager ProtocolHandler connectionHandler @@ -82,8 +72,8 @@ if (BUILD_BT_SUPPORT) list(APPEND testLibraries bluetooth) endif() -file(COPY log4cxx.properties DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +create_test("telemetry_monitor_test" "${SOURCES}" "${LIBRARIES}") + +file(COPY ${COMPONENTS_DIR}/telemetry_monitor/test/log4cxx.properties DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -create_test("telemetry_monitor_test" "${testSources}" "${testLibraries}") -endif() diff --git a/src/components/transport_manager/CMakeLists.txt b/src/components/transport_manager/CMakeLists.txt index fbe6018d6a..5d70aca285 100644 --- a/src/components/transport_manager/CMakeLists.txt +++ b/src/components/transport_manager/CMakeLists.txt @@ -28,8 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -set(target TransportManager) -set(TM_SRC_DIR ${COMPONENTS_DIR}/transport_manager/src) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( include @@ -42,83 +42,63 @@ include_directories ( ${LIBUSB_INCLUDE_DIRECTORY} ${LOG4CXX_INCLUDE_DIRECTORY} ) -if (BUILD_BT_SUPPORT) - include_directories( - ) -endif() -set (SOURCES - ${TM_SRC_DIR}/transport_manager_impl.cc - ${TM_SRC_DIR}/transport_manager_default.cc - ${TM_SRC_DIR}/transport_adapter/transport_adapter_listener_impl.cc - ${TM_SRC_DIR}/transport_adapter/transport_adapter_impl.cc - ${TM_SRC_DIR}/tcp/tcp_transport_adapter.cc - ${TM_SRC_DIR}/transport_adapter/threaded_socket_connection.cc - ${TM_SRC_DIR}/tcp/tcp_client_listener.cc - ${TM_SRC_DIR}/tcp/tcp_device.cc - ${TM_SRC_DIR}/tcp/tcp_socket_connection.cc - ${TM_SRC_DIR}/tcp/tcp_connection_factory.cc +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +set(EXCLUDE_PATHS) + +set(LIBRARIES + ProtocolLibrary ) -if (BUILD_BT_SUPPORT) - list (APPEND SOURCES - ${TM_SRC_DIR}/bluetooth/bluetooth_device_scanner.cc - ${TM_SRC_DIR}/bluetooth/bluetooth_transport_adapter.cc - ${TM_SRC_DIR}/bluetooth/bluetooth_connection_factory.cc - ${TM_SRC_DIR}/bluetooth/bluetooth_socket_connection.cc - ${TM_SRC_DIR}/bluetooth/bluetooth_device.cc +if(BUILD_BT_SUPPORT) + list(APPEND LIBRARIES + bluetooth + ) +else() + list(APPEND EXCLUDE_PATHS + ${COMPONENTS_DIR}/transport_manager/include/transport_manager/bluetooth + ${COMPONENTS_DIR}/transport_manager/src/bluetooth ) endif() -if (BUILD_USB_SUPPORT) - list (APPEND SOURCES - ${TM_SRC_DIR}/usb/usb_aoa_adapter.cc - ${TM_SRC_DIR}/usb/usb_connection_factory.cc - ${TM_SRC_DIR}/usb/usb_device_scanner.cc - ) +if(BUILD_USB_SUPPORT) if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - list (APPEND SOURCES - ${TM_SRC_DIR}/usb/libusb/usb_handler.cc - ${TM_SRC_DIR}/usb/libusb/usb_connection.cc - ${TM_SRC_DIR}/usb/libusb/platform_usb_device.cc + set(EXCLUDE_PATHS + ${COMPONENTS_DIR}/transport_manager/include/transport_manager/usb/qnx + ${COMPONENTS_DIR}/transport_manager/src/usb/qnx + ) + list(APPEND LIBRARIES + Libusb-1.0.16 ) elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") - list(APPEND SOURCES - ${TM_SRC_DIR}/usb/qnx/usb_handler.cc - ${TM_SRC_DIR}/usb/qnx/usb_connection.cc - ${TM_SRC_DIR}/usb/qnx/platform_usb_device.cc + set(EXCLUDE_PATHS + ${COMPONENTS_DIR}/transport_manager/include/transport_manager/usb/libusb + ${COMPONENTS_DIR}/transport_manager/src/usb/libusb + ) + list(APPEND LIBRARIES + usbdi ) endif() -endif(BUILD_USB_SUPPORT) - - -if (CMAKE_SYSTEM_NAME STREQUAL "QNX") +else() + list(APPEND EXCLUDE_PATHS + ${COMPONENTS_DIR}/transport_manager/include/transport_manager/usb + ${COMPONENTS_DIR}/transport_manager/src/usb + ) endif() -add_library(${target} ${SOURCES}) -target_link_libraries(${target} ProtocolLibrary) +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") -if (BUILD_USB_SUPPORT) - if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - target_link_libraries(${target} usbdi) - endif() -endif(BUILD_USB_SUPPORT) +add_library("TransportManager" ${SOURCES}) +target_link_libraries("TransportManager" ${LIBRARIES}) if(ENABLE_LOG) - target_link_libraries(${target} log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) -endif() - -if (BUILD_BT_SUPPORT) - target_link_libraries(${target} bluetooth) + target_link_libraries("TransportManager" log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) endif() -if (CMAKE_SYSTEM_NAME STREQUAL "QNX") -endif() - -add_library("transport_manager" ${SOURCES} - ${TRANSPORT_MANAGER_SOURCES} -) - if(BUILD_TESTS) add_subdirectory(test) endif() diff --git a/src/components/transport_manager/test/CMakeLists.txt b/src/components/transport_manager/test/CMakeLists.txt index da20f1d43c..757d0b4a63 100644 --- a/src/components/transport_manager/test/CMakeLists.txt +++ b/src/components/transport_manager/test/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,8 +28,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) -set(TM_TEST_DIR ${COMPONENTS_DIR}/transport_manager/test) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( include @@ -42,10 +41,16 @@ include_directories( ${JSONCPP_INCLUDE_DIRECTORY} ) +set(EXCLUDE_PATHS + raw_message_matcher.cc +) + +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") + set(LIBRARIES gmock ConfigProfile - transport_manager + TransportManager Utils ConfigProfile ProtocolLibrary @@ -58,20 +63,12 @@ if (BUILD_USB_SUPPORT) endif() if (BUILD_BT_SUPPORT) + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") list(APPEND LIBRARIES bluetooth) + endif() endif() -set(SOURCES - ${TM_TEST_DIR}/transport_manager_impl_test.cc - ${TM_TEST_DIR}/transport_adapter_test.cc - ${TM_TEST_DIR}/transport_adapter_listener_test.cc - ${TM_TEST_DIR}/tcp_transport_adapter_test.cc - ${TM_TEST_DIR}/tcp_device_test.cc - ${TM_TEST_DIR}/tcp_client_listener_test.cc - ${TM_TEST_DIR}/transport_manager_default_test.cc -) - create_test("transport_manager_test" "${SOURCES}" "${LIBRARIES}") + file(COPY smartDeviceLink_test.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY app_info_storage2 DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -endif() diff --git a/src/components/transport_manager/test/raw_message_matcher.cc b/src/components/transport_manager/test/raw_message_matcher.cc index 130ddc96c8..ae43838be9 100644 --- a/src/components/transport_manager/test/raw_message_matcher.cc +++ b/src/components/transport_manager/test/raw_message_matcher.cc @@ -30,7 +30,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "include/raw_message_matcher.h" +#include "include/transport_manager/raw_message_matcher.h" //#include "../../include/protocol/raw_message.h" namespace test { diff --git a/src/components/utils/CMakeLists.txt b/src/components/utils/CMakeLists.txt index f72d43e546..93e11d745b 100644 --- a/src/components/utils/CMakeLists.txt +++ b/src/components/utils/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,62 +28,77 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) -set(UTILS_INCLUDE_DIR ${COMPONENTS_DIR}/utils/include) -set(UTILS_SRC_DIR ${COMPONENTS_DIR}/utils/src) +find_package(SDLSqlite3 REQUIRED) include_directories ( - ${UTILS_INCLUDE_DIR} + ${COMPONENTS_DIR}/utils/include ${COMPONENTS_DIR}/config_profile/include ${COMPONENTS_DIR}/media_manager/include ${COMPONENTS_DIR}/protocol_handler/include ${LOG4CXX_INCLUDE_DIRECTORY} ) -set (SOURCES - ${UTILS_SRC_DIR}/bitstream.cc - ${UTILS_SRC_DIR}/conditional_variable_posix.cc - ${UTILS_SRC_DIR}/file_system.cc - ${UTILS_SRC_DIR}/threads/posix_thread.cc - ${UTILS_SRC_DIR}/threads/thread_delegate.cc - ${UTILS_SRC_DIR}/threads/thread_validator.cc - ${UTILS_SRC_DIR}/threads/async_runner.cc - ${UTILS_SRC_DIR}/lock_posix.cc - ${UTILS_SRC_DIR}/rwlock_posix.cc - ${UTILS_SRC_DIR}/date_time.cc - ${UTILS_SRC_DIR}/signals_linux.cc - ${UTILS_SRC_DIR}/system.cc - ${UTILS_SRC_DIR}/resource_usage.cc - ${UTILS_SRC_DIR}/appenders_loader.cc - ${UTILS_SRC_DIR}/gen_hash.cc - ${UTILS_SRC_DIR}/convert_utils.cc - ${UTILS_SRC_DIR}/custom_string.cc - ${UTILS_SRC_DIR}/timer.cc +# dbms +set(DBMS_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/utils/sqlite_wrapper + ${CMAKE_CURRENT_SOURCE_DIR}/src/sqlite_wrapper + ${CMAKE_CURRENT_SOURCE_DIR}/include/utils/qdb_wrapper + ${CMAKE_CURRENT_SOURCE_DIR}/src/qdb_wrapper ) +set(EXCLUDE_PATHS + thread_manager.cc + pulse_thread_delegate.cc + ${DBMS_PATHS} +) + +set(LIBRARIES) + +if(NOT BUILD_BACKTRACE_SUPPORT) + list(APPEND EXCLUDE_PATHS + back_trace.cc + ) +endif() + if(ENABLE_LOG) - list(APPEND SOURCES - ${UTILS_SRC_DIR}/push_log.cc - ${UTILS_SRC_DIR}/log_message_loop_thread.cc - ${UTILS_SRC_DIR}/logger_status.cc - ${UTILS_SRC_DIR}/auto_trace.cc - ${UTILS_SRC_DIR}/logger.cc + list(APPEND LIBRARIES + log4cxx -L${LOG4CXX_LIBS_DIRECTORY} + apr-1 -L${APR_LIBS_DIRECTORY} + aprutil-1 -L${APR_UTIL_LIBS_DIRECTORY} + ConfigProfile + ) +else() + list(APPEND EXCLUDE_PATHS + push_log.cc + log_message_loop_thread.cc + logger_status.cc + auto_trace.cc + logger.cc ) endif() -if (BUILD_BACKTRACE_SUPPORT) - list(APPEND SOURCES - ${UTILS_SRC_DIR}/back_trace.cc - ) +if(NOT BUILD_BT_SUPPORT) + list(APPEND EXCLUDE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include/utils/bluetooth + ${CMAKE_CURRENT_SOURCE_DIR}/src/bluetooth + ) endif() -if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - list(APPEND SOURCES - ${UTILS_SRC_DIR}/threads/pulse_thread_delegate.cc +if (NOT CMAKE_SYSTEM_NAME STREQUAL "QNX") + list(APPEND EXCLUDE_PATHS + pulse_thread_delegate.cc ) endif() -add_library("Utils" ${SOURCES}) +set(PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +collect_sources(SOURCES "${PATHS}" "${EXCLUDE_PATHS}") if (CMAKE_SYSTEM_NAME STREQUAL "QNX") # --- QDB Wrapper @@ -94,26 +109,16 @@ else () endif () if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - list(APPEND LIBRARIES dl) + list(APPEND LIBRARIES dl pthread ${RTLIB}) endif() +add_library("Utils" ${SOURCES}) +target_link_libraries("Utils" ${LIBRARIES}) if(ENABLE_LOG) - list(APPEND LIBRARIES log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) - list(APPEND LIBRARIES apr-1 -L${APR_LIBS_DIRECTORY}) - list(APPEND LIBRARIES aprutil-1 -L${APR_UTIL_LIBS_DIRECTORY}) - list(APPEND LIBRARIES ConfigProfile) - - ADD_DEPENDENCIES(Utils install-3rd_party_logger) + add_dependencies("Utils" install-3rd_party_logger) endif() -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries("Utils" pthread ${RTLIB}) -endif() - -target_link_libraries("Utils" ${LIBRARIES}) - - if(BUILD_TESTS) add_subdirectory(test) endif() diff --git a/src/components/utils/src/qdb_wrapper/CMakeLists.txt b/src/components/utils/src/qdb_wrapper/CMakeLists.txt deleted file mode 100644 index c19321568e..0000000000 --- a/src/components/utils/src/qdb_wrapper/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -# Copyright (c) 2013, Ford Motor Company -# 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 name of the Ford Motor Company nor the names of its 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. - -set(target dbms) - -include_directories(${COMPONENTS_DIR}/utils/include/utils) - -set(SOURCES - ./sql_database.cc - ./sql_query.cc - ./sql_error.cc -) - -add_library(${target} ${SOURCES}) -target_link_libraries(${target} qdb Utils) - -if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/policy.ini DESTINATION ${CMAKE_BINARY_DIR}/src/appMain) - file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/qdbserver.sh DESTINATION ${CMAKE_BINARY_DIR}/src/appMain) -endif () - -if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - install(FILES policy.ini DESTINATION bin) - install(FILES qdbserver.sh DESTINATION bin - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ - GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) -endif () diff --git a/src/components/utils/src/signals_linux.cc b/src/components/utils/src/signals_linux.cc deleted file mode 100644 index 274c254716..0000000000 --- a/src/components/utils/src/signals_linux.cc +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2016, Ford Motor Company - * 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 name of the Ford Motor Company nor the names of its 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. - */ -#include -#include -#include - -#include "utils/signals.h" - -bool utils::UnsibscribeFromTermination() { - // Disable some system signals receiving in thread - // by blocking those signals - // (system signals processes only in the main thread) - // Mustn't block all signals! - // See "Advanced Programming in the UNIX Environment, 3rd Edition" - // (http://poincare.matf.bg.ac.rs/~ivana//courses/ps/sistemi_knjige/pomocno/apue.pdf, - // "12.8. Threads and Signals". - sigset_t signal_set; - sigemptyset(&signal_set); - sigaddset(&signal_set, SIGINT); - sigaddset(&signal_set, SIGTERM); - - return !pthread_sigmask(SIG_BLOCK, &signal_set, NULL); -} - -namespace { -bool CatchSIGSEGV(sighandler_t handler) { - struct sigaction act; - - act.sa_handler = handler; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; - - return !sigaction(SIGSEGV, &act, NULL); -} -} // namespace - -bool utils::WaitTerminationSignals(sighandler_t sig_handler) { - sigset_t signal_set; - int sig = -1; - - sigemptyset(&signal_set); - sigaddset(&signal_set, SIGINT); - sigaddset(&signal_set, SIGTERM); - - if (!CatchSIGSEGV(sig_handler)) { - return false; - } - - if (!sigwait(&signal_set, &sig)) { - sig_handler(sig); - return true; - } - return false; -} diff --git a/src/components/utils/src/signals_posix.cc b/src/components/utils/src/signals_posix.cc new file mode 100644 index 0000000000..274c254716 --- /dev/null +++ b/src/components/utils/src/signals_posix.cc @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, Ford Motor Company + * 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 name of the Ford Motor Company nor the names of its 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. + */ +#include +#include +#include + +#include "utils/signals.h" + +bool utils::UnsibscribeFromTermination() { + // Disable some system signals receiving in thread + // by blocking those signals + // (system signals processes only in the main thread) + // Mustn't block all signals! + // See "Advanced Programming in the UNIX Environment, 3rd Edition" + // (http://poincare.matf.bg.ac.rs/~ivana//courses/ps/sistemi_knjige/pomocno/apue.pdf, + // "12.8. Threads and Signals". + sigset_t signal_set; + sigemptyset(&signal_set); + sigaddset(&signal_set, SIGINT); + sigaddset(&signal_set, SIGTERM); + + return !pthread_sigmask(SIG_BLOCK, &signal_set, NULL); +} + +namespace { +bool CatchSIGSEGV(sighandler_t handler) { + struct sigaction act; + + act.sa_handler = handler; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + + return !sigaction(SIGSEGV, &act, NULL); +} +} // namespace + +bool utils::WaitTerminationSignals(sighandler_t sig_handler) { + sigset_t signal_set; + int sig = -1; + + sigemptyset(&signal_set); + sigaddset(&signal_set, SIGINT); + sigaddset(&signal_set, SIGTERM); + + if (!CatchSIGSEGV(sig_handler)) { + return false; + } + + if (!sigwait(&signal_set, &sig)) { + sig_handler(sig); + return true; + } + return false; +} diff --git a/src/components/utils/src/threads/posix_thread.cc b/src/components/utils/src/threads/posix_thread.cc deleted file mode 100644 index 51e59fa108..0000000000 --- a/src/components/utils/src/threads/posix_thread.cc +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Copyright (c) 2015, Ford Motor Company - * 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 name of the Ford Motor Company nor the names of its 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. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "utils/threads/thread.h" -#include "utils/atomic.h" -#include "utils/threads/thread_delegate.h" -#include "utils/logger.h" - -#ifndef __QNXNTO__ -const int EOK = 0; -#endif - -#if defined(OS_POSIX) -const size_t THREAD_NAME_SIZE = 15; -#endif - -namespace threads { - -CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") - -size_t Thread::kMinStackSize = - PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */ - -void Thread::cleanup(void* arg) { - LOG4CXX_AUTO_TRACE(logger_); - Thread* thread = reinterpret_cast(arg); - sync_primitives::AutoLock auto_lock(thread->state_lock_); - thread->isThreadRunning_ = false; - thread->state_cond_.Broadcast(); -} - -void* Thread::threadFunc(void* arg) { - // 0 - state_lock unlocked - // stopped = 0 - // running = 0 - // finalized = 0 - // 4 - state_lock unlocked - // stopped = 1 - // running = 1 - // finalized = 0 - // 5 - state_lock unlocked - // stopped = 1 - // running = 1 - // finalized = 1 - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - - threads::Thread* thread = reinterpret_cast(arg); - DCHECK(thread); - - pthread_cleanup_push(&cleanup, thread); - - thread->state_lock_.Acquire(); - thread->state_cond_.Broadcast(); - - while (!thread->finalized_) { - LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " iteration"); - thread->run_cond_.Wait(thread->state_lock_); - LOG4CXX_DEBUG(logger_, - "Thread #" << pthread_self() << " execute. " - << "stopped_ = " << thread->stopped_ - << "; finalized_ = " << thread->finalized_); - if (!thread->stopped_ && !thread->finalized_) { - thread->isThreadRunning_ = true; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - pthread_testcancel(); - - thread->state_lock_.Release(); - thread->delegate_->threadMain(); - thread->state_lock_.Acquire(); - - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - thread->isThreadRunning_ = false; - } - thread->state_cond_.Broadcast(); - LOG4CXX_DEBUG(logger_, - "Thread #" << pthread_self() << " finished iteration"); - } - - thread->state_lock_.Release(); - pthread_cleanup_pop(1); - - LOG4CXX_DEBUG(logger_, - "Thread #" << pthread_self() << " exited successfully"); - return NULL; -} - -void Thread::SetNameForId(const PlatformThreadHandle& thread_id, - std::string name) { - if (name.size() > THREAD_NAME_SIZE) - name.erase(THREAD_NAME_SIZE); - const int rc = pthread_setname_np(thread_id, name.c_str()); - if (rc != EOK) { - LOG4CXX_WARN(logger_, - "Couldn't set pthread name \"" << name << "\", error code " - << rc << " (" << strerror(rc) - << ")"); - } -} - -Thread::Thread(const char* name, ThreadDelegate* delegate) - : name_(name ? name : "undefined") - , delegate_(delegate) - , handle_(0) - , thread_options_() - , isThreadRunning_(0) - , stopped_(false) - , finalized_(false) - , thread_created_(false) {} - -bool Thread::start() { - return start(thread_options_); -} - -PlatformThreadHandle Thread::CurrentId() { - return pthread_self(); -} - -bool Thread::IsCurrentThread() const { - return pthread_equal(CurrentId(), thread_handle()); -} - -bool Thread::start(const ThreadOptions& options) { - LOG4CXX_AUTO_TRACE(logger_); - - sync_primitives::AutoLock auto_lock(state_lock_); - // 1 - state_lock locked - // stopped = 0 - // running = 0 - - if (!delegate_) { - LOG4CXX_ERROR(logger_, - "Cannot start thread " << name_ << ": delegate is NULL"); - // 0 - state_lock unlocked - return false; - } - - if (isThreadRunning_) { - LOG4CXX_TRACE(logger_, - "EXIT thread " << name_ << " #" << handle_ - << " is already running"); - return true; - } - - thread_options_ = options; - - pthread_attr_t attributes; - int pthread_result = pthread_attr_init(&attributes); - if (pthread_result != EOK) { - LOG4CXX_WARN(logger_, - "Couldn't init pthread attributes. Error code = " - << pthread_result << " (\"" << strerror(pthread_result) - << "\")"); - } - - if (!thread_options_.is_joinable()) { - pthread_result = - pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); - if (pthread_result != EOK) { - LOG4CXX_WARN(logger_, - "Couldn't set detach state attribute. Error code = " - << pthread_result << " (\"" << strerror(pthread_result) - << "\")"); - thread_options_.is_joinable(false); - } - } - - const size_t stack_size = thread_options_.stack_size(); - if (stack_size >= Thread::kMinStackSize) { - pthread_result = pthread_attr_setstacksize(&attributes, stack_size); - if (pthread_result != EOK) { - LOG4CXX_WARN(logger_, - "Couldn't set stacksize = " - << stack_size << ". Error code = " << pthread_result - << " (\"" << strerror(pthread_result) << "\")"); - } - } else { - ThreadOptions thread_options_temp(Thread::kMinStackSize, - thread_options_.is_joinable()); - thread_options_ = thread_options_temp; - } - - if (!thread_created_) { - // state_lock 1 - pthread_result = pthread_create(&handle_, &attributes, threadFunc, this); - if (pthread_result == EOK) { - LOG4CXX_DEBUG(logger_, "Created thread: " << name_); - SetNameForId(handle_, name_); - // state_lock 0 - // possible concurrencies: stop and threadFunc - state_cond_.Wait(auto_lock); - thread_created_ = true; - } else { - LOG4CXX_ERROR(logger_, - "Couldn't create thread " - << name_ << ". Error code = " << pthread_result - << " (\"" << strerror(pthread_result) << "\")"); - } - } - stopped_ = false; - run_cond_.NotifyOne(); - LOG4CXX_DEBUG(logger_, - "Thread " << name_ << " #" << handle_ << " started." - << " pthread_result = " << pthread_result); - pthread_attr_destroy(&attributes); - return pthread_result == EOK; -} - -void Thread::yield() { - sched_yield(); -} - -void Thread::stop() { - LOG4CXX_AUTO_TRACE(logger_); - sync_primitives::AutoLock auto_lock(state_lock_); - - stopped_ = true; - - LOG4CXX_DEBUG(logger_, - "Stopping thread #" << handle_ << " \"" << name_ << "\""); - - if (delegate_ && isThreadRunning_) { - delegate_->exitThreadMain(); - } - - LOG4CXX_DEBUG(logger_, - "Stopped thread #" << handle_ << " \"" << name_ << " \""); -} - -void Thread::join() { - LOG4CXX_AUTO_TRACE(logger_); - DCHECK_OR_RETURN_VOID(!IsCurrentThread()); - - stop(); - - sync_primitives::AutoLock auto_lock(state_lock_); - run_cond_.NotifyOne(); - if (isThreadRunning_) { - if (!pthread_equal(pthread_self(), handle_)) { - LOG4CXX_DEBUG(logger_, - "Waiting for #" << handle_ - << " finished iteration in thread #" - << pthread_self()); - state_cond_.Wait(auto_lock); - } - } -} - -Thread::~Thread() { - finalized_ = true; - stopped_ = true; - join(); - // in some platforms pthread_join behaviour is undefined when thread is - // not created(pthread_create) and call pthread_join. - if (handle_) { - pthread_join(handle_, NULL); - } -} - -Thread* CreateThread(const char* name, ThreadDelegate* delegate) { - Thread* thread = new Thread(name, delegate); - delegate->set_thread(thread); - return thread; -} - -void DeleteThread(Thread* thread) { - delete thread; -} - -} // namespace threads diff --git a/src/components/utils/src/threads/thread_posix.cc b/src/components/utils/src/threads/thread_posix.cc new file mode 100644 index 0000000000..51e59fa108 --- /dev/null +++ b/src/components/utils/src/threads/thread_posix.cc @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2015, Ford Motor Company + * 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 name of the Ford Motor Company nor the names of its 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "utils/threads/thread.h" +#include "utils/atomic.h" +#include "utils/threads/thread_delegate.h" +#include "utils/logger.h" + +#ifndef __QNXNTO__ +const int EOK = 0; +#endif + +#if defined(OS_POSIX) +const size_t THREAD_NAME_SIZE = 15; +#endif + +namespace threads { + +CREATE_LOGGERPTR_GLOBAL(logger_, "Utils") + +size_t Thread::kMinStackSize = + PTHREAD_STACK_MIN; /* Ubuntu : 16384 ; QNX : 256; */ + +void Thread::cleanup(void* arg) { + LOG4CXX_AUTO_TRACE(logger_); + Thread* thread = reinterpret_cast(arg); + sync_primitives::AutoLock auto_lock(thread->state_lock_); + thread->isThreadRunning_ = false; + thread->state_cond_.Broadcast(); +} + +void* Thread::threadFunc(void* arg) { + // 0 - state_lock unlocked + // stopped = 0 + // running = 0 + // finalized = 0 + // 4 - state_lock unlocked + // stopped = 1 + // running = 1 + // finalized = 0 + // 5 - state_lock unlocked + // stopped = 1 + // running = 1 + // finalized = 1 + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + + threads::Thread* thread = reinterpret_cast(arg); + DCHECK(thread); + + pthread_cleanup_push(&cleanup, thread); + + thread->state_lock_.Acquire(); + thread->state_cond_.Broadcast(); + + while (!thread->finalized_) { + LOG4CXX_DEBUG(logger_, "Thread #" << pthread_self() << " iteration"); + thread->run_cond_.Wait(thread->state_lock_); + LOG4CXX_DEBUG(logger_, + "Thread #" << pthread_self() << " execute. " + << "stopped_ = " << thread->stopped_ + << "; finalized_ = " << thread->finalized_); + if (!thread->stopped_ && !thread->finalized_) { + thread->isThreadRunning_ = true; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_testcancel(); + + thread->state_lock_.Release(); + thread->delegate_->threadMain(); + thread->state_lock_.Acquire(); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + thread->isThreadRunning_ = false; + } + thread->state_cond_.Broadcast(); + LOG4CXX_DEBUG(logger_, + "Thread #" << pthread_self() << " finished iteration"); + } + + thread->state_lock_.Release(); + pthread_cleanup_pop(1); + + LOG4CXX_DEBUG(logger_, + "Thread #" << pthread_self() << " exited successfully"); + return NULL; +} + +void Thread::SetNameForId(const PlatformThreadHandle& thread_id, + std::string name) { + if (name.size() > THREAD_NAME_SIZE) + name.erase(THREAD_NAME_SIZE); + const int rc = pthread_setname_np(thread_id, name.c_str()); + if (rc != EOK) { + LOG4CXX_WARN(logger_, + "Couldn't set pthread name \"" << name << "\", error code " + << rc << " (" << strerror(rc) + << ")"); + } +} + +Thread::Thread(const char* name, ThreadDelegate* delegate) + : name_(name ? name : "undefined") + , delegate_(delegate) + , handle_(0) + , thread_options_() + , isThreadRunning_(0) + , stopped_(false) + , finalized_(false) + , thread_created_(false) {} + +bool Thread::start() { + return start(thread_options_); +} + +PlatformThreadHandle Thread::CurrentId() { + return pthread_self(); +} + +bool Thread::IsCurrentThread() const { + return pthread_equal(CurrentId(), thread_handle()); +} + +bool Thread::start(const ThreadOptions& options) { + LOG4CXX_AUTO_TRACE(logger_); + + sync_primitives::AutoLock auto_lock(state_lock_); + // 1 - state_lock locked + // stopped = 0 + // running = 0 + + if (!delegate_) { + LOG4CXX_ERROR(logger_, + "Cannot start thread " << name_ << ": delegate is NULL"); + // 0 - state_lock unlocked + return false; + } + + if (isThreadRunning_) { + LOG4CXX_TRACE(logger_, + "EXIT thread " << name_ << " #" << handle_ + << " is already running"); + return true; + } + + thread_options_ = options; + + pthread_attr_t attributes; + int pthread_result = pthread_attr_init(&attributes); + if (pthread_result != EOK) { + LOG4CXX_WARN(logger_, + "Couldn't init pthread attributes. Error code = " + << pthread_result << " (\"" << strerror(pthread_result) + << "\")"); + } + + if (!thread_options_.is_joinable()) { + pthread_result = + pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); + if (pthread_result != EOK) { + LOG4CXX_WARN(logger_, + "Couldn't set detach state attribute. Error code = " + << pthread_result << " (\"" << strerror(pthread_result) + << "\")"); + thread_options_.is_joinable(false); + } + } + + const size_t stack_size = thread_options_.stack_size(); + if (stack_size >= Thread::kMinStackSize) { + pthread_result = pthread_attr_setstacksize(&attributes, stack_size); + if (pthread_result != EOK) { + LOG4CXX_WARN(logger_, + "Couldn't set stacksize = " + << stack_size << ". Error code = " << pthread_result + << " (\"" << strerror(pthread_result) << "\")"); + } + } else { + ThreadOptions thread_options_temp(Thread::kMinStackSize, + thread_options_.is_joinable()); + thread_options_ = thread_options_temp; + } + + if (!thread_created_) { + // state_lock 1 + pthread_result = pthread_create(&handle_, &attributes, threadFunc, this); + if (pthread_result == EOK) { + LOG4CXX_DEBUG(logger_, "Created thread: " << name_); + SetNameForId(handle_, name_); + // state_lock 0 + // possible concurrencies: stop and threadFunc + state_cond_.Wait(auto_lock); + thread_created_ = true; + } else { + LOG4CXX_ERROR(logger_, + "Couldn't create thread " + << name_ << ". Error code = " << pthread_result + << " (\"" << strerror(pthread_result) << "\")"); + } + } + stopped_ = false; + run_cond_.NotifyOne(); + LOG4CXX_DEBUG(logger_, + "Thread " << name_ << " #" << handle_ << " started." + << " pthread_result = " << pthread_result); + pthread_attr_destroy(&attributes); + return pthread_result == EOK; +} + +void Thread::yield() { + sched_yield(); +} + +void Thread::stop() { + LOG4CXX_AUTO_TRACE(logger_); + sync_primitives::AutoLock auto_lock(state_lock_); + + stopped_ = true; + + LOG4CXX_DEBUG(logger_, + "Stopping thread #" << handle_ << " \"" << name_ << "\""); + + if (delegate_ && isThreadRunning_) { + delegate_->exitThreadMain(); + } + + LOG4CXX_DEBUG(logger_, + "Stopped thread #" << handle_ << " \"" << name_ << " \""); +} + +void Thread::join() { + LOG4CXX_AUTO_TRACE(logger_); + DCHECK_OR_RETURN_VOID(!IsCurrentThread()); + + stop(); + + sync_primitives::AutoLock auto_lock(state_lock_); + run_cond_.NotifyOne(); + if (isThreadRunning_) { + if (!pthread_equal(pthread_self(), handle_)) { + LOG4CXX_DEBUG(logger_, + "Waiting for #" << handle_ + << " finished iteration in thread #" + << pthread_self()); + state_cond_.Wait(auto_lock); + } + } +} + +Thread::~Thread() { + finalized_ = true; + stopped_ = true; + join(); + // in some platforms pthread_join behaviour is undefined when thread is + // not created(pthread_create) and call pthread_join. + if (handle_) { + pthread_join(handle_, NULL); + } +} + +Thread* CreateThread(const char* name, ThreadDelegate* delegate) { + Thread* thread = new Thread(name, delegate); + delegate->set_thread(thread); + return thread; +} + +void DeleteThread(Thread* thread) { + delete thread; +} + +} // namespace threads diff --git a/src/components/utils/test/CMakeLists.txt b/src/components/utils/test/CMakeLists.txt index 6ec12a17e6..81e7d15bcb 100644 --- a/src/components/utils/test/CMakeLists.txt +++ b/src/components/utils/test/CMakeLists.txt @@ -28,7 +28,8 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories ( ${JSONCPP_INCLUDE_DIRECTORY} @@ -39,74 +40,61 @@ include_directories ( ${COMPONENTS_DIR}/policy/include ) -set(testSources - messagemeter_test.cc - file_system_test.cc - date_time_test.cc - system_test.cc - thread_validator_test.cc - conditional_variable_test.cc - message_queue_test.cc - resource_usage_test.cc - bitstream_test.cc - prioritized_queue_test.cc - data_accessor_test.cc - lock_posix_test.cc - singleton_test.cc - #posix_thread_test.cc - stl_utils_test.cc - rwlock_posix_test.cc - async_runner_test.cc - shared_ptr_test.cc - scope_guard_test.cc - atomic_object_test.cc - message_loop_thread_test.cc - custom_string_test.cc - timer_test.cc +set(EXCLUDE_PATHS + qdb_wrapper + test_generator ) -set(testLibraries - gmock - Utils - Policy - ConfigProfile -) +if(NOT ENABLE_LOG) + list(APPEND EXCLUDE_PATHS + auto_trace_test.cc + log_message_loop_thread_test.cc + ) +endif() + +if(NOT BUILD_BACKTRACE_SUPPORT) + list(APPEND EXCLUDE_PATHS + back_trace_test.cc + ) +endif() if (CMAKE_SYSTEM_NAME STREQUAL "QNX") - # --- Tests for QDB Wrapper - list (APPEND testSources - ./qdb_wrapper/sql_database_test.cc - ./qdb_wrapper/sql_query_test.cc + # exclude tests for SQLite wrapper + list (APPEND EXCLUDE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/sqlite_wrapper ) file(COPY qdbserver.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY test-qdb.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY policy.sql DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) else () - # --- Tests for SQLite Wrapper find_package(Sqlite3 REQUIRED) - list (APPEND testSources - ./sqlite_wrapper/sql_database_test.cc - ./sqlite_wrapper/sql_query_test.cc - generated_code_with_sqlite_test.cc + # exclude tests for QDB wrapper + list (APPEND EXCLUDE_PATHS + ${CMAKE_CURRENT_SOURCE_DIR}/qdb_wrapper ) list (APPEND testLibraries sqlite3) endif() -if (ENABLE_LOG) - list(APPEND testSources auto_trace_test.cc) - list(APPEND testSources log_message_loop_thread_test.cc) -endif() +# exclude some tests +list(APPEND EXCLUDE_PATHS + generated_code_with_sqlite_test.cc + posix_thread_test.cc + resource_usage_test.cc +) -if (BUILD_BACKTRACE_SUPPORT) - list(APPEND testSources back_trace_test.cc) -endif() +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}" "${EXCLUDE_PATHS}") + +set(LIBRARIES + gmock + Utils + Policy + ConfigProfile +) + +create_test(utils_test "${SOURCES}" "${LIBRARIES}") file(COPY testscript.sh DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY log4cxx.properties DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) file(COPY smartDeviceLink.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -create_test("utils_test" "${testSources}" "${testLibraries}") - add_subdirectory(test_generator) - -endif() diff --git a/src/components/utils/test/test_generator/CMakeLists.txt b/src/components/utils/test/test_generator/CMakeLists.txt index d649f927a5..5a7f939659 100644 --- a/src/components/utils/test/test_generator/CMakeLists.txt +++ b/src/components/utils/test/test_generator/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2015, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,38 +28,35 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTS) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/generators.cmake) include_directories ( - ${JSONCPP_INCLUDE_DIRECTORY} - ${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/include - ${CMAKE_SOURCE_DIR}/src/3rd_party-static/gmock-1.7.0/gtest/include ${CMAKE_SOURCE_DIR}/tools/interfaceGenerator ${CMAKE_CURRENT_BINARY_DIR} ${COMPONENTS_DIR}/utils/include/utils ${COMPONENTS_DIR}/include/utils + ${JSONCPP_INCLUDE_DIRECTORY} + ${GMOCK_INCLUDE_DIRECTORY} ) -set(full_xml_name "${CMAKE_SOURCE_DIR}/src/components/interfaces/MOBILE_API.xml") - -add_custom_target( generate_version - COMMAND ${INTEFRACE_GENERATOR_CMD} ${full_xml_name} "mobile_apis" - ${CMAKE_CURRENT_BINARY_DIR} "--parser-type" "sdlrpcv2" - DEPENDS ${INTERFACE_GENERATOR_DEPENDENCIES} ${full_xml_name} - VERBATIM - ) +set(XML_NAME ${CMAKE_SOURCE_DIR}/src/components/interfaces/MOBILE_API.xml) +add_custom_target(generate_version + COMMAND ${INTEFRACE_GENERATOR_CMD} ${XML_NAME} "mobile_apis" + ${CMAKE_CURRENT_BINARY_DIR} "--parser-type" "sdlrpcv2" + DEPENDS ${INTERFACE_GENERATOR_DEPENDENCIES} ${XML_NAME} + VERBATIM +) -set(testLibraries +set(LIBRARIES gmock Utils ) -set(testSources +set(SOURCES generated_msg_version_test.cc ) -file(COPY ${full_xml_name} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -create_test("generator_test" "${testSources}" "${testLibraries}") -add_dependencies("generator_test" generate_version) +create_test(generator_test "${SOURCES}" "${LIBRARIES}") +file(COPY ${XML_NAME} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -endif() +add_dependencies("generator_test" generate_version) diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 1a4eff13b5..4b6f6d8dfa 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -29,5 +29,5 @@ # POSSIBILITY OF SUCH DAMAGE. if(ENABLE_LOG) -add_subdirectory(appenders) + add_subdirectory(appenders) endif() diff --git a/src/plugins/appenders/CMakeLists.txt b/src/plugins/appenders/CMakeLists.txt index 9d01599ca3..59628a021b 100644 --- a/src/plugins/appenders/CMakeLists.txt +++ b/src/plugins/appenders/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Ford Motor Company +# Copyright (c) 2016, Ford Motor Company # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -28,22 +28,22 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -SET(target "appenders") - -SET(SOURCES - safe_file_appender.cc - safe_rolling_file_appender.cc -) +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/sources.cmake) include_directories( ${LOG4CXX_INCLUDE_DIRECTORY} ) -add_library(${target} MODULE ${SOURCES}) +collect_sources(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}") + +set(LIBRARIES + log4cxx -L${LOG4CXX_LIBS_DIRECTORY} +) -target_link_libraries(${target} log4cxx -L${LOG4CXX_LIBS_DIRECTORY}) +add_library(appenders ${SOURCES}) +target_link_libraries(appenders ${LIBRARIES}) -install(TARGETS ${target} +install(TARGETS appenders DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE diff --git a/tools/cmake/helpers/cotire.cmake b/tools/cmake/helpers/cotire.cmake new file mode 100644 index 0000000000..741d6901f1 --- /dev/null +++ b/tools/cmake/helpers/cotire.cmake @@ -0,0 +1,3917 @@ +# - cotire (compile time reducer) +# +# See the cotire manual for usage hints. +# +#============================================================================= +# Copyright 2012-2016 Sascha Kratky +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +#============================================================================= + +if(__COTIRE_INCLUDED) + return() +endif() +set(__COTIRE_INCLUDED TRUE) + +# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode +# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(PUSH) +endif() +cmake_minimum_required(VERSION 2.8.12) +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(POP) +endif() + +set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") +set (COTIRE_CMAKE_MODULE_VERSION "1.7.8") + +# activate select policies +if (POLICY CMP0025) + # Compiler id for Apple Clang is now AppleClang + cmake_policy(SET CMP0025 NEW) +endif() + +if (POLICY CMP0026) + # disallow use of the LOCATION target property + cmake_policy(SET CMP0026 NEW) +endif() + +if (POLICY CMP0038) + # targets may not link directly to themselves + cmake_policy(SET CMP0038 NEW) +endif() + +if (POLICY CMP0039) + # utility targets may not have link dependencies + cmake_policy(SET CMP0039 NEW) +endif() + +if (POLICY CMP0040) + # target in the TARGET signature of add_custom_command() must exist + cmake_policy(SET CMP0040 NEW) +endif() + +if (POLICY CMP0045) + # error on non-existent target in get_target_property + cmake_policy(SET CMP0045 NEW) +endif() + +if (POLICY CMP0046) + # error on non-existent dependency in add_dependencies + cmake_policy(SET CMP0046 NEW) +endif() + +if (POLICY CMP0049) + # do not expand variables in target source entries + cmake_policy(SET CMP0049 NEW) +endif() + +if (POLICY CMP0050) + # disallow add_custom_command SOURCE signatures + cmake_policy(SET CMP0050 NEW) +endif() + +if (POLICY CMP0051) + # include TARGET_OBJECTS expressions in a target's SOURCES property + cmake_policy(SET CMP0051 NEW) +endif() + +if (POLICY CMP0053) + # simplify variable reference and escape sequence evaluation + cmake_policy(SET CMP0053 NEW) +endif() + +if (POLICY CMP0054) + # only interpret if() arguments as variables or keywords when unquoted + cmake_policy(SET CMP0054 NEW) +endif() + +include(CMakeParseArguments) +include(ProcessorCount) + +function (cotire_get_configuration_types _configsVar) + set (_configs "") + if (CMAKE_CONFIGURATION_TYPES) + list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) + endif() + if (CMAKE_BUILD_TYPE) + list (APPEND _configs "${CMAKE_BUILD_TYPE}") + endif() + if (_configs) + list (REMOVE_DUPLICATES _configs) + set (${_configsVar} ${_configs} PARENT_SCOPE) + else() + set (${_configsVar} "None" PARENT_SCOPE) + endif() +endfunction() + +function (cotire_get_source_file_extension _sourceFile _extVar) + # get_filename_component returns extension from first occurrence of . in file name + # this function computes the extension from last occurrence of . in file name + string (FIND "${_sourceFile}" "." _index REVERSE) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) + else() + set (_sourceExt "") + endif() + set (${_extVar} "${_sourceExt}" PARENT_SCOPE) +endfunction() + +macro (cotire_check_is_path_relative_to _path _isRelativeVar) + set (${_isRelativeVar} FALSE) + if (IS_ABSOLUTE "${_path}") + foreach (_dir ${ARGN}) + file (RELATIVE_PATH _relPath "${_dir}" "${_path}") + if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) + set (${_isRelativeVar} TRUE) + break() + endif() + endforeach() + endif() +endmacro() + +function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) + if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") + else() + set (_languageExtensions "") + endif() + if (CMAKE_${_language}_IGNORE_EXTENSIONS) + set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") + else() + set (_ignoreExtensions "") + endif() + if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) + set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") + else() + set (_excludeExtensions "") + endif() + if (COTIRE_DEBUG AND _languageExtensions) + message (STATUS "${_language} source file extensions: ${_languageExtensions}") + endif() + if (COTIRE_DEBUG AND _ignoreExtensions) + message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") + endif() + if (COTIRE_DEBUG AND _excludeExtensions) + message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") + endif() + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_allSourceFiles ${ARGN}) + else() + # as of CMake 3.1 target sources may contain generator expressions + # since we cannot obtain required property information about source files added + # through generator expressions at configure time, we filter them out + string (GENEX_STRIP "${ARGN}" _allSourceFiles) + endif() + set (_filteredSourceFiles "") + set (_excludedSourceFiles "") + foreach (_sourceFile ${_allSourceFiles}) + get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) + get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) + get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) + if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) + cotire_get_source_file_extension("${_sourceFile}" _sourceExt) + if (_sourceExt) + list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) + if (_ignoreIndex LESS 0) + list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) + if (_excludeIndex GREATER -1) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) + if (_sourceIndex GREATER -1) + # consider source file unless it is excluded explicitly + get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) + if (_sourceIsExcluded) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _filteredSourceFiles "${_sourceFile}") + endif() + else() + get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) + if ("${_sourceLanguage}" STREQUAL "${_language}") + # add to excluded sources, if file is not ignored and has correct language without having the correct extension + list (APPEND _excludedSourceFiles "${_sourceFile}") + endif() + endif() + endif() + endif() + endif() + endif() + endforeach() + # separate filtered source files from already cotired ones + # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire + set (_sourceFiles "") + set (_cotiredSourceFiles "") + foreach (_sourceFile ${_filteredSourceFiles}) + get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + if (_sourceIsCotired) + list (APPEND _cotiredSourceFiles "${_sourceFile}") + else() + get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) + if (_sourceCompileFlags) + # add to excluded sources, if file has custom compile flags + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _sourceFiles "${_sourceFile}") + endif() + endif() + endforeach() + if (COTIRE_DEBUG) + if (_sourceFiles) + message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}") + endif() + if (_excludedSourceFiles) + message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}") + endif() + if (_cotiredSourceFiles) + message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}") + endif() + endif() + set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) + set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) + set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (NOT _propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_file_property_values _valuesVar _property) + set (_values "") + foreach (_sourceFile ${ARGN}) + get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) + if (_propertyValue) + list (APPEND _values "${_propertyValue}") + endif() + endforeach() + set (${_valuesVar} ${_values} PARENT_SCOPE) +endfunction() + +function (cotire_resolve_config_properites _configurations _propertiesVar) + set (_properties "") + foreach (_property ${ARGN}) + if ("${_property}" MATCHES "") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + string (REPLACE "" "${_upperConfig}" _configProperty "${_property}") + list (APPEND _properties ${_configProperty}) + endforeach() + else() + list (APPEND _properties ${_property}) + endif() + endforeach() + set (${_propertiesVar} ${_properties} PARENT_SCOPE) +endfunction() + +function (cotire_copy_set_properites _configurations _type _source _target) + cotire_resolve_config_properites("${_configurations}" _properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) + set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") + endif() + endforeach() +endfunction() + +function (cotire_get_target_usage_requirements _target _targetRequirementsVar) + set (_targetRequirements "") + get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) + while (_librariesToProcess) + # remove from head + list (GET _librariesToProcess 0 _library) + list (REMOVE_AT _librariesToProcess 0) + if (TARGET ${_library}) + list (FIND _targetRequirements ${_library} _index) + if (_index LESS 0) + list (APPEND _targetRequirements ${_library}) + # BFS traversal of transitive libraries + get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) + if (_libraries) + list (APPEND _librariesToProcess ${_libraries}) + list (REMOVE_DUPLICATES _librariesToProcess) + endif() + endif() + endif() + endwhile() + set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE) +endfunction() + +function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + set (_flagPrefix "[/-]") + else() + set (_flagPrefix "--?") + endif() + set (_optionFlag "") + set (_matchedOptions "") + set (_unmatchedOptions "") + foreach (_compileFlag ${ARGN}) + if (_compileFlag) + if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") + # option with separate argument + list (APPEND _matchedOptions "${_compileFlag}") + set (_optionFlag "") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") + # remember option + set (_optionFlag "${CMAKE_MATCH_2}") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") + # option with joined argument + list (APPEND _matchedOptions "${CMAKE_MATCH_3}") + set (_optionFlag "") + else() + # flush remembered option + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + set (_optionFlag "") + endif() + # add to unfiltered options + list (APPEND _unmatchedOptions "${_compileFlag}") + endif() + endif() + endforeach() + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + endif() + if (COTIRE_DEBUG AND _matchedOptions) + message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}") + endif() + if (COTIRE_DEBUG AND _unmatchedOptions) + message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}") + endif() + set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) + set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) +endfunction() + +function (cotire_is_target_supported _target _isSupportedVar) + if (NOT TARGET "${_target}") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_imported ${_target} IMPORTED) + if (_imported) + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_targetType ${_target} TYPE) + if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + set (${_isSupportedVar} TRUE PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_flags _config _language _target _flagsVar) + string (TOUPPER "${_config}" _upperConfig) + # collect options from CMake language variables + set (_compileFlags "") + if (CMAKE_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") + endif() + if (CMAKE_${_language}_FLAGS_${_upperConfig}) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") + endif() + if (_target) + # add target compile flags + get_target_property(_targetflags ${_target} COMPILE_FLAGS) + if (_targetflags) + set (_compileFlags "${_compileFlags} ${_targetflags}") + endif() + endif() + if (UNIX) + separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") + elseif(WIN32) + separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") + else() + separate_arguments(_compileFlags) + endif() + # target compile options + if (_target) + get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endif() + # interface compile options from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endforeach() + endif() + # handle language standard properties + if (_target) + get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD) + get_target_property(_targetLanguageExtensions ${_target} ${_language}_EXTENSIONS) + get_target_property(_targetLanguageStandardRequired ${_target} ${_language}_STANDARD_REQUIRED) + if (_targetLanguageExtensions) + if (CMAKE_${_language}${_targetLanguageExtensions}_EXTENSION_COMPILE_OPTION) + list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageExtensions}_EXTENSION_COMPILE_OPTION}") + endif() + elseif (_targetLanguageStandard) + if (_targetLanguageStandardRequired) + if (CMAKE_${_language}${_targetLanguageStandard}_STANDARD_COMPILE_OPTION) + list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_STANDARD_COMPILE_OPTION}") + endif() + else() + if (CMAKE_${_language}${_targetLanguageStandard}_EXTENSION_COMPILE_OPTION) + list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_EXTENSION_COMPILE_OPTION}") + endif() + endif() + endif() + endif() + # handle the POSITION_INDEPENDENT_CODE target property + if (_target) + get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) + if (_targetPIC) + get_target_property(_targetType ${_target} TYPE) + if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") + elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") + endif() + endif() + endif() + # handle visibility target properties + if (_target) + get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET) + if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}") + endif() + get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN) + if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}") + endif() + endif() + # platform specific flags + if (APPLE) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) + if (NOT _architectures) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES) + endif() + if (_architectures) + foreach (_arch ${_architectures}) + list (APPEND _compileFlags "-arch" "${_arch}") + endforeach() + endif() + if (CMAKE_OSX_SYSROOT) + if (CMAKE_${_language}_SYSROOT_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") + else() + list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") + endif() + endif() + if (CMAKE_OSX_DEPLOYMENT_TARGET) + if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + else() + list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() + endif() + endif() + if (COTIRE_DEBUG AND _compileFlags) + message (STATUS "Target ${_target} compile flags: ${_compileFlags}") + endif() + set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar) + set (_includeDirs "") + set (_systemIncludeDirs "") + # default include dirs + if (CMAKE_INCLUDE_CURRENT_DIR) + list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}") + list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + # parse additional include directories from target compile flags + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _includeDirs ${_dirs}) + endif() + endif() + endif() + # parse additional system include directories from target compile flags + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _systemIncludeDirs ${_dirs}) + endif() + endif() + endif() + # target include directories + get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES) + if (_target) + get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endif() + # interface include directories from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_linkedTargetType ${_linkedTarget} TYPE) + if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND + _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR + # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR + # which are only available with CMake 3.4 or later. + get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endforeach() + endif() + if (dirs) + list (REMOVE_DUPLICATES _dirs) + endif() + list (LENGTH _includeDirs _projectInsertIndex) + foreach (_dir ${_dirs}) + if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) + cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") + if (_isRelative) + list (LENGTH _includeDirs _len) + if (_len EQUAL _projectInsertIndex) + list (APPEND _includeDirs "${_dir}") + else() + list (INSERT _includeDirs _projectInsertIndex "${_dir}") + endif() + math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") + else() + list (APPEND _includeDirs "${_dir}") + endif() + else() + list (APPEND _includeDirs "${_dir}") + endif() + endforeach() + list (REMOVE_DUPLICATES _includeDirs) + list (REMOVE_DUPLICATES _systemIncludeDirs) + if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) + list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) + endif() + if (COTIRE_DEBUG AND _includeDirs) + message (STATUS "Target ${_target} include dirs: ${_includeDirs}") + endif() + set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) + if (COTIRE_DEBUG AND _systemIncludeDirs) + message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}") + endif() + set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_export_symbol _target _exportSymbolVar) + set (_exportSymbol "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_enableExports ${_target} ENABLE_EXPORTS) + if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR + (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) + get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) + if (NOT _exportSymbol) + set (_exportSymbol "${_target}_EXPORTS") + endif() + string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol) + endif() + set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_definitions _config _language _target _definitionsVar) + string (TOUPPER "${_config}" _upperConfig) + set (_configDefinitions "") + # CMAKE_INTDIR for multi-configuration build systems + if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") + endif() + # target export define symbol + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + list (APPEND _configDefinitions "${_defineSymbol}") + endif() + # directory compile definitions + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # target compile definitions + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # interface compile definitions from linked library targets + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + endforeach() + # parse additional compile definitions from target compile flags + # and don't look at directory compile definitions, which we already handled + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + list (REMOVE_DUPLICATES _configDefinitions) + if (COTIRE_DEBUG AND _configDefinitions) + message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}") + endif() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar) + # parse target compile flags omitting compile definitions and include directives + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + set (_flagFilter "D") + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + set (_compilerFlags "") + cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags}) + if (COTIRE_DEBUG AND _compilerFlags) + message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}") + endif() + set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) +endfunction() + +function (cotire_add_sys_root_paths _pathsVar) + if (APPLE) + if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) + foreach (_path IN LISTS ${_pathsVar}) + if (IS_ABSOLUTE "${_path}") + get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) + if (EXISTS "${_path}") + list (APPEND ${_pathsVar} "${_path}") + endif() + endif() + endforeach() + endif() + endif() + set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) + set (_extraProperties ${ARGN}) + set (_result "") + if (_extraProperties) + list (FIND _extraProperties "${_sourceFile}" _index) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + list (LENGTH _extraProperties _len) + math (EXPR _len "${_len} - 1") + foreach (_index RANGE ${_index} ${_len}) + list (GET _extraProperties ${_index} _value) + if (_value MATCHES "${_pattern}") + list (APPEND _result "${_value}") + else() + break() + endif() + endforeach() + endif() + endif() + set (${_resultVar} ${_result} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) + set (_compileDefinitions "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + string (TOUPPER "${_config}" _upperConfig) + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + if (COTIRE_DEBUG AND _compileDefinitions) + message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}") + endif() + set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) + set (_configDefinitions "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) + if (_sourceDefinitions) + list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") + endif() + endforeach() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) + set (_sourceUndefs "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + get_source_file_property(_undefs "${_sourceFile}" ${_property}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + if (COTIRE_DEBUG AND _sourceUndefs) + message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}") + endif() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_undefs _property _sourceUndefsVar) + set (_sourceUndefs "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) + if (_undefs) + list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") + endif() + endforeach() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +macro (cotire_set_cmd_to_prologue _cmdVar) + set (${_cmdVar} "${CMAKE_COMMAND}") + if (COTIRE_DEBUG) + list (APPEND ${_cmdVar} "--warn-uninitialized") + endif() + list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") + if (COTIRE_VERBOSE) + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") + elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") + endif() +endmacro() + +function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1) + if (NOT _compilerLauncher) + set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER}) + endif() + if (NOT _compilerExe) + set (_compilerExe "${CMAKE_${_language}_COMPILER}") + endif() + if (NOT _compilerArg1) + set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) + endif() + string (STRIP "${_compilerArg1}" _compilerArg1) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # compiler launcher is only supported for Makefile and Ninja + set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + else() + set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_add_definitions_to_cmd _cmdVar _language) + foreach (_definition ${ARGN}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + list (APPEND ${_cmdVar} "/D${_definition}") + else() + list (APPEND ${_cmdVar} "-D${_definition}") + endif() + endforeach() +endmacro() + +function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}}) + if (_includeDirs) + list (REMOVE_DUPLICATES _includeDirs) + foreach (_include ${_includeDirs}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + file (TO_NATIVE_PATH "${_include}" _include) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_${_language}_SEP}${_include}") + else() + set (_index -1) + if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+") + list (FIND ${_systemIncludesVar} "${_include}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${_include}") + else() + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_${_language}_SEP}${_include}") + endif() + endif() + endforeach() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() + +function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + if (APPLE) + set (_frameworkDirs "") + foreach (_include ${${_includesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _frameworkDirs "${_frameworkDir}") + endif() + endforeach() + set (_systemFrameworkDirs "") + foreach (_include ${${_systemIncludesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _systemFrameworkDirs "${_frameworkDir}") + endif() + endforeach() + if (_systemFrameworkDirs) + list (APPEND _frameworkDirs ${_systemFrameworkDirs}) + endif() + if (_frameworkDirs) + list (REMOVE_DUPLICATES _frameworkDirs) + foreach (_frameworkDir ${_frameworkDirs}) + set (_index -1) + if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+") + list (FIND _systemFrameworkDirs "${_frameworkDir}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + else() + list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + endif() + endforeach() + endif() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() + +macro (cotire_add_compile_flags_to_cmd _cmdVar) + foreach (_flag ${ARGN}) + list (APPEND ${_cmdVar} "${_flag}") + endforeach() +endmacro() + +function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) + if (EXISTS "${_file}") + set (_triggerFile "") + foreach (_dependencyFile ${ARGN}) + if (EXISTS "${_dependencyFile}") + # IS_NEWER_THAN returns TRUE if both files have the same timestamp + # thus we do the comparison in both directions to exclude ties + if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND + NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}") + set (_triggerFile "${_dependencyFile}") + break() + endif() + endif() + endforeach() + if (_triggerFile) + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") + endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + else() + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} is up-to-date.") + endif() + set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) + endif() + else() + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} does not exist yet.") + endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) + set (${_relPathVar} "") + foreach (_includeDir ${_includeDirs}) + if (IS_DIRECTORY "${_includeDir}") + file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") + if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") + string (LENGTH "${${_relPathVar}}" _closestLen) + string (LENGTH "${_relPath}" _relLen) + if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) + set (${_relPathVar} "${_relPath}") + endif() + endif() + elseif ("${_includeDir}" STREQUAL "${_headerFile}") + # if path matches exactly, return short non-empty string + set (${_relPathVar} "1") + break() + endif() + endforeach() +endmacro() + +macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside) + # check header path against ignored and honored include directories + cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath) + if (_insideRelPath) + # header is inside, but could be become outside if there is a shorter outside match + cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath) + if (_outsideRelPath) + string (LENGTH "${_insideRelPath}" _insideRelPathLen) + string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) + if (_outsideRelPathLen LESS _insideRelPathLen) + set (${_headerIsInside} FALSE) + else() + set (${_headerIsInside} TRUE) + endif() + else() + set (${_headerIsInside} TRUE) + endif() + else() + # header is outside + set (${_headerIsInside} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) + if (NOT EXISTS "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif (IS_DIRECTORY "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") + # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path + # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation + # with the error message "error: no include path in which to search for header.h" + set (${_headerIsIgnoredVar} TRUE) + else() + set (${_headerIsIgnoredVar} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) + # check header file extension + cotire_get_source_file_extension("${_headerFile}" _headerFileExt) + set (${_headerIsIgnoredVar} FALSE) + if (_headerFileExt) + list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) + if (_index GREATER -1) + set (${_headerIsIgnoredVar} TRUE) + endif() + endif() +endmacro() + +macro (cotire_parse_line _line _headerFileVar _headerDepthVar) + if (MSVC) + # cl.exe /showIncludes output looks different depending on the language pack used, e.g.: + # English: "Note: including file: C:\directory\file" + # German: "Hinweis: Einlesen der Datei: C:\directory\file" + # We use a very general regular expression, relying on the presence of the : characters + if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") + # Visual Studio compiler output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + else() + if (_line MATCHES "^(\\.+) (.*)$") + # GCC like output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + if (IS_ABSOLUTE "${CMAKE_MATCH_2}") + set (${_headerFileVar} "${CMAKE_MATCH_2}") + else() + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) + endif() + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + endif() +endmacro() + +function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) + if (WIN32) + # prevent CMake macro invocation errors due to backslash characters in Windows paths + string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") + endif() + # canonize slashes + string (REPLACE "//" "/" _scanOutput "${_scanOutput}") + # prevent semicolon from being interpreted as a line separator + string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") + # then separate lines + string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") + list (LENGTH _scanOutput _len) + # remove duplicate lines to speed up parsing + list (REMOVE_DUPLICATES _scanOutput) + list (LENGTH _scanOutput _uniqueLen) + if (COTIRE_VERBOSE OR COTIRE_DEBUG) + message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") + if (_ignoredExtensions) + message (STATUS "Ignored extensions: ${_ignoredExtensions}") + endif() + if (_ignoredIncludeDirs) + message (STATUS "Ignored paths: ${_ignoredIncludeDirs}") + endif() + if (_honoredIncludeDirs) + message (STATUS "Included paths: ${_honoredIncludeDirs}") + endif() + endif() + set (_sourceFiles ${ARGN}) + set (_selectedIncludes "") + set (_unparsedLines "") + # stack keeps track of inside/outside project status of processed header files + set (_headerIsInsideStack "") + foreach (_line IN LISTS _scanOutput) + if (_line) + cotire_parse_line("${_line}" _headerFile _headerDepth) + if (_headerFile) + cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside) + if (COTIRE_DEBUG) + message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") + endif() + # update stack + list (LENGTH _headerIsInsideStack _stackLen) + if (_headerDepth GREATER _stackLen) + math (EXPR _stackLen "${_stackLen} + 1") + foreach (_index RANGE ${_stackLen} ${_headerDepth}) + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endforeach() + else() + foreach (_index RANGE ${_headerDepth} ${_stackLen}) + list (REMOVE_AT _headerIsInsideStack -1) + endforeach() + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerIsInsideStack}") + endif() + # header is a candidate if it is outside project + if (NOT _headerIsInside) + # get parent header file's inside/outside status + if (_headerDepth GREATER 1) + math (EXPR _index "${_headerDepth} - 2") + list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) + else() + set (_parentHeaderIsInside TRUE) + endif() + # select header file if parent header file is inside project + # (e.g., a project header file that includes a standard header file) + if (_parentHeaderIsInside) + cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) + if (NOT _headerIsIgnored) + cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) + if (NOT _headerIsIgnored) + list (APPEND _selectedIncludes "${_headerFile}") + else() + # fix header's inside status on stack, it is ignored by extension now + list (REMOVE_AT _headerIsInsideStack -1) + list (APPEND _headerIsInsideStack TRUE) + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") + endif() + endif() + endif() + else() + if (MSVC) + # for cl.exe do not keep unparsed lines which solely consist of a source file name + string (FIND "${_sourceFiles}" "${_line}" _index) + if (_index LESS 0) + list (APPEND _unparsedLines "${_line}") + endif() + else() + list (APPEND _unparsedLines "${_line}") + endif() + endif() + endif() + endforeach() + list (REMOVE_DUPLICATES _selectedIncludes) + set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) + set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) +endfunction() + +function (cotire_scan_includes _includesVar) + set(_options "") + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES + IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) + # only consider existing source files for scanning + set (_existingSourceFiles "") + foreach (_sourceFile ${_sourceFiles}) + if (EXISTS "${_sourceFile}") + list (APPEND _existingSourceFiles "${_sourceFile}") + endif() + endforeach() + if (NOT _existingSourceFiles) + set (${_includesVar} "" PARENT_SCOPE) + return() + endif() + list (APPEND _cmd ${_existingSourceFiles}) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result + OUTPUT_QUIET + ERROR_VARIABLE _output) + if (_result) + message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") + endif() + cotire_parse_includes( + "${_option_LANGUAGE}" "${_output}" + "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" + "${_option_IGNORE_EXTENSIONS}" + _includes _unparsedLines + ${_sourceFiles}) + if (_option_INCLUDE_PRIORITY_PATH) + set (_sortedIncludes "") + foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH}) + foreach (_include ${_includes}) + string (FIND ${_include} ${_priorityPath} _position) + if (_position GREATER -1) + list (APPEND _sortedIncludes ${_include}) + endif() + endforeach() + endforeach() + if (_sortedIncludes) + list (INSERT _includes 0 ${_sortedIncludes}) + list (REMOVE_DUPLICATES _includes) + endif() + endif() + set (${_includesVar} ${_includes} PARENT_SCOPE) + if (_option_UNPARSED_LINES) + set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_append_undefs _contentsVar) + set (_undefs ${ARGN}) + if (_undefs) + list (REMOVE_DUPLICATES _undefs) + foreach (_definition ${_undefs}) + list (APPEND ${_contentsVar} "#undef ${_definition}") + endforeach() + endif() +endmacro() + +macro (cotire_comment_str _language _commentText _commentVar) + if ("${_language}" STREQUAL "CMAKE") + set (${_commentVar} "# ${_commentText}") + else() + set (${_commentVar} "/* ${_commentText} */") + endif() +endmacro() + +function (cotire_write_file _language _file _contents _force) + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) + cotire_comment_str("${_language}" "${_file}" _header2) + set (_contents "${_header1}\n${_header2}\n${_contents}") + if (COTIRE_DEBUG) + message (STATUS "${_contents}") + endif() + if (_force OR NOT EXISTS "${_file}") + file (WRITE "${_file}" "${_contents}") + else() + file (READ "${_file}" _oldContents) + if (NOT "${_oldContents}" STREQUAL "${_contents}") + file (WRITE "${_file}" "${_contents}") + else() + if (COTIRE_DEBUG) + message (STATUS "${_file} unchanged") + endif() + endif() + endif() +endfunction() + +function (cotire_generate_unity_source _unityFile) + set(_options "") + set(_oneValueArgs LANGUAGE) + set(_multiValueArgs + DEPENDS SOURCES_COMPILE_DEFINITIONS + PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) + if (_unityFileIsUpToDate) + return() + endif() + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_PRE_UNDEFS) + set (_option_PRE_UNDEFS "") + endif() + if (NOT _option_SOURCES_PRE_UNDEFS) + set (_option_SOURCES_PRE_UNDEFS "") + endif() + if (NOT _option_POST_UNDEFS) + set (_option_POST_UNDEFS "") + endif() + if (NOT _option_SOURCES_POST_UNDEFS) + set (_option_SOURCES_POST_UNDEFS "") + endif() + set (_contents "") + if (_option_PROLOGUE) + list (APPEND _contents ${_option_PROLOGUE}) + endif() + if (_option_LANGUAGE AND _sourceFiles) + if ("${_option_LANGUAGE}" STREQUAL "CXX") + list (APPEND _contents "#ifdef __cplusplus") + elseif ("${_option_LANGUAGE}" STREQUAL "C") + list (APPEND _contents "#ifndef __cplusplus") + endif() + endif() + set (_compileUndefinitions "") + foreach (_sourceFile ${_sourceFiles}) + cotire_get_source_compile_definitions( + "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions + ${_option_SOURCES_COMPILE_DEFINITIONS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) + if (_option_PRE_UNDEFS) + list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) + endif() + if (_sourcePreUndefs) + list (APPEND _compileUndefinitions ${_sourcePreUndefs}) + endif() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_sourcePostUndefs) + list (APPEND _compileUndefinitions ${_sourcePostUndefs}) + endif() + if (_option_POST_UNDEFS) + list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) + endif() + foreach (_definition ${_compileDefinitions}) + if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") + list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") + list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") + else() + list (APPEND _contents "#define ${_definition}") + list (INSERT _compileUndefinitions 0 "${_definition}") + endif() + endforeach() + # use absolute path as source file location + get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) + if (WIN32) + file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) + endif() + list (APPEND _contents "#include \"${_sourceFileLocation}\"") + endforeach() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_option_LANGUAGE AND _sourceFiles) + list (APPEND _contents "#endif") + endif() + if (_option_EPILOGUE) + list (APPEND _contents ${_option_EPILOGUE}) + endif() + list (APPEND _contents "") + string (REPLACE ";" "\n" _contents "${_contents}") + if (COTIRE_VERBOSE) + message ("${_contents}") + endif() + cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) +endfunction() + +function (cotire_generate_prefix_header _prefixFile) + set(_options "") + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION) + set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS + INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH + IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + if (_option_DEPENDS) + cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) + if (_prefixFileIsUpToDate) + # create empty log file + set (_unparsedLinesFile "${_prefixFile}.log") + file (WRITE "${_unparsedLinesFile}" "") + return() + endif() + endif() + set (_prologue "") + set (_epilogue "") + if (_option_COMPILER_ID MATCHES "Clang") + set (_prologue "#pragma clang system_header") + elseif (_option_COMPILER_ID MATCHES "GNU") + set (_prologue "#pragma GCC system_header") + elseif (_option_COMPILER_ID MATCHES "MSVC") + set (_prologue "#pragma warning(push, 0)") + set (_epilogue "#pragma warning(pop)") + elseif (_option_COMPILER_ID MATCHES "Intel") + # Intel compiler requires hdrstop pragma to stop generating PCH file + set (_epilogue "#pragma hdrstop") + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + cotire_scan_includes(_selectedHeaders ${_sourceFiles} + LANGUAGE "${_option_LANGUAGE}" + COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" + COMPILER_ARG1 "${_option_COMPILER_ARG1}" + COMPILER_ID "${_option_COMPILER_ID}" + COMPILER_VERSION "${_option_COMPILER_VERSION}" + COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} + COMPILE_FLAGS ${_option_COMPILE_FLAGS} + INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} + SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} + IGNORE_PATH ${_option_IGNORE_PATH} + INCLUDE_PATH ${_option_INCLUDE_PATH} + IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} + INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH} + UNPARSED_LINES _unparsedLines) + cotire_generate_unity_source("${_prefixFile}" + PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) + set (_unparsedLinesFile "${_prefixFile}.log") + if (_unparsedLines) + if (COTIRE_VERBOSE OR NOT _selectedHeaders) + list (LENGTH _unparsedLines _skippedLineCount) + message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFile}") + endif() + string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") + endif() + file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}") +endfunction() + +function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + # cl.exe options used + # /nologo suppresses display of sign-on banner + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # /showIncludes list include files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /showIncludes") + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fdirectives-only do not expand macros, requires GCC >= 4.3 + if (_flags) + # append to list + list (APPEND _flags -H -E) + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + list (APPEND _flags "-fdirectives-only") + endif() + else() + # return as a flag string + set (_flags "-H -E") + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + set (_flags "${_flags} -fdirectives-only") + endif() + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fno-color-diagnostics don't prints diagnostics in color + if (_flags) + # append to list + list (APPEND _flags -H -E -fno-color-diagnostics) + else() + # return as a flag string + set (_flags "-H -E -fno-color-diagnostics") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + # Windows Intel options used + # /nologo do not display compiler version information + # /QH display the include file order + # /EP preprocess to stdout, omitting #line directives + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /QH") + endif() + else() + # Linux / Mac OS X Intel options used + # -H print the name of each header file used + # -EP preprocess to stdout, omitting #line directives + # -Kc++ process all source or unrecognized file types as C++ source files + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags -H -EP) + else() + # return as a flag string + if ("${_language}" STREQUAL "CXX") + set (_flags "-Kc++ ") + endif() + set (_flags "${_flags}-H -EP") + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /Zs syntax check only + # /Zm precompiled header memory allocation scaling factor + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + endif() + elseif (_compilerID MATCHES "GNU|Clang") + # GCC / Clang options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may + # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # Windows Intel options used + # /nologo do not display compiler version information + # /Yc create a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + # /Zs syntax check only + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-create name of the precompiled header (PCH) to create + # -Kc++ process all source or unrecognized file types as C++ source files + # -fsyntax-only check only for correct syntax + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "-Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /Zm precompiled header memory allocation scaling factor + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -include process include file as the first line of the primary source file + # -Winvalid-pch warns if precompiled header is found but cannot be used + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -include process include file as the first line of the primary source file + # -include-pch include precompiled header file + # -Qunused-arguments don't emit warning for unused driver arguments + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # Windows Intel options used + # /Yu use a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-use name of the precompiled header (PCH) to use + # -include process include file as the first line of the primary source file + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) + get_filename_component(_pchName "${_pchFile}" NAME) + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "-Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) + set(_options "") + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_pch_compilation_flags( + "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result) + if (_result) + message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") + endif() +endfunction() + +function (cotire_check_precompiled_header_support _language _target _msgVar) + set (_unsupportedCompiler + "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # supported since Visual Studio C++ 6.0 + # and CMake does not support an earlier version + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC PCH support requires version >= 3.4 + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # all Clang versions have PCH support + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel PCH support requires version >= 8.0.0 + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + else() + set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) + endif() + get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER) + if (CMAKE_${_language}_COMPILER MATCHES "ccache" OR _launcher MATCHES "ccache") + if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros|pch_defines") + set (${_msgVar} + "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + endif() + if (APPLE) + # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) + cotire_get_configuration_types(_configs) + foreach (_config ${_configs}) + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) + list (LENGTH _architectures _numberOfArchitectures) + if (_numberOfArchitectures GREATER 1) + string (REPLACE ";" ", " _architectureStr "${_architectures}") + set (${_msgVar} + "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." + PARENT_SCOPE) + break() + endif() + endforeach() + endif() +endfunction() + +macro (cotire_get_intermediate_dir _cotireDir) + # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types + get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) +endmacro() + +macro (cotire_setup_file_extension_variables) + set (_unityFileExt_C ".c") + set (_unityFileExt_CXX ".cxx") + set (_prefixFileExt_C ".h") + set (_prefixFileExt_CXX ".hxx") + set (_prefixSourceFileExt_C ".c") + set (_prefixSourceFileExt_CXX ".cxx") +endmacro() + +function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") + cotire_get_intermediate_dir(_baseDir) + set (_unityFile "${_baseDir}/${_unityFileName}") + set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + cotire_get_intermediate_dir(_baseDir) + set (_startIndex 0) + set (_index 0) + set (_unityFiles "") + set (_sourceFiles ${ARGN}) + foreach (_sourceFile ${_sourceFiles}) + get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) + math (EXPR _unityFileCount "${_index} - ${_startIndex}") + if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) + if (_index GREATER 0) + # start new unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (_startIndex ${_index}) + endif() + math (EXPR _index "${_index} + 1") + endforeach() + list (LENGTH _sourceFiles _numberOfSources) + if (_startIndex EQUAL 0) + # there is only a single unity file + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) + elseif (_startIndex LESS _numberOfSources) + # end with final unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) + if (COTIRE_DEBUG AND _unityFiles) + message (STATUS "unity files: ${_unityFiles}") + endif() +endfunction() + +function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_prefixFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") + string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") + set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) +endfunction() + +function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _prefixSourceFileExt_${_language}) + set (${_prefixSourceFileVar} "" PARENT_SCOPE) + return() + endif() + string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") + set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) + cotire_setup_file_extension_variables() + if (NOT _language) + set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") + elseif (DEFINED _prefixFileExt_${_language}) + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") + else() + set (_prefixFileBaseName "") + set (_prefixFileName "") + endif() + set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) + set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_path _language _target _prefixFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_prefixFileVar} "" PARENT_SCOPE) + if (_prefixFileName) + if (NOT _language) + set (_language "C") + endif() + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC") + cotire_get_intermediate_dir(_baseDir) + set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (cotire_make_pch_file_path _language _target _pchFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_pchFileVar} "" PARENT_SCOPE) + if (_prefixFileBaseName AND _prefixFileName) + cotire_check_precompiled_header_support("${_language}" "${_target}" _msg) + if (NOT _msg) + if (XCODE) + # For Xcode, we completely hand off the compilation of the prefix header to the IDE + return() + endif() + cotire_get_intermediate_dir(_baseDir) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # MSVC uses the extension .pch added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel uses the extension .pchi added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + +function (cotire_select_unity_source_files _unityFile _sourcesVar) + set (_sourceFiles ${ARGN}) + if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") + set (_startIndex ${CMAKE_MATCH_1}) + set (_endIndex ${CMAKE_MATCH_2}) + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _startIndex LESS _numberOfSources) + math (EXPR _startIndex "${_numberOfSources} - 1") + endif() + if (NOT _endIndex LESS _numberOfSources) + math (EXPR _endIndex "${_numberOfSources} - 1") + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${_endIndex}) + list (GET _sourceFiles ${_index} _file) + list (APPEND _files "${_file}") + endforeach() + else() + set (_files ${_sourceFiles}) + endif() + set (${_sourcesVar} ${_files} PARENT_SCOPE) +endfunction() + +function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target's generated source files + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + # but omit all generated source files that have the COTIRE_EXCLUDED property set to true + cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) + if (_excludedGeneratedSources) + list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) + endif() + # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly + cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) + if (_excludedNonDependencySources) + list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) + endif() + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target source files marked with custom COTIRE_DEPENDENCY property + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles}) + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar) + set (_targetSources ${ARGN}) + cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources}) + cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources}) + # set up variables to be configured + set (COTIRE_TARGET_LANGUAGE "${_language}") + get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) + get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) + get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) + get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) + get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources}) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources}) + set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + cotire_get_target_include_directories( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) + cotire_get_target_compile_definitions( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) + cotire_get_target_compiler_flags( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) + cotire_get_source_files_compile_definitions( + "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources}) + endforeach() + get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER) + # set up COTIRE_TARGET_SOURCES + set (COTIRE_TARGET_SOURCES "") + foreach (_sourceFile ${_targetSources}) + get_source_file_property(_generated "${_sourceFile}" GENERATED) + if (_generated) + # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}") + else() + list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}") + endif() + endforeach() + # copy variable definitions to cotire target script + get_cmake_property(_vars VARIABLES) + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") + # omit COTIRE_*_INIT variables + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}") + if (_initVars) + list (REMOVE_ITEM _matchVars ${_initVars}) + endif() + # omit COTIRE_VERBOSE which is passed as a CMake define on command line + list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) + set (_contents "") + set (_contentsHasGeneratorExpressions FALSE) + foreach (_var IN LISTS _matchVars ITEMS + XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES + CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION + CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_${_language}_SEP + CMAKE_INCLUDE_SYSTEM_FLAG_${_language} + CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + if (DEFINED ${_var}) + string (REPLACE "\"" "\\\"" _value "${${_var}}") + set (_contents "${_contents}set (${_var} \"${_value}\")\n") + if (NOT _contentsHasGeneratorExpressions) + if ("${_value}" MATCHES "\\$<.*>") + set (_contentsHasGeneratorExpressions TRUE) + endif() + endif() + endif() + endforeach() + # generate target script file + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") + cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) + if (_contentsHasGeneratorExpressions) + # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time + set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") + set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") + file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") + else() + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() + set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) + set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) +endfunction() + +function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we attach the precompiled header compilation to the host file + # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion + if (_sourceFiles) + set (_flags "") + cotire_add_pch_compilation_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) + set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") + # make object file generated from host file depend on prefix header + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") + # mark host file as cotired to prevent it from being used in another cotired target + set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generator, we add a custom command to precompile the prefix header + if (_targetScript) + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath) + else() + file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + endif() + set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) + add_custom_command( + OUTPUT "${_pchFile}" + COMMAND ${_cmds} + DEPENDS "${_prefixFile}" + IMPLICIT_DEPENDS ${_language} "${_prefixFile}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}" + VERBATIM) + endif() + endif() +endfunction() + +function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we include the precompiled header in all but the host file + # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation + set (_sourceFiles ${ARGN}) + list (LENGTH _sourceFiles _numberOfSourceFiles) + if (_numberOfSourceFiles GREATER 0) + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + set (_flags "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # make object files generated from source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + set (_sourceFiles ${_hostFile} ${ARGN}) + if (NOT _wholeTarget) + # for makefile based generator, we force the inclusion of the prefix header for a subset + # of the source files, if this is a multi-language target or has excluded files + set (_flags "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + endif() + # make object files generated from source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() +endfunction() + +function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) + set (_sourceFiles ${ARGN}) + # force the inclusion of the prefix header for the given source files + set (_flags "") + set (_pchFile "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + # make object files generated from source files depend on prefix header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") +endfunction() + +function (cotire_get_first_set_property_value _propertyValueVar _type _object) + set (_properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) + return() + endif() + endforeach() + set (${_propertyValueVar} "" PARENT_SCOPE) +endfunction() + +function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar) + set (_files ${ARGN}) + set (_filesPaths "") + foreach (_file ${_files}) + get_filename_component(_filePath "${_file}" ABSOLUTE) + list (APPEND _filesPaths "${_filePath}") + endforeach() + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") + if (_targetScript) + list (APPEND _prefixCmd "${_targetScript}") + endif() + list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") + endif() + set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath) + else() + file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + endif() + get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) + get_filename_component(_joinedFileExt "${_joinedFile}" EXT) + if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}") + elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") + if (_joinedFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}") + endif() + else() + set (_comment "Generating ${_joinedFileLogPath}") + endif() + add_custom_command( + OUTPUT "${_joinedFile}" + COMMAND ${_prefixCmd} + DEPENDS ${_files} + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_target_pch_usage _languages _target _wholeTarget) + if (XCODE) + # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers + set (_prefixFiles "") + foreach (_language ${_languages}) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + list (APPEND _prefixFiles "${_prefixFile}") + endif() + endforeach() + set (_cmds ${ARGN}) + list (LENGTH _prefixFiles _numberOfPrefixFiles) + if (_numberOfPrefixFiles GREATER 1) + # we also generate a generic, single prefix header which includes all language specific prefix headers + set (_language "") + set (_targetScript "") + cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader) + cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles}) + else() + set (_prefixHeader "${_prefixFiles}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") + endif() + # because CMake PRE_BUILD command does not support dependencies, + # we check dependencies explicity in cotire script mode when the pre-build action is run + add_custom_command( + TARGET "${_target}" + PRE_BUILD ${_cmds} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Updating target ${_target} prefix headers" + VERBATIM) + # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generator, we force inclusion of the prefix header for all target source files + # if this is a single-language target without any excluded files + if (_wholeTarget) + set (_language "${_languages}") + # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level + # see cotire_setup_pch_file_inclusion + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) + set (_options COMPILE_OPTIONS) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _options) + set_property(TARGET ${_target} APPEND PROPERTY ${_options}) + endif() + endif() + endif() + endif() +endfunction() + +function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar) + set (_dependencySources "") + cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) + foreach (_unityFile ${_unityFiles}) + set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) + # set up compiled unity source dependencies via OBJECT_DEPENDS + # this ensures that missing source files are generated before the unity file is compiled + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") + endif() + if (_dependencySources) + # the OBJECT_DEPENDS property requires a list of full paths + set (_objectDependsPaths "") + foreach (_sourceFile ${_dependencySources}) + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND _objectDependsPaths "${_sourceLocation}") + endforeach() + set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) + endif() + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel + set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") + endif() + cotire_set_cmd_to_prologue(_unityCmd) + list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_unityCmdDepends "${_targetScript}") + else() + # CMake 3.1.0 supports generator expressions in arguments to DEPENDS + set (_unityCmdDepends "${_targetConfigScript}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath) + else() + file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") + endif() + add_custom_command( + OUTPUT "${_unityFile}" + COMMAND ${_unityCmd} + DEPENDS ${_unityCmdDepends} + COMMENT "Generating ${_language} unity source ${_unityFileLogPath}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) + endforeach() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + set (_dependencySources "") + cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles}) + set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath) + else() + file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") + endif() + get_filename_component(_prefixFileExt "${_prefixFile}" EXT) + if (_prefixFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}") + endif() + # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist + # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence + # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files + set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre") + if (TARGET ${_preTargetName}) + # custom helper target has already been generated while processing a different language + list (APPEND _dependencySources ${_preTargetName}) + else() + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources}) + cotire_init_target("${_preTargetName}") + list (APPEND _dependencySources ${_preTargetName}) + endif() + endif() + add_custom_command( + OUTPUT "${_prefixFile}" "${_prefixFile}.log" + COMMAND ${_prefixCmd} + DEPENDS ${_unityFiles} ${_dependencySources} + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_prefix_generation_command( + ${_language} ${_target} "${_targetScript}" + "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar) + set (_prefixHeaderFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_init_cotire_target_properties _target) + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") + cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") + if (NOT _isRelative) + set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") + endif() + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) + if (NOT _isSet) + if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") + else() + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") + endif() + endif() +endfunction() + +function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + string (REPLACE ";" " " _languagesStr "${_languages}") + math (EXPR _numberOfExcludedFiles "${ARGC} - 4") + if (_numberOfExcludedFiles EQUAL 0) + set (_excludedStr "") + elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) + string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") + else() + set (_excludedStr "excluding ${_numberOfExcludedFiles} files") + endif() + set (_targetMsg "") + if (NOT _languages) + set (_targetMsg "Target ${_target} cannot be cotired.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH AND NOT _targetAddSCU) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") + endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetAddSCU) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") + endif() + else() + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired.") + endif() + endif() + set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) +endfunction() + +function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar) + set (_languages ${ARGN}) + set (_allSourceFiles "") + set (_allExcludedSourceFiles "") + set (_allCotiredSourceFiles "") + set (_targetLanguages "") + set (_pchEligibleTargetLanguages "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + set (_disableMsg "") + foreach (_language ${_languages}) + get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) + get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) + if (_prefixHeader OR _unityBuildFile) + message (STATUS "cotire: target ${_target} has already been cotired.") + set (${_targetLanguagesVar} "" PARENT_SCOPE) + return() + endif() + if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND NOT "${CMAKE_${_language}_COMPILER_ID}" STREQUAL "") + cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg) + if (_disableMsg) + set (_targetUsePCH FALSE) + endif() + endif() + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _excludedSources OR _cotiredSources) + list (APPEND _targetLanguages ${_language}) + endif() + if (_sourceFiles) + list (APPEND _allSourceFiles ${_sourceFiles}) + endif() + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + list (APPEND _pchEligibleTargetLanguages ${_language}) + endif() + if (_excludedSources) + list (APPEND _allExcludedSourceFiles ${_excludedSources}) + endif() + if (_cotiredSources) + list (APPEND _allCotiredSourceFiles ${_cotiredSources}) + endif() + endforeach() + set (_targetMsgLevel STATUS) + if (NOT _targetLanguages) + string (REPLACE ";" " or " _languagesStr "${_languages}") + set (_disableMsg "No ${_languagesStr} source files.") + set (_targetUsePCH FALSE) + set (_targetAddSCU FALSE) + endif() + if (_targetUsePCH) + if (_allCotiredSourceFiles) + cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) + list (REMOVE_DUPLICATES _cotireTargets) + string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") + set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") + set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") + set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") + set (_targetMsgLevel SEND_ERROR) + set (_targetUsePCH FALSE) + elseif (NOT _pchEligibleTargetLanguages) + set (_disableMsg "Too few applicable sources.") + set (_targetUsePCH FALSE) + elseif (XCODE AND _allExcludedSourceFiles) + # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target + set (_disableMsg "Exclusion of source files not supported for generator Xcode.") + set (_targetUsePCH FALSE) + elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") + # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target + set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") + set (_targetUsePCH FALSE) + endif() + endif() + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) + cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) + if (_targetMsg) + if (NOT DEFINED COTIREMSG_${_target}) + set (COTIREMSG_${_target} "") + endif() + if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR + NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") + # cache message to avoid redundant messages on re-configure + set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") + message (${_targetMsgLevel} "${_targetMsg}") + endif() + endif() + list (LENGTH _targetLanguages _numberOfLanguages) + if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) + set (${_wholeTargetVar} FALSE PARENT_SCOPE) + else() + set (${_wholeTargetVar} TRUE PARENT_SCOPE) + endif() + set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) +endfunction() + +function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) + set (_sourceFiles ${ARGN}) + get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") + set (_numberOfThreads "${CMAKE_MATCH_2}") + if (NOT _numberOfThreads) + # use all available cores + ProcessorCount(_numberOfThreads) + endif() + list (LENGTH _sourceFiles _numberOfSources) + math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") + elseif (NOT _maxIncludes MATCHES "[0-9]+") + set (_maxIncludes 0) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_target} unity source max includes: ${_maxIncludes}") + endif() + set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) +endfunction() + +function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar) + set (${_cmdsVar} "" PARENT_SCOPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (NOT _sourceFiles AND NOT _cotiredSources) + return() + endif() + set (_cmds "") + # check for user provided unity source file list + get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) + if (NOT _unitySourceFiles) + set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) + endif() + cotire_generate_target_script( + ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) + # set up unity files for parallel compilation + cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) + cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles EQUAL 0) + return() + elseif (_numberOfUnityFiles GREATER 1) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + endif() + # set up single unity file for prefix header generation + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles}) + cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) + # set up prefix header + if (_prefixFile) + # check for user provided prefix header files + get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + if (_prefixHeaderFiles) + cotire_setup_prefix_generation_from_provided_command( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + else() + cotire_setup_prefix_generation_from_unity_command( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles}) + endif() + # check if selected language has enough sources at all + list (LENGTH _sourceFiles _numberOfSources) + if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_targetUsePCH FALSE) + else() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + endif() + if (_targetUsePCH) + cotire_make_pch_file_path(${_language} ${_target} _pchFile) + if (_pchFile) + # first file in _sourceFiles is passed as the host file + cotire_setup_pch_file_compilation( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + cotire_setup_pch_file_inclusion( + ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + endif() + elseif (_prefixHeaderFiles) + # user provided prefix header must be included unconditionally + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) + endif() + endif() + # mark target as cotired for language + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") + if (_prefixFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") + if (_targetUsePCH AND _pchFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") + endif() + endif() + set (${_cmdsVar} ${_cmds} PARENT_SCOPE) +endfunction() + +function (cotire_setup_clean_target _target) + set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") + if (NOT TARGET "${_cleanTargetName}") + cotire_set_cmd_to_prologue(_cmds) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") + add_custom_target(${_cleanTargetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up target ${_target} cotire generated files" + VERBATIM) + cotire_init_target("${_cleanTargetName}") + endif() +endfunction() + +function (cotire_setup_pch_target _languages _configurations _target) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generators, we add a custom target to trigger the generation of the cotire related files + set (_dependsFiles "") + foreach (_language ${_languages}) + set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # Visual Studio and Intel only create precompiled header as a side effect + list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) + endif() + cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) + if (_dependsFile) + list (APPEND _dependsFiles "${_dependsFile}") + endif() + endforeach() + if (_dependsFiles) + set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") + add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) + cotire_init_target("${_pchTargetName}") + cotire_add_to_pch_all_target(${_pchTargetName}) + endif() + else() + # for other generators, we add the "clean all" target to clean up the precompiled header + cotire_setup_clean_all_target() + endif() +endfunction() + +function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_unityTargetSources ${_targetSourceFiles}) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + # remove source files that are included in the unity source + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _cotiredSources) + list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) + endif() + # add unity source files instead + list (APPEND _unityTargetSources ${_unityFiles}) + endif() + endforeach() + set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE) +endfunction() + +function (cotire_setup_unity_target_pch_usage _languages _target) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_userPrefixFile AND _prefixFile) + # user provided prefix header must be included unconditionally by unity sources + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles}) + endif() + endif() + endforeach() +endfunction() + +function (cotire_setup_unity_build_target _languages _configurations _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (NOT _unityTargetName) + set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") + endif() + # determine unity target sub type + get_target_property(_targetType ${_target} TYPE) + if ("${_targetType}" STREQUAL "EXECUTABLE") + set (_unityTargetSubType "") + elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (_unityTargetSubType "${CMAKE_MATCH_1}") + else() + message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") + return() + endif() + # determine unity target sources + set (_unityTargetSources "") + cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources) + # handle automatic Qt processing + get_target_property(_targetAutoMoc ${_target} AUTOMOC) + get_target_property(_targetAutoUic ${_target} AUTOUIC) + get_target_property(_targetAutoRcc ${_target} AUTORCC) + if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) + # if the original target sources are subject to CMake's automatic Qt processing, + # also include implicitly generated _automoc.cpp file + list (APPEND _unityTargetSources "${_target}_automoc.cpp") + set_property (SOURCE "${_target}_automoc.cpp" PROPERTY GENERATED TRUE) + endif() + # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created + set (CMAKE_AUTOMOC OFF) + set (CMAKE_AUTOUIC OFF) + set (CMAKE_AUTORCC OFF) + if (COTIRE_DEBUG) + message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") + endif() + # generate unity target + if ("${_targetType}" STREQUAL "EXECUTABLE") + add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + else() + add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + endif() + if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) + # depend on the original target's implicity generated _automoc target + add_dependencies(${_unityTargetName} ${_target}_automoc) + endif() + # copy output location properties + set (_outputDirProperties + ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ + LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ + RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) + if (COTIRE_UNITY_OUTPUT_DIRECTORY) + set (_setDefaultOutputDir TRUE) + if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + else() + # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_resolve_config_properites("${_configurations}" _properties ${_outputDirProperties}) + foreach (_property ${_properties}) + get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) + if (_outputDir) + get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") + set (_setDefaultOutputDir FALSE) + endif() + endforeach() + if (_setDefaultOutputDir) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + endif() + endif() + if (_setDefaultOutputDir) + set_target_properties(${_unityTargetName} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" + LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" + RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") + endif() + else() + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + ${_outputDirProperties}) + endif() + # copy output name + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ + LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ + OUTPUT_NAME OUTPUT_NAME_ + RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ + PREFIX _POSTFIX SUFFIX + IMPORT_PREFIX IMPORT_SUFFIX) + # copy compile stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ + COMPILE_FLAGS COMPILE_OPTIONS + Fortran_FORMAT Fortran_MODULE_DIRECTORY + INCLUDE_DIRECTORIES + INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ + POSITION_INDEPENDENT_CODE + C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER + C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE + C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN) + # copy compile features + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED + CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED + COMPILE_FEATURES) + # copy interface stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN + COMPATIBLE_INTERFACE_STRING + INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS + INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES + INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED) + # copy link stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH + LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED + LINK_FLAGS LINK_FLAGS_ + LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ + LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ + LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC + STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ + NO_SONAME SOVERSION VERSION) + # copy cmake stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) + # copy Apple platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR + MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH + OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST + IOS_INSTALL_COMBINED) + # copy Windows platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + GNUtoMS + COMPILE_PDB_NAME COMPILE_PDB_NAME_ + COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_ + PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ + VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION + VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE + VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK + VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION + VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER + VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION + VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES + WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS) + # copy Android platform specific stuff + cotire_copy_set_properites("${_configurations}" TARGET ${_target} ${_unityTargetName} + ANDROID_API ANDROID_API_MIN ANDROID_GUI + ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES + ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR + ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES + ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH + ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE) + # use output name from original target + get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) + if (NOT _targetOutputName) + set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") + endif() + # use export symbol from original target + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") + if ("${_targetType}" STREQUAL "EXECUTABLE") + set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) + endif() + endif() + cotire_init_target(${_unityTargetName}) + cotire_add_to_unity_all_target(${_unityTargetName}) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") +endfunction(cotire_setup_unity_build_target) + +function (cotire_target _target) + set(_options "") + set(_oneValueArgs "") + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGES) + get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + endif() + if (NOT _option_CONFIGURATIONS) + cotire_get_configuration_types(_option_CONFIGURATIONS) + endif() + # check if cotire can be applied to target at all + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + get_target_property(_imported ${_target} IMPORTED) + get_target_property(_targetType ${_target} TYPE) + if (_imported) + message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.") + else() + message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.") + endif() + return() + endif() + # resolve alias + get_target_property(_aliasName ${_target} ALIASED_TARGET) + if (_aliasName) + if (COTIRE_DEBUG) + message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") + endif() + set (_target ${_aliasName}) + endif() + # check if target needs to be cotired for build type + # when using configuration types, the test is performed at build time + cotire_init_cotire_target_properties(${_target}) + if (NOT CMAKE_CONFIGURATION_TYPES) + if (CMAKE_BUILD_TYPE) + list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) + else() + list (FIND _option_CONFIGURATIONS "None" _index) + endif() + if (_index EQUAL -1) + if (COTIRE_DEBUG) + message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") + endif() + return() + endif() + endif() + # when not using configuration types, immediately create cotire intermediate dir + if (NOT CMAKE_CONFIGURATION_TYPES) + cotire_get_intermediate_dir(_baseDir) + file (MAKE_DIRECTORY "${_baseDir}") + endif() + # choose languages that apply to the target + cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) + if (NOT _targetLanguages) + return() + endif() + set (_cmds "") + foreach (_language ${_targetLanguages}) + cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd) + if (_cmd) + list (APPEND _cmds ${_cmd}) + endif() + endforeach() + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + if (_targetAddSCU) + cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + endif() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + if (_targetUsePCH) + cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds}) + cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + if (_targetAddSCU) + cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target}) + endif() + endif() + get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) + if (_targetAddCleanTarget) + cotire_setup_clean_target(${_target}) + endif() +endfunction(cotire_target) + +function (cotire_map_libraries _strategy _mappedLibrariesVar) + set (_mappedLibraries "") + foreach (_library ${ARGN}) + if (_library MATCHES "^\\$$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly TRUE) + else() + set (_libraryName "${_library}") + set (_linkOnly FALSE) + endif() + if ("${_strategy}" MATCHES "COPY_UNITY") + cotire_is_target_supported(${_libraryName} _isSupported) + if (_isSupported) + # use target's corresponding unity target, if available + get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + if (_linkOnly) + list (APPEND _mappedLibraries "$") + else() + list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + endforeach() + list (REMOVE_DUPLICATES _mappedLibraries) + set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_target_link_libraries _target) + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + return() + endif() + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_unityTargetName}") + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") + endif() + if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + if (_linkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}") + endif() + endif() + get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) + if (_interfaceLinkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}") + endif() + endif() + endif() + endif() +endfunction(cotire_target_link_libraries) + +function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) + if (_targetName) + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") + else() + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") + endif() + # filter files in intermediate directory + set (_filesToRemove "") + foreach (_file ${_cotireFiles}) + get_filename_component(_dir "${_file}" DIRECTORY) + get_filename_component(_dirName "${_dir}" NAME) + if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") + list (APPEND _filesToRemove "${_file}") + endif() + endforeach() + if (_filesToRemove) + if (COTIRE_VERBOSE) + message (STATUS "cleaning up ${_filesToRemove}") + endif() + file (REMOVE ${_filesToRemove}) + endif() +endfunction() + +function (cotire_init_target _targetName) + if (COTIRE_TARGETS_FOLDER) + set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") + endif() + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE) + if (MSVC_IDE) + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endfunction() + +function (cotire_add_to_pch_all_target _pchTargetName) + set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_pchTargetName}) +endfunction() + +function (cotire_add_to_unity_all_target _unityTargetName) + set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_unityTargetName}) +endfunction() + +function (cotire_setup_clean_all_target) + set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") + add_custom_target(${_targetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up all cotire generated files" + VERBATIM) + cotire_init_target("${_targetName}") + endif() +endfunction() + +function (cotire) + set(_options "") + set(_oneValueArgs "") + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_targets ${_option_UNPARSED_ARGUMENTS}) + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}) + else() + message (WARNING "cotire: ${_target} is not a target.") + endif() + endforeach() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target_link_libraries(${_target}) + endif() + endforeach() +endfunction() + +if (CMAKE_SCRIPT_MODE_FILE) + + # cotire is being run in script mode + # locate -P on command args + set (COTIRE_ARGC -1) + foreach (_index RANGE ${CMAKE_ARGC}) + if (COTIRE_ARGC GREATER -1) + set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") + math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") + elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") + set (COTIRE_ARGC 0) + endif() + endforeach() + + # include target script if available + if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") + # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) + include("${COTIRE_ARGV2}") + endif() + + if (COTIRE_DEBUG) + message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") + endif() + + if (NOT COTIRE_BUILD_TYPE) + set (COTIRE_BUILD_TYPE "None") + endif() + string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) + set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) + set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) + # check if target has been cotired for actual build type COTIRE_BUILD_TYPE + list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) + if (_index GREATER -1) + set (_sources ${COTIRE_TARGET_SOURCES}) + set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) + else() + if (COTIRE_DEBUG) + message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") + endif() + set (_sources "") + set (_sourcesDefinitions "") + endif() + set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) + set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) + set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) + set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) + + if ("${COTIRE_ARGV1}" STREQUAL "unity") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on target script + set (_dependsOption DEPENDS "${COTIRE_ARGV2}") + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) + + cotire_generate_unity_source( + "${COTIRE_ARGV3}" ${_sources} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} + PRE_UNDEFS ${_targetPreUndefs} + POST_UNDEFS ${_targetPostUndefs} + SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} + SOURCES_POST_UNDEFS ${_sourcesPostUndefs} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies + set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + set (_files "") + foreach (_index RANGE 4 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_generate_prefix_header( + "${COTIRE_ARGV3}" ${_files} + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" + INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} + IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" + INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH} + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") + + set (_files "") + foreach (_index RANGE 5 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_precompile_prefix_header( + "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "combine") + + if (COTIRE_TARGET_LANGUAGE) + set (_combinedFile "${COTIRE_ARGV3}") + set (_startIndex 4) + else() + set (_combinedFile "${COTIRE_ARGV2}") + set (_startIndex 3) + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + if (XCODE) + # executing pre-build action under Xcode, check dependency on files to be combined + set (_dependsOption DEPENDS ${_files}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + if (COTIRE_TARGET_LANGUAGE) + cotire_generate_unity_source( + "${_combinedFile}" ${_files} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + ${_dependsOption}) + else() + cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption}) + endif() + + elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") + + cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") + + else() + message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") + endif() + +else() + + # cotire is being run in include mode + # set up all variable and property definitions + + if (NOT DEFINED COTIRE_DEBUG_INIT) + if (DEFINED COTIRE_DEBUG) + set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) + else() + set (COTIRE_DEBUG_INIT FALSE) + endif() + endif() + option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) + + if (NOT DEFINED COTIRE_VERBOSE_INIT) + if (DEFINED COTIRE_VERBOSE) + set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) + else() + set (COTIRE_VERBOSE_INIT FALSE) + endif() + endif() + option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING + "Ignore headers with the listed file extensions from the generated prefix header.") + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING + "Ignore headers from these directories when generating the prefix header.") + + set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING + "Ignore sources with the listed file extensions from the generated unity source.") + + set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING + "Minimum number of sources in target required to enable use of precompiled header.") + + if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) + if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) + elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") + # enable parallelization for generators that run multiple jobs by default + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") + else() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") + endif() + endif() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING + "Maximum number of source files to include in a single unity source file.") + + if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) + set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") + endif() + if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) + set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") + endif() + if (NOT COTIRE_INTDIR) + set (COTIRE_INTDIR "cotire") + endif() + if (NOT COTIRE_PCH_ALL_TARGET_NAME) + set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) + set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") + endif() + if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) + set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") + endif() + if (NOT COTIRE_CLEAN_TARGET_SUFFIX) + set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") + endif() + if (NOT COTIRE_PCH_TARGET_SUFFIX) + set (COTIRE_PCH_TARGET_SUFFIX "_pch") + endif() + if (MSVC) + # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code + # use a bigger default factor of 170 percent (128 MB) + if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170") + endif() + endif() + if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) + set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") + endif() + if (NOT DEFINED COTIRE_TARGETS_FOLDER) + set (COTIRE_TARGETS_FOLDER "cotire") + endif() + if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) + if ("${CMAKE_GENERATOR}" MATCHES "Ninja") + # generated Ninja build files do not work if the unity target produces the same output file as the cotired target + set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") + else() + set (COTIRE_UNITY_OUTPUT_DIRECTORY "") + endif() + endif() + + # define cotire cache variables + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of include directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "If not defined, defaults to empty list." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" + BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a header file extension matches one in the list, it will be excluded from the generated prefix header." + "Includes with an extension in CMAKE__SOURCE_FILE_EXTENSIONS are always ignored." + "If not defined, defaults to inc;inl;ipp." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" + BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a source file extension matches one in the list, it will be excluded from the generated unity source file." + "Source files with an extension in CMAKE__IGNORE_EXTENSIONS are always excluded." + "If not defined, defaults to m;mm." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" + BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." + FULL_DOCS + "The variable can be set to an integer > 0." + "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." + "If not defined, defaults to 3." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer >= 0." + "If 0, cotire will only create a single unity source file." + "If a target contains more than that number of source files, cotire will create multiple unity source files for it." + "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." + "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." + "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." + ) + + # define cotire directory properties + + define_property( + DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" + BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." + FULL_DOCS + "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" + BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_UNITY_BUILD." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" + BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_CLEAN." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" + BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" + BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." + FULL_DOCS + "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." + ) + + # define cotire target properties + + define_property( + TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED + BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." + FULL_DOCS + "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." + "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." + "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." + "The target name will be set to this target's name with the suffix _pch appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED + BRIEF_DOCS "Add a new target that performs a unity build for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." + "Most of the relevant target properties will be copied from this target to the new unity build target." + "Target dependencies and linked libraries have to be manually set up for the new unity build target." + "The unity target name will be set to this target's name with the suffix _unity appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED + BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." + "The clean target name will be set to this target's name with the suffix _clean_cotire appended." + "Inherited from directory." + "Defaults to FALSE." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "Inherited from directory." + "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." + "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," + "the option which yields the closer relative path match wins." + "Inherited from directory." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED + BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header." + "Header files are sorted according to the order of the directories in the property." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer > 0." + "If a target contains more than that number of source files, cotire will create multiple unity build files for it." + "If not set, cotire will only create a single unity source file." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE_INIT" + BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will only add the given file(s) to the generated unity source file." + "If not set, cotire will add all the target source files to the generated unity source file." + "The property can be set to a user provided unity source file." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER_INIT" + BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will add the given header file(s) to the generated prefix header file." + "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." + "The property can be set to a user provided prefix header file (e.g., stdafx.h)." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED + BRIEF_DOCS "Define strategy for setting up unity target's link libraries." + FULL_DOCS + "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually." + "If this property is set to COPY, the unity target's link libraries will be copied from this target." + "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE" + BRIEF_DOCS "Read-only property. The generated unity source file(s)." + FULL_DOCS + "cotire sets this property to the path of the generated single computation unit source file for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER" + BRIEF_DOCS "Read-only property. The generated prefix header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language prefix header for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PRECOMPILED_HEADER" + BRIEF_DOCS "Read-only property. The generated precompiled header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language precompiled header binary for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" + BRIEF_DOCS "The name of the generated unity build target corresponding to this target." + FULL_DOCS + "This property can be set to the desired name of the unity target that will be created by cotire." + "If not set, the unity target name will be set to this target's name with the suffix _unity appended." + "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." + "Defaults to empty string." + ) + + # define cotire source properties + + define_property( + SOURCE PROPERTY "COTIRE_EXCLUDED" + BRIEF_DOCS "Do not modify source file's build command." + FULL_DOCS + "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." + "The source file will also be excluded from the generated unity source file." + "Source files that have their COMPILE_FLAGS property set will be excluded by default." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_DEPENDENCY" + BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." + FULL_DOCS + "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." + "If the file is modified, cotire will re-generate the prefix header source upon build." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" + BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." + FULL_DOCS + "If this property is set to TRUE, cotire will complete the current unity file and start a new one." + "The new unity source file will include this source file as the first one." + "This property essentially works as a separator for unity source files." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_TARGET" + BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." + FULL_DOCS + "cotire sets this property to the name of target, that the source file's build command has been altered for." + "Defaults to empty string." + ) + + message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") + +endif() diff --git a/tools/cmake/helpers/generators.cmake b/tools/cmake/helpers/generators.cmake new file mode 100644 index 0000000000..64f7c1f670 --- /dev/null +++ b/tools/cmake/helpers/generators.cmake @@ -0,0 +1,62 @@ +# Copyright (c) 2016, Ford Motor Company +# 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 name of the Ford Motor Company nor the names of its 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. + +find_package(PythonInterp REQUIRED) + +if(NOT PYTHONINTERP_FOUND) + message(STATUS "Python interpreter is not found") + message(STATUS "To install it type in the command line:") + message(STATUS "sudo apt-get install python") + message(FATAL_ERROR "Exiting!") +endif(NOT PYTHONINTERP_FOUND) + +set(INTEFRACE_GENERATOR "${CMAKE_SOURCE_DIR}/tools/InterfaceGenerator/Generator.py") +set(INTEFRACE_GENERATOR_CMD ${PYTHON_EXECUTABLE} -B ${INTEFRACE_GENERATOR}) +file(GLOB_RECURSE INTERFACE_GENERATOR_DEPENDENCIES "${CMAKE_SOURCE_DIR}/tools/InterfaceGenerator/*.*") + +macro(generate_interface ARG_XML_NAME ARG_NAMESPACE PARSER_TYPE) + string(REGEX MATCH "^[a-zA-Z_0-9]*[^.]" FILE_NAME ${ARG_XML_NAME}) # TODO: make expression more robust + + set(HPP_FILE + "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}.h" + "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}_schema.h" + ) + + set(CPP_FILE "${CMAKE_CURRENT_BINARY_DIR}/${FILE_NAME}_schema.cc") + set(FULL_XML_NAME "${CMAKE_CURRENT_SOURCE_DIR}/${ARG_XML_NAME}") + + add_custom_command( + OUTPUT ${HPP_FILE} ${CPP_FILE} + COMMAND ${INTEFRACE_GENERATOR_CMD} ${FULL_XML_NAME} ${ARG_NAMESPACE} ${CMAKE_CURRENT_BINARY_DIR} "--parser-type" "${PARSER_TYPE}" + DEPENDS ${INTERFACE_GENERATOR_DEPENDENCIES} ${FULL_XML_NAME} + COMMENT "Generating files:\n ${HPP_FILE}\n ${CPP_FILE}\nfrom:\n ${FULL_XML_NAME} ..." + VERBATIM + ) +endmacro() diff --git a/tools/cmake/helpers/platform.cmake b/tools/cmake/helpers/platform.cmake new file mode 100644 index 0000000000..a377dfd042 --- /dev/null +++ b/tools/cmake/helpers/platform.cmake @@ -0,0 +1,96 @@ +# Copyright (c) 2016, Ford Motor Company +# 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 name of the Ford Motor Company nor the names of its 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. + +# SDL build platform includes three necessary components: +# OS, Architecture and SDK. Build parameters and sources code base +# could be varied depends on these three components combination. +# +# Platform helpers provide functionality to get supported by SDL +# OS, Architecture or SDK lists and specified for actual build these +# variables values. Values could be passed to cmake as parameters +# (f.e. "-DOS_WINDOWS=1 -DSDK_QT=1"), otherwise they will be detected +# related to current build environment. +# +# Full list of supported cmake flags: +# OS_POSIX +# OS_WINDOWS +# ARCH_X86 +# ARCH_X64 +# SDK_QT + +function(get_supported_os OS_LIST) + set(${OS_LIST} "posix" "win" PARENT_SCOPE) +endfunction() + +function(get_supported_arch ARCH_LIST) + set(${ARCH_LIST} "x86" "x64" PARENT_SCOPE) +endfunction() + +function(get_supported_sdk SDK_LIST) + set(${SDK_LIST} "qt" PARENT_SCOPE) +endfunction() + +function(get_os OS) + if(OS_POSIX) + set(${OS} "posix" PARENT_SCOPE) + elseif(OS_WINDOWS) + set(${OS} "win" PARENT_SCOPE) + else() + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(${OS} "posix" PARENT_SCOPE) + elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + set(${OS} "win" PARENT_SCOPE) + else() + message(FATAL_ERROR "Unsupported operation system") + endif() + endif() +endfunction() + +function(get_arch ARCH) + if(ARCH_X86) + set(${ARCH} "x86" PARENT_SCOPE) + elseif(ARCH_X64) + set(${ARCH} "x64" PARENT_SCOPE) + else() + if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "i386") + set(${ARCH} "x86" PARENT_SCOPE) + elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64") + set(${ARCH} "x64" PARENT_SCOPE) + else() + message(FATAL_ERROR "Unsupported architecture") + endif() + endif() +endfunction() + +function(get_sdk SDK) + if(SDK_QT) + set(${SDK} "qt" PARENT_SCOPE) + endif() +endfunction() diff --git a/tools/cmake/helpers/sources.cmake b/tools/cmake/helpers/sources.cmake new file mode 100644 index 0000000000..0315b905d9 --- /dev/null +++ b/tools/cmake/helpers/sources.cmake @@ -0,0 +1,166 @@ +# Copyright (c) 2016, Ford Motor Company +# 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 name of the Ford Motor Company nor the names of its 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. + +# Sources helpers provide functionality to collect headers, source files +# or any other files depends on current build settings (OS, Architecture, SDK). +# +# Files could be included or excluded to/from build for some platform by +# platform-specific suffix adding to filename. For example file +# sdl_source_file_posix_x86_qt.cc will be added only to build with parameters: +# OS=posix ARCH=x86 SDK=qt but file sdl_source_file_win.cc to all builds +# with OS=win option enabled. Suffixes could be mixed within filename randomly. +# +# Full list of supported suffixes: +# posix +# win +# x86 +# x64 +# qt + +include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/platform.cmake) + +function(filter_files_by_name FILES IGNORE_NAMES) + set(FILES_LOCAL ${${FILES}}) + foreach(FILE_ENTRY ${${FILES}}) + foreach(IGNORE_ENTRY ${IGNORE_NAMES}) + if(${FILE_ENTRY} MATCHES ${IGNORE_ENTRY}) + list(REMOVE_ITEM FILES_LOCAL ${FILE_ENTRY}) + endif() + endforeach() + endforeach() + set(${FILES} ${FILES_LOCAL} PARENT_SCOPE) +endfunction() + +function(filter_files_by_suffix FILES IGNORE_SUFFIXES) + set(FILES_LOCAL ${${FILES}}) + foreach(FILE_ENTRY ${${FILES}}) + foreach(IGNORE_ENTRY ${IGNORE_SUFFIXES}) + if((${FILE_ENTRY} MATCHES "_${IGNORE_ENTRY}_") OR (${FILE_ENTRY} MATCHES "_${IGNORE_ENTRY}\\.")) + list(REMOVE_ITEM FILES_LOCAL ${FILE_ENTRY}) + endif() + endforeach() + endforeach() + set(${FILES} ${FILES_LOCAL} PARENT_SCOPE) +endfunction() + +function(filter_files_by_os FILES) + set(FILES_LOCAL ${${FILES}}) + get_supported_os(OS_LIST) + get_os(OS) + list(REMOVE_ITEM OS_LIST ${OS}) + filter_files_by_suffix(FILES_LOCAL "${OS_LIST}") + set(${FILES} ${FILES_LOCAL} PARENT_SCOPE) +endfunction() + +function(filter_files_by_arch FILES) + set(FILES_LOCAL ${${FILES}}) + get_supported_arch(ARCH_LIST) + get_arch(ARCH) + list(REMOVE_ITEM ARCH_LIST ${ARCH}) + filter_files_by_suffix(FILES_LOCAL "${ARCH_LIST}") + set(${FILES} ${FILES_LOCAL} PARENT_SCOPE) +endfunction() + +function(filter_files_by_sdk FILES) + set(FILES_LOCAL ${${FILES}}) + get_supported_sdk(SDK_LIST) + get_sdk(SDK) + if(SDK) + list(REMOVE_ITEM SDK_LIST ${SDK}) + endif() + filter_files_by_suffix(FILES_LOCAL "${SDK_LIST}") + set(${FILES} ${FILES_LOCAL} PARENT_SCOPE) +endfunction() + +function(filter_files FILES IGNORE_NAMES) + set(FILES_LOCAL ${${FILES}}) + filter_files_by_name(FILES_LOCAL "${IGNORE_NAMES}") + filter_files_by_os(FILES_LOCAL) + filter_files_by_arch(FILES_LOCAL) + filter_files_by_sdk(FILES_LOCAL) + set(${FILES} ${FILES_LOCAL} PARENT_SCOPE) +endfunction() + +function(collect_sources SOURCES PATHS) + set(OPTIONAL_ARG ${ARGN}) + set(HEADERS_LOCAL) + set(SOURCES_LOCAL) + get_os(OS) + + foreach(PATH_ENTRY ${PATHS}) + file(GLOB_RECURSE SOURCES_TO_FILTER "${PATH_ENTRY}/*.c" "${PATH_ENTRY}/*.cc" "${PATH_ENTRY}/*.cpp") + filter_files(SOURCES_TO_FILTER "${OPTIONAL_ARG}") + list(APPEND SOURCES_LOCAL ${SOURCES_TO_FILTER}) + set(SOURCES_TO_FILTER) + if(${OS} STREQUAL "win") + file(GLOB_RECURSE HEADERS_TO_FILTER "${PATH_ENTRY}/*.h" "${PATH_ENTRY}/*.hpp") + filter_files(HEADERS_TO_FILTER "${OPTIONAL_ARG}") + list(APPEND HEADERS_LOCAL ${HEADERS_TO_FILTER}) + set(HEADERS_TO_FILTER) + endif() + endforeach() + + if(${OS} STREQUAL "win") + source_group("Header Files" FILES ${HEADERS_LOCAL}) + source_group("Source Files" FILES ${SOURCES_LOCAL}) + endif() + set(${SOURCES} ${SOURCES_LOCAL} PARENT_SCOPE) +endfunction() + +function(create_test NAME SOURCES LIBS) + add_executable("${NAME}" ${CMAKE_SOURCE_DIR}/src/components/test_main.cc ${SOURCES}) + target_link_libraries("${NAME}" ${LIBS}) + target_link_libraries("${NAME}" Utils) + add_test(NAME ${NAME} + COMMAND ${NAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/) +endfunction() + +function(create_cotired_test NAME SOURCES LIBS) + add_executable( + ${NAME} + EXCLUDE_FROM_ALL + ${CMAKE_SOURCE_DIR}/src/components/test_main.cc + ${SOURCES} + ) + # TODO: Fix problems with Cotire on Windows and Qt APPLINK-28060 + if(${USE_COTIRE} AND (${CMAKE_SYSTEM_NAME} MATCHES "Linux")) + include(${CMAKE_SOURCE_DIR}/tools/cmake/helpers/cotire.cmake) + cotire(${NAME}) + set(NAME "${NAME}_unity") + endif() + target_link_libraries(${NAME} ${LIBS}) + set_target_properties( + ${NAME} + PROPERTIES + EXCLUDE_FROM_ALL 0 + ) + add_test(NAME ${NAME} + COMMAND ${NAME} --gtest_output=xml:${CMAKE_BINARY_DIR}/test_results/) +endfunction() diff --git a/tools/cmake/modules/FindGlib-2.0.cmake b/tools/cmake/modules/FindGlib-2.0.cmake new file mode 100644 index 0000000000..b39da141c9 --- /dev/null +++ b/tools/cmake/modules/FindGlib-2.0.cmake @@ -0,0 +1,43 @@ +FILE(TO_CMAKE_PATH "$ENV{GLIB2_DIR}" TRY1_DIR) +FILE(TO_CMAKE_PATH "${GLIB2_DIR}" TRY2_DIR) +FILE(GLOB GLIB2_DIR ${TRY1_DIR} ${TRY2_DIR}) + +FIND_PATH(GLIB_glib_2_INCLUDE_DIR glib.h + PATHS ${GLIB2_DIR}/include ${GLIB2_DIR}/include/glib-2.0 /usr/local/include/glib-2.0 /usr/include/glib-2.0 /usr/lib/glib-2.0/include/ + ENV INCLUDE DOC "Directory containing glib.h include file") + +FIND_PATH(GLIB_glibconfig_2_INCLUDE_DIR glibconfig.h + PATHS ${GLIB2_DIR}/include ${GLIB2_DIR}/include/glib-2.0 ${GLIB2_DIR}/lib/include ${GLIB2_DIR}/lib/glib-2.0/include /usr/local/include/glib-2.0 /usr/include/glib-2.0 /usr/lib/glib-2.0/include /usr/local/lib/glib-2.0/include + ENV INCLUDE DOC "Directory containing glibconfig.h include file") + +FIND_LIBRARY(GLIB_glib_2_LIBRARY NAMES glib-2.0 + PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "glib library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GLIB_gmodule_2_LIBRARY NAMES gmodule-2.0 + PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gmodule library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GLIB_gobject_2_LIBRARY NAMES gobject-2.0 + PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gobject library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GLIB_gthread_2_LIBRARY NAMES gthread-2.0 + PATHS ${GLIB2_DIR}/bin ${GLIB2_DIR}/win32/bin ${GLIB2_DIR}/lib ${GLIB2_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gthread library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +IF (GLIB_glib_2_INCLUDE_DIR AND GLIB_glibconfig_2_INCLUDE_DIR AND GLIB_glib_2_LIBRARY AND GLIB_gmodule_2_LIBRARY AND GLIB_gobject_2_LIBRARY AND GLIB_gthread_2_LIBRARY) + SET(GLIB2_INCLUDE_DIR ${GLIB_glib_2_INCLUDE_DIR} ${GLIB_glibconfig_2_INCLUDE_DIR}) + list(REMOVE_DUPLICATES GLIB2_INCLUDE_DIR) + SET(GLIB2_LIBRARIES ${GLIB_glib_2_LIBRARY} ${GLIB_gmodule_2_LIBRARY} ${GLIB_gobject_2_LIBRARY} ${GLIB_gthread_2_LIBRARY}) + list(REMOVE_DUPLICATES GLIB2_LIBRARIES) + SET(GLIB2_FOUND TRUE) +ENDIF (GLIB_glib_2_INCLUDE_DIR AND GLIB_glibconfig_2_INCLUDE_DIR AND GLIB_glib_2_LIBRARY AND GLIB_gmodule_2_LIBRARY AND GLIB_gobject_2_LIBRARY AND GLIB_gthread_2_LIBRARY) diff --git a/tools/cmake/modules/FindGstreamer-1.0.cmake b/tools/cmake/modules/FindGstreamer-1.0.cmake new file mode 100644 index 0000000000..8f1d69d01b --- /dev/null +++ b/tools/cmake/modules/FindGstreamer-1.0.cmake @@ -0,0 +1,136 @@ +FILE(TO_CMAKE_PATH "$ENV{GSTREAMER_DIR}" TRY1_DIR) +FILE(TO_CMAKE_PATH "${GSTREAMER_DIR}" TRY2_DIR) +FILE(GLOB GSTREAMER_DIR ${TRY1_DIR} ${TRY2_DIR}) + +FIND_PATH(GSTREAMER_gst_INCLUDE_DIR gst/gst.h + PATHS ${GSTREAMER_DIR}/include /usr/local/include/gstreamer-1.0 /usr/include/gstreamer-1.0 + ENV INCLUDE DOC "Directory containing gst/gst.h include file") + +FIND_PATH(GSTREAMER_gstconfig_INCLUDE_DIR gst/gstconfig.h + PATHS ${GSTREAMER_DIR}/include ${GSTREAMER_DIR}/lib/include /usr/local/include/gstreamer-1.0 /usr/include/gstreamer-1.0 /usr/local/lib/include/gstreamer-1.0 /usr/lib/include/gstreamer-1.0 + ENV INCLUDE DOC "Directory containing gst/gstconfig.h include file") + +FIND_LIBRARY(GSTREAMER_gstaudio_LIBRARY NAMES gstaudio-1.0 libgstaudio-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstaudio library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstapp_LIBRARY NAMES gstapp-1.0 libgstapp-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstapp library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstbase_LIBRARY NAMES gstbase-1.0 libgstbase-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstbase library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GLIB_gstcdda_LIBRARY NAMES gstcdda-1.0 libgstcdda-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstcdda library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstcontroller_LIBRARY NAMES gstcontroller-1.0 libgstcontroller-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstcontroller library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstdataprotocol_LIBRARY NAMES gstdataprotocol-1.0 libgstdataprotocol-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstdataprotocol library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstinterfaces_LIBRARY NAMES gstinterfaces-1.0 libgstinterfaces-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstinterfaces library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstnet_LIBRARY NAMES gstnet-1.0 libgstnet-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstnet library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstnetbuffer_LIBRARY NAMES gstnetbuffer-1.0 libgstnetbuffer-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstnetbuffer library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstpbutils_LIBRARY NAMES gstpbutils-1.0 libgstpbutils-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstpbutils library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstreamer_LIBRARY NAMES gstreamer-1.0 libgstreamer-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstreamer library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstriff_LIBRARY NAMES gstriff-1.0 libgstriff-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstriff library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstrtp_LIBRARY NAMES gstrtp-1.0 libgstrtp-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstrtp library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstrtsp_LIBRARY NAMES gstrtsp-1.0 libgstrtsp-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstrtsp library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstsdp_LIBRARY NAMES gstsdp-1.0 libgstsdp-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstsdp library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gsttag_LIBRARY NAMES gsttag-1.0 libgsttag-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gsttag library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + +FIND_LIBRARY(GSTREAMER_gstvideo_LIBRARY NAMES gstvideo-1.0 libgstvideo-1.0 + PATHS ${GSTREAMER_DIR}/bin ${GSTREAMER_DIR}/win32/bin ${GSTREAMER_DIR}/bin/bin C:/gstreamer/bin ${GSTREAMER_DIR}/lib ${GSTREAMER_DIR}/win32/lib /usr/local/lib /usr/lib + ENV LIB + DOC "gstvideo library to link with" + NO_SYSTEM_ENVIRONMENT_PATH) + + +IF (GSTREAMER_gst_INCLUDE_DIR AND GSTREAMER_gstconfig_INCLUDE_DIR AND + GSTREAMER_gstaudio_LIBRARY AND GSTREAMER_gstbase_LIBRARY AND GSTREAMER_gstcontroller_LIBRARY AND + GSTREAMER_gstdataprotocol_LIBRARY AND GSTREAMER_gstinterfaces_LIBRARY AND GSTREAMER_gstnet_LIBRARY AND + GSTREAMER_gstnetbuffer_LIBRARY AND GSTREAMER_gstpbutils_LIBRARY AND GSTREAMER_gstreamer_LIBRARY AND + GSTREAMER_gstriff_LIBRARY AND GSTREAMER_gstrtp_LIBRARY AND GSTREAMER_gstrtsp_LIBRARY AND GSTREAMER_gstsdp_LIBRARY AND + GSTREAMER_gsttag_LIBRARY AND GSTREAMER_gstvideo_LIBRARY) + SET(GSTREAMER_INCLUDE_DIR ${GSTREAMER_gst_INCLUDE_DIR} ${GSTREAMER_gstconfig_INCLUDE_DIR}) + list(REMOVE_DUPLICATES GSTREAMER_INCLUDE_DIR) + SET(GSTREAMER_LIBRARIES ${GSTREAMER_gstaudio_LIBRARY} ${GSTREAMER_gstbase_LIBRARY} + ${GSTREAMER_gstcontroller_LIBRARY} ${GSTREAMER_gstdataprotocol_LIBRARY} ${GSTREAMER_gstinterfaces_LIBRARY} + ${GSTREAMER_gstnet_LIBRARY} ${GSTREAMER_gstnetbuffer_LIBRARY} ${GSTREAMER_gstpbutils_LIBRARY} + ${GSTREAMER_gstreamer_LIBRARY} ${GSTREAMER_gstriff_LIBRARY} ${GSTREAMER_gstrtp_LIBRARY} + ${GSTREAMER_gstrtsp_LIBRARY} ${GSTREAMER_gstsdp_LIBRARY} ${GSTREAMER_gsttag_LIBRARY} ${GSTREAMER_gstvideo_LIBRARY}) + list(REMOVE_DUPLICATES GSTREAMER_LIBRARIES) + SET(GSTREAMER_FOUND TRUE) +ENDIF (GSTREAMER_gst_INCLUDE_DIR AND GSTREAMER_gstconfig_INCLUDE_DIR AND + GSTREAMER_gstaudio_LIBRARY AND GSTREAMER_gstbase_LIBRARY AND GSTREAMER_gstcontroller_LIBRARY AND + GSTREAMER_gstdataprotocol_LIBRARY AND GSTREAMER_gstinterfaces_LIBRARY AND GSTREAMER_gstnet_LIBRARY AND + GSTREAMER_gstnetbuffer_LIBRARY AND GSTREAMER_gstpbutils_LIBRARY AND GSTREAMER_gstreamer_LIBRARY AND + GSTREAMER_gstriff_LIBRARY AND GSTREAMER_gstrtp_LIBRARY AND GSTREAMER_gstrtsp_LIBRARY AND GSTREAMER_gstsdp_LIBRARY AND + GSTREAMER_gsttag_LIBRARY AND GSTREAMER_gstvideo_LIBRARY) diff --git a/tools/cmake/modules/FindLibXML2.cmake b/tools/cmake/modules/FindLibXML2.cmake new file mode 100644 index 0000000000..1daaeb07b7 --- /dev/null +++ b/tools/cmake/modules/FindLibXML2.cmake @@ -0,0 +1,20 @@ +find_path(LibXML2_ROOT_DIR NAMES include/libxml2/libxml/xpath.h) +find_library(LibXML2_LIBRARIES + NAMES xml2 + HINTS ${LibXML2_ROOT_DIR}/lib +) +find_path(LibXML2_INCLUDE_DIR + NAMES libxml/tree.h + HINTS ${LibXML2_ROOT_DIR}/include/libxml2 +) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibXML2 DEFAULT_MSG + LibXML2_LIBRARIES + LibXML2_INCLUDE_DIR +) + +mark_as_advanced( + LibXML2_ROOT_DIR + LibXML2_LIBRARIES + LibXML2_INCLUDE_DIR +) \ No newline at end of file diff --git a/tools/cmake/modules/FindQt5Core.cmake b/tools/cmake/modules/FindQt5Core.cmake new file mode 100644 index 0000000000..1a2ad84842 --- /dev/null +++ b/tools/cmake/modules/FindQt5Core.cmake @@ -0,0 +1,10 @@ +execute_process( + COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5CoreConfig.cmake + OUTPUT_VARIABLE config_file +) + +if(config_file STREQUAL "") + message(FATAL_ERROR "Qt5 Core module not found") +endif(config_file STREQUAL "") + +include(${config_file}) diff --git a/tools/cmake/modules/FindQt5DBus.cmake b/tools/cmake/modules/FindQt5DBus.cmake new file mode 100644 index 0000000000..d850010e97 --- /dev/null +++ b/tools/cmake/modules/FindQt5DBus.cmake @@ -0,0 +1,10 @@ +execute_process( + COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5DBusConfig.cmake + OUTPUT_VARIABLE config_file +) + +if(config_file STREQUAL "") + message(FATAL_ERROR "Qt5 DBus module not found") +endif(config_file STREQUAL "") + +include(${config_file}) diff --git a/tools/cmake/modules/FindQt5Qml.cmake b/tools/cmake/modules/FindQt5Qml.cmake new file mode 100644 index 0000000000..f4bdaa8f71 --- /dev/null +++ b/tools/cmake/modules/FindQt5Qml.cmake @@ -0,0 +1,10 @@ +execute_process( + COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5QmlConfig.cmake + OUTPUT_VARIABLE config_file +) + +if(config_file STREQUAL "") + message(FATAL_ERROR "Qt5 Qml module not found") +endif(config_file STREQUAL "") + +include(${config_file}) diff --git a/tools/cmake/modules/FindQt5Quick.cmake b/tools/cmake/modules/FindQt5Quick.cmake new file mode 100644 index 0000000000..1e16340c2e --- /dev/null +++ b/tools/cmake/modules/FindQt5Quick.cmake @@ -0,0 +1,10 @@ +execute_process( + COMMAND ${CMAKE_SOURCE_DIR}/FindQt.sh -v ${qt_version} Qt5QuickConfig.cmake + OUTPUT_VARIABLE config_file +) + +if(config_file STREQUAL "") + message(FATAL_ERROR "Qt5 Quick module not found") +endif(config_file STREQUAL "") + +include(${config_file}) diff --git a/tools/cmake/modules/FindSDLGstreamer.cmake b/tools/cmake/modules/FindSDLGstreamer.cmake new file mode 100644 index 0000000000..515404d39b --- /dev/null +++ b/tools/cmake/modules/FindSDLGstreamer.cmake @@ -0,0 +1,42 @@ +# - Try to find Gstreamer +# +# GSTREAMER_INCLUDE_DIRECTORY - the Gstreamer include directory +# GSTREAMER_LIBRARIES - the Gstreamer libraries + +get_os(OS) +if(${OS} STREQUAL "posix") + find_package(Gstreamer-1.0 REQUIRED) + find_package(Glib-2.0 REQUIRED) + find_package(PkgConfig) + pkg_check_modules(GLIB2 REQUIRED glib-2.0) + add_definitions(${GLIB2_CFLAGS}) + set(GSTREAMER_INCLUDE_DIRECTORY + ${GSTREAMER_gst_INCLUDE_DIR} + ${GLIB_glib_2_INCLUDE_DIR} + ) + set(GSTREAMER_LIBRARIES + ${GSTREAMER_gstreamer_LIBRARY} + gobject-2.0 + glib-2.0 + ) +elseif(${OS} STREQUAL "win") + get_sdk(SDK) + if(NOT SDK) + if(EXISTS $ENV{SDL_GSTREAMER_DIR}) + set(GSTREAMER_DIR $ENV{SDL_GSTREAMER_DIR}) + else() + message(FATAL_ERROR "Could not find GSTREAMER (Check SDL_GSTREAMER_DIR environment variable)") + endif() + set(GSTREAMER_INCLUDE_DIRECTORY + ${GSTREAMER_DIR}/include/gstreamer-0.10 + ${GSTREAMER_DIR}/include/libxml2 + ${GSTREAMER_DIR}/include/glib-2.0 + ${GSTREAMER_DIR}/lib/glib-2.0/include + ) + set(GSTREAMER_LIBRARIES + ${GSTREAMER_DIR}/lib/gstreamer-0.10.lib + ${GSTREAMER_DIR}/lib/glib-2.0.lib + ${GSTREAMER_DIR}/lib/gobject-2.0.lib + ) + endif() +endif() diff --git a/tools/cmake/modules/FindSDLLibUSB.cmake b/tools/cmake/modules/FindSDLLibUSB.cmake new file mode 100644 index 0000000000..0082d62315 --- /dev/null +++ b/tools/cmake/modules/FindSDLLibUSB.cmake @@ -0,0 +1,19 @@ +# - Try to find libusb +# +# LIBUSB_INCLUDE_DIRECTORY - the libusb include directory +# LIBUSB_LIBRARIES - libusb libraries to link + +get_os(OS) +if(${OS} STREQUAL "posix") + set(LIBUSB_INCLUDE_DIRECTORY /usr/include/libusb-1.0) + set(LIBUSB_LIBRARIES usb-1.0 udev) +elseif(${OS} STREQUAL "win") + get_arch(ARCH) + if(${ARCH} STREQUAL "x86") + set(LIBUSB_DIR ${CMAKE_SOURCE_DIR}/build/libusbx_win_x86) + elseif(${ARCH} STREQUAL "x64") + set(LIBUSB_DIR ${CMAKE_SOURCE_DIR}/build/libusbx_win_x64) + endif() + set(LIBUSB_INCLUDE_DIRECTORY ${LIBUSB_DIR}/libusb) + set(LIBUSB_LIBRARIES ${LIBUSB_DIR}/bin/libusb-1.0.lib) +endif() diff --git a/tools/cmake/modules/FindSDLOpenSSL.cmake b/tools/cmake/modules/FindSDLOpenSSL.cmake new file mode 100644 index 0000000000..c16236a1cb --- /dev/null +++ b/tools/cmake/modules/FindSDLOpenSSL.cmake @@ -0,0 +1,18 @@ +# - Try to find OpenSSL +# +# OPENSSL_INCLUDE_DIRECTORY - the OpenSSL include directory +# OPENSSL_LIBRARIES - the OpenSSL libraries + +get_os(OS) +if(${OS} STREQUAL "posix") + find_package(OpenSSL REQUIRED) +elseif(${OS} STREQUAL "win") + get_arch(ARCH) + if(${ARCH} STREQUAL "x86") + set(OPENSSL_DIR ${CMAKE_SOURCE_DIR}/build/openssl_win_x86) + elseif(${ARCH} STREQUAL "x64") + set(OPENSSL_DIR ${CMAKE_SOURCE_DIR}/build/openssl_win_x64) + endif() + set(OPENSSL_INCLUDE_DIRECTORY ${OPENSSL_DIR}/include) + set(OPENSSL_LIBRARIES ${OPENSSL_DIR}/lib/libeay32.lib ${OPENSSL_DIR}/lib/ssleay32.lib) +endif() diff --git a/tools/cmake/modules/FindSDLSqlite3.cmake b/tools/cmake/modules/FindSDLSqlite3.cmake new file mode 100644 index 0000000000..1338ef297f --- /dev/null +++ b/tools/cmake/modules/FindSDLSqlite3.cmake @@ -0,0 +1,15 @@ +# - Try to find Sqlite3 +# +# SQLITE3_INCLUDE_DIRECTORY - the Sqlite3 include directory +# SQLITE3_LIBRARIES - the Sqlite3 libraries + +get_os(OS) +if(${OS} STREQUAL "posix") + find_package(Sqlite3 REQUIRED) +elseif(${OS} STREQUAL "win") + get_sdk(SDK) + if(NOT SDK OR NOT ${SDK} STREQUAL "qt") + set(SQLITE3_INCLUDE_DIRECTORY $ENV{SDL_SQLITE_DIR}) + set(SQLITE3_LIBRARIES $ENV{SDL_SQLITE_DIR}/sqlite3.lib) + endif() +endif() diff --git a/tools/cmake/modules/FindSqlite3.cmake b/tools/cmake/modules/FindSqlite3.cmake new file mode 100644 index 0000000000..f6bdcad69c --- /dev/null +++ b/tools/cmake/modules/FindSqlite3.cmake @@ -0,0 +1,81 @@ +# - Try to find Sqlite3 +# Once done this will define +# +# SQLITE3_FOUND - system has Sqlite3 +# SQLITE3_INCLUDE_DIRS - the Sqlite3 include directory +# SQLITE3_LIBRARIES - Link these to use Sqlite3 +# SQLITE3_DEFINITIONS - Compiler switches required for using Sqlite3 +# +# Copyright (c) 2008 Andreas Schneider +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# + + +if (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS) + set(SQLITE3_FOUND TRUE) +else (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS) + find_package(PkgConfig) + if (PKG_CONFIG_FOUND) + pkg_check_modules(_SQLITE3 REQUIRED sqlite3>=3.7.11) + else (PKG_CONFIG_FOUND) + message(WARNING "PkgConfig isn't installed. You need to sure sqlite3>=3.7.11") + endif (PKG_CONFIG_FOUND) + + find_path(SQLITE3_INCLUDE_DIR + NAMES + sqlite3.h + PATHS + ${_SQLITE3_INCLUDEDIR} + /usr/include + /usr/local/include + /opt/local/include + /sw/include + ) + + find_library(SQLITE3_LIBRARY + NAMES + sqlite3 + PATHS + ${_SQLITE3_LIBDIR} + /usr/lib + /usr/local/lib + /opt/local/lib + /sw/lib + ) + + if (SQLITE3_LIBRARY) + set(SQLITE3_FOUND TRUE) + endif (SQLITE3_LIBRARY) + + set(SQLITE3_INCLUDE_DIRS + ${SQLITE3_INCLUDE_DIR} + ) + + if (SQLITE3_FOUND) + set(SQLITE3_LIBRARIES + ${SQLITE3_LIBRARIES} + ${SQLITE3_LIBRARY} + ) + endif (SQLITE3_FOUND) + + if (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES) + set(SQLITE3_FOUND TRUE) + endif (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES) + + if (SQLITE3_FOUND) + if (NOT Sqlite3_FIND_QUIETLY) + message(STATUS "Found Sqlite3: ${SQLITE3_LIBRARIES}") + endif (NOT Sqlite3_FIND_QUIETLY) + else (SQLITE3_FOUND) + if (Sqlite3_FIND_REQUIRED) + message(FATAL_ERROR "Could not find Sqlite3") + endif (Sqlite3_FIND_REQUIRED) + endif (SQLITE3_FOUND) + + # show the SQLITE3_INCLUDE_DIRS and SQLITE3_LIBRARIES variables only in the advanced view + mark_as_advanced(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES) + +endif (SQLITE3_LIBRARIES AND SQLITE3_INCLUDE_DIRS) \ No newline at end of file diff --git a/tools/cmake/modules/FindUDev.cmake b/tools/cmake/modules/FindUDev.cmake new file mode 100644 index 0000000000..cdc8743777 --- /dev/null +++ b/tools/cmake/modules/FindUDev.cmake @@ -0,0 +1,53 @@ +# razor-de: Configure libudev environment +# +# UDEV_FOUND - system has a libudev +# UDEV_INCLUDE_DIR - where to find header files +# UDEV_LIBRARIES - the libraries to link against udev +# UDEV_STABLE - it's true when is the version greater or equals to 143 - version when the libudev was stabilized in its API +# +# copyright (c) 2011 Petr Vanek +# Redistribution and use is allowed according to the terms of the BSD license. +# + +FIND_PATH( + UDEV_INCLUDE_DIR + libudev.h + /usr/include + /usr/local/include + ${UDEV_PATH_INCLUDES} +) + +FIND_LIBRARY( + UDEV_LIBRARIES + NAMES udev libudev + PATHS + /usr/lib${LIB_SUFFIX} + /usr/local/lib${LIB_SUFFIX} + ${UDEV_PATH_LIB} +) + +IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR) + SET(UDEV_FOUND "YES") + execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE) + # retvale is 0 of the condition is "true" so we need to negate the value... + if (UDEV_STABLE) +set(UDEV_STABLE 0) + else (UDEV_STABLE) +set(UDEV_STABLE 1) + endif (UDEV_STABLE) + message(STATUS "libudev stable: ${UDEV_STABLE}") +ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR) + +IF (UDEV_FOUND) + MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}") + MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}") +ELSE (UDEV_FOUND) + MESSAGE(STATUS "UDev not found.") + MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include") + MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}") + MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib") + MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}") + IF (UDev_FIND_REQUIRED) + MESSAGE(FATAL_ERROR "Could not find UDev library") + ENDIF (UDev_FIND_REQUIRED) +ENDIF (UDEV_FOUND) \ No newline at end of file diff --git a/tools/intergen/test/CMakeLists.txt b/tools/intergen/test/CMakeLists.txt index f8af75c3bf..27d506443e 100644 --- a/tools/intergen/test/CMakeLists.txt +++ b/tools/intergen/test/CMakeLists.txt @@ -76,10 +76,10 @@ if (${HMI_DBUS_API}) ${CMAKE_SOURCE_DIR}/src/components/dbus/include ${DBUS_INCLUDE_DIRS} ) - set (LIBRARIES ${LIBRARIES} DBus) + set (LIBRARIES ${LIBRARIES} dbus) set (SOURCES ${SOURCES} generated_interface_dbus_tests.cc) endif () create_test(test_generated_interface "${SOURCES}" "${LIBRARIES}") -endif() \ No newline at end of file +endif() -- cgit v1.2.1