From ce75c3d19e620d43bcbc3682999a77a5680691f5 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Mon, 15 Feb 2016 20:10:51 +0100 Subject: [PATCH 1/7] Don't leak asio headers from libremote-processor Wrap some classes and forward-declare some others in other not to expose any asio object in the public interfaces. This means that client (such as libparameter) will now be completely unaware of asio. Signed-off-by: David Wagner --- remote-process/main.cpp | 5 +- ...BackgroundRemoteProcessorServerBuilder.cpp | 64 +++++++++++++++++++ .../BackgroundRemoteProcessorServerBuilder.h | 41 ++++-------- remote-processor/CMakeLists.txt | 11 ++-- remote-processor/Message.cpp | 26 ++++---- remote-processor/Message.h | 6 +- remote-processor/RemoteProcessorServer.cpp | 3 +- remote-processor/Socket.h | 41 ++++++++++++ test/test-platform/CMakeLists.txt | 2 + 9 files changed, 149 insertions(+), 50 deletions(-) create mode 100644 remote-processor/BackgroundRemoteProcessorServerBuilder.cpp create mode 100644 remote-processor/Socket.h diff --git a/remote-process/main.cpp b/remote-process/main.cpp index ef202e324..3ebaa86b3 100644 --- a/remote-process/main.cpp +++ b/remote-process/main.cpp @@ -36,6 +36,7 @@ #include #include "RequestMessage.h" #include "AnswerMessage.h" +#include "Socket.h" using namespace std; @@ -43,7 +44,7 @@ bool sendAndDisplayCommand(asio::ip::tcp::socket &socket, CRequestMessage &reque { string strError; - if (requestMessage.serialize(socket, true, strError) != CRequestMessage::success) { + if (requestMessage.serialize(Socket(socket), true, strError) != CRequestMessage::success) { cerr << "Unable to send command to target: " << strError << endl; return false; @@ -51,7 +52,7 @@ bool sendAndDisplayCommand(asio::ip::tcp::socket &socket, CRequestMessage &reque ///// Get answer CAnswerMessage answerMessage; - if (answerMessage.serialize(socket, false, strError) != CRequestMessage::success) { + if (answerMessage.serialize(Socket(socket), false, strError) != CRequestMessage::success) { cerr << "Unable to received answer from target: " << strError << endl; return false; diff --git a/remote-processor/BackgroundRemoteProcessorServerBuilder.cpp b/remote-processor/BackgroundRemoteProcessorServerBuilder.cpp new file mode 100644 index 000000000..48317cc68 --- /dev/null +++ b/remote-processor/BackgroundRemoteProcessorServerBuilder.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 "BackgroundRemoteProcessorServerBuilder.h" +#include "RemoteProcessorServer.h" + +BackgroundRemoteProcessorServer::BackgroundRemoteProcessorServer( + uint16_t uiPort, std::unique_ptr &&commandHandler) + : _server(new CRemoteProcessorServer(uiPort)), mCommandHandler(std::move(commandHandler)) +{ +} + +bool BackgroundRemoteProcessorServer::start(std::string &error) +{ + if (!_server->start(error)) { + return false; + } + try { + mServerSuccess = std::async(std::launch::async, &CRemoteProcessorServer::process, + _server.get(), std::ref(*mCommandHandler)); + } catch (std::exception &e) { + error = "Could not create a remote processor thread: " + std::string(e.what()); + return false; + } + + return true; +} + +bool BackgroundRemoteProcessorServer::stop() +{ + _server->stop(); + return mServerSuccess.get(); +} + +BackgroundRemoteProcessorServer::~BackgroundRemoteProcessorServer() +{ + stop(); +} diff --git a/remote-processor/BackgroundRemoteProcessorServerBuilder.h b/remote-processor/BackgroundRemoteProcessorServerBuilder.h index cebbad0bf..1c17fca82 100644 --- a/remote-processor/BackgroundRemoteProcessorServerBuilder.h +++ b/remote-processor/BackgroundRemoteProcessorServerBuilder.h @@ -27,45 +27,30 @@ * (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 "RemoteProcessorServer.h" +#include "RemoteProcessorServerInterface.h" +#include "RemoteCommandHandler.h" #include #include -class BackgroundRemoteProcessorServer final : public IRemoteProcessorServerInterface +#include "remote_processor_export.h" + +class CRemoteProcessorServer; + +class REMOTE_PROCESSOR_EXPORT BackgroundRemoteProcessorServer final + : public IRemoteProcessorServerInterface { public: BackgroundRemoteProcessorServer(uint16_t uiPort, - std::unique_ptr &&commandHandler) - : _server(uiPort), mCommandHandler(std::move(commandHandler)) - { - } - - ~BackgroundRemoteProcessorServer() { stop(); } + std::unique_ptr &&commandHandler); - bool start(std::string &error) override - { - if (!_server.start(error)) { - return false; - } - try { - mServerSuccess = std::async(std::launch::async, &CRemoteProcessorServer::process, - &_server, std::ref(*mCommandHandler)); - } catch (std::exception &e) { - error = "Could not create a remote processor thread: " + std::string(e.what()); - return false; - } + ~BackgroundRemoteProcessorServer(); - return true; - } + bool start(std::string &error) override; - bool stop() override - { - _server.stop(); - return mServerSuccess.get(); - } + bool stop() override; private: - CRemoteProcessorServer _server; + std::unique_ptr _server; std::unique_ptr mCommandHandler; std::future mServerSuccess; }; diff --git a/remote-processor/CMakeLists.txt b/remote-processor/CMakeLists.txt index 774927973..b7d50fbd8 100644 --- a/remote-processor/CMakeLists.txt +++ b/remote-processor/CMakeLists.txt @@ -30,7 +30,8 @@ add_library(remote-processor SHARED Message.cpp RequestMessage.cpp AnswerMessage.cpp - RemoteProcessorServer.cpp) + RemoteProcessorServer.cpp + BackgroundRemoteProcessorServerBuilder.cpp) include(GenerateExportHeader) generate_export_header(remote-processor @@ -39,21 +40,19 @@ generate_export_header(remote-processor set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads REQUIRED) -# Find ASIO (the standalone version, not Boost) and declare it as a dependency -# for remote-processor's users too. (FIXME: this should not be the case) +# Find ASIO (the standalone version, not Boost) # If asio isn't installed in a standard directory, add the correct directory to # CMAKE_PREFIX_PATH (see the main README for more information). find_path(ASIO_DIR NAMES asio.hpp) # Hide this variable from CMake GUIs and `cmake -L` set_property(CACHE ASIO_DIR PROPERTY ADVANCED TRUE) -# FIXME: asio header should not leak to remote-processor users -target_include_directories(remote-processor SYSTEM PUBLIC "${ASIO_DIR}") +target_include_directories(remote-processor SYSTEM PRIVATE "${ASIO_DIR}") # Ubuntu 14.04 packages asio 1.10.1 and clang 3.4.1. # In this environment, asio stand alone (set ASIO_STANDALONE) # does not correcly detect that the stl has CHRONO support (c++11). # Force the use of std::chrono by setting ASIO_HAS_STD_CHRONO -target_compile_definitions(remote-processor PUBLIC ASIO_STANDALONE ASIO_HAS_STD_CHRONO) +target_compile_definitions(remote-processor PRIVATE ASIO_STANDALONE ASIO_HAS_STD_CHRONO) target_include_directories(remote-processor # Symbol export macro header diff --git a/remote-processor/Message.cpp b/remote-processor/Message.cpp index af7556120..66154ec8b 100644 --- a/remote-processor/Message.cpp +++ b/remote-processor/Message.cpp @@ -28,7 +28,9 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "Message.h" +#include "Socket.h" #include "Iterator.hpp" +#include #include #include #include @@ -125,8 +127,10 @@ size_t CMessage::getRemainingDataSize() const } // Send/Receive -CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, string &strError) +CMessage::Result CMessage::serialize(Socket &&socket, bool bOut, string &strError) { + asio::ip::tcp::socket &asioSocket = socket.get(); + if (bOut) { asio::error_code ec; @@ -142,7 +146,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // First send sync word uint16_t uiSyncWord = SYNC_WORD; - if (!asio::write(socket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { if (ec == asio::error::eof) { return peerDisconnected; @@ -153,21 +157,21 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Size uint32_t uiSize = (uint32_t)(sizeof(_ucMsgId) + getMessageDataSize()); - if (!asio::write(socket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { strError += string("Size write failed: ") + ec.message(); return error; } // Msg Id - if (!asio::write(socket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { strError += string("Msg write failed: ") + ec.message(); return error; } // Data - if (!asio::write(socket, asio::buffer(mData), ec)) { + if (!asio::write(asioSocket, asio::buffer(mData), ec)) { strError = string("Data write failed: ") + ec.message(); return error; @@ -176,7 +180,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Checksum uint8_t ucChecksum = computeChecksum(); - if (!asio::write(socket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { + if (!asio::write(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { strError = string("Checksum write failed: ") + ec.message(); return error; @@ -187,7 +191,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s uint16_t uiSyncWord = 0; asio::error_code ec; - if (!asio::read(socket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&uiSyncWord, sizeof(uiSyncWord)), ec)) { strError = string("Sync read failed: ") + ec.message(); if (ec == asio::error::eof) { return peerDisconnected; @@ -205,13 +209,13 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Size uint32_t uiSize = 0; - if (!asio::read(socket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&uiSize, sizeof(uiSize)), ec)) { strError = string("Size read failed: ") + ec.message(); return error; } // Msg Id - if (!asio::read(socket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&_ucMsgId, sizeof(_ucMsgId)), ec)) { strError = string("Msg id read failed: ") + ec.message(); return error; } @@ -222,7 +226,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s allocateData(uiSize - sizeof(_ucMsgId)); // Data receive - if (!asio::read(socket, asio::buffer(mData), ec)) { + if (!asio::read(asioSocket, asio::buffer(mData), ec)) { strError = string("Data read failed: ") + ec.message(); return error; } @@ -230,7 +234,7 @@ CMessage::Result CMessage::serialize(asio::ip::tcp::socket &socket, bool bOut, s // Checksum uint8_t ucChecksum = 0; - if (!asio::read(socket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { + if (!asio::read(asioSocket, asio::buffer(&ucChecksum, sizeof(ucChecksum)), ec)) { strError = string("Checksum read failed: ") + ec.message(); return error; } diff --git a/remote-processor/Message.h b/remote-processor/Message.h index ead2743c2..2a596f113 100644 --- a/remote-processor/Message.h +++ b/remote-processor/Message.h @@ -30,12 +30,14 @@ #pragma once #include "NonCopyable.hpp" -#include +#include #include #include #include +class Socket; + class REMOTE_PROCESSOR_EXPORT CMessage : private utility::NonCopyable { public: @@ -69,7 +71,7 @@ class REMOTE_PROCESSOR_EXPORT CMessage : private utility::NonCopyable * peerDisconnected if the peer disconnected before the first socket access. * error if the message could not be read/write for any other reason */ - Result serialize(asio::ip::tcp::socket &socket, bool bOut, std::string &strError); + Result serialize(Socket &&socket, bool bOut, std::string &strError); protected: // Msg Id diff --git a/remote-processor/RemoteProcessorServer.cpp b/remote-processor/RemoteProcessorServer.cpp index 4fac086c1..d3fefddcb 100644 --- a/remote-processor/RemoteProcessorServer.cpp +++ b/remote-processor/RemoteProcessorServer.cpp @@ -35,6 +35,7 @@ #include "RequestMessage.h" #include "AnswerMessage.h" #include "RemoteCommandHandler.h" +#include "Socket.h" using std::string; @@ -126,7 +127,7 @@ void CRemoteProcessorServer::handleNewConnection(IRemoteCommandHandler &commandH string strError; ///// Receive command CRequestMessage::Result res; - res = requestMessage.serialize(_socket, false, strError); + res = requestMessage.serialize(Socket(_socket), false, strError); switch (res) { case CRequestMessage::error: diff --git a/remote-processor/Socket.h b/remote-processor/Socket.h new file mode 100644 index 000000000..4acf3983e --- /dev/null +++ b/remote-processor/Socket.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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 + +class Socket +{ +public: + Socket(asio::ip::tcp::socket &socket) : mSocket(socket) {} + + asio::ip::tcp::socket &get() { return mSocket; } + +private: + asio::ip::tcp::socket &mSocket; +}; diff --git a/test/test-platform/CMakeLists.txt b/test/test-platform/CMakeLists.txt index cef284f27..d94d4edac 100644 --- a/test/test-platform/CMakeLists.txt +++ b/test/test-platform/CMakeLists.txt @@ -32,5 +32,7 @@ add_executable(test-platform target_link_libraries(test-platform PRIVATE parameter pfw_utility remote-processor) +# Workaround because asio is still leaking to test-platform +target_link_libraries(test-platform PRIVATE asio) install(TARGETS test-platform RUNTIME DESTINATION bin) From c062b3e099e7506efe7e2fe46982d51a2c0320de Mon Sep 17 00:00:00 2001 From: David Wagner Date: Tue, 16 Feb 2016 09:15:12 +0100 Subject: [PATCH 2/7] BackgroundRemoteProcessorServer: rename header and source files to match class name Signed-off-by: David Wagner --- parameter/ParameterMgr.cpp | 2 +- ...erverBuilder.cpp => BackgroundRemoteProcessorServer.cpp} | 2 +- ...sorServerBuilder.h => BackgroundRemoteProcessorServer.h} | 0 remote-processor/CMakeLists.txt | 2 +- remote-processor/Socket.h | 6 ++++++ 5 files changed, 9 insertions(+), 3 deletions(-) rename remote-processor/{BackgroundRemoteProcessorServerBuilder.cpp => BackgroundRemoteProcessorServer.cpp} (97%) rename remote-processor/{BackgroundRemoteProcessorServerBuilder.h => BackgroundRemoteProcessorServer.h} (100%) diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp index dd6724527..3b2d182d5 100644 --- a/parameter/ParameterMgr.cpp +++ b/parameter/ParameterMgr.cpp @@ -67,7 +67,7 @@ #include "BitParameterType.h" #include "StringParameterType.h" #include "EnumParameterType.h" -#include "BackgroundRemoteProcessorServerBuilder.h" +#include "BackgroundRemoteProcessorServer.h" #include "ElementLocator.h" #include "CompoundRule.h" #include "SelectionCriterionRule.h" diff --git a/remote-processor/BackgroundRemoteProcessorServerBuilder.cpp b/remote-processor/BackgroundRemoteProcessorServer.cpp similarity index 97% rename from remote-processor/BackgroundRemoteProcessorServerBuilder.cpp rename to remote-processor/BackgroundRemoteProcessorServer.cpp index 48317cc68..08207864c 100644 --- a/remote-processor/BackgroundRemoteProcessorServerBuilder.cpp +++ b/remote-processor/BackgroundRemoteProcessorServer.cpp @@ -27,7 +27,7 @@ * (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 "BackgroundRemoteProcessorServerBuilder.h" +#include "BackgroundRemoteProcessorServer.h" #include "RemoteProcessorServer.h" BackgroundRemoteProcessorServer::BackgroundRemoteProcessorServer( diff --git a/remote-processor/BackgroundRemoteProcessorServerBuilder.h b/remote-processor/BackgroundRemoteProcessorServer.h similarity index 100% rename from remote-processor/BackgroundRemoteProcessorServerBuilder.h rename to remote-processor/BackgroundRemoteProcessorServer.h diff --git a/remote-processor/CMakeLists.txt b/remote-processor/CMakeLists.txt index b7d50fbd8..5578ee4bf 100644 --- a/remote-processor/CMakeLists.txt +++ b/remote-processor/CMakeLists.txt @@ -31,7 +31,7 @@ add_library(remote-processor SHARED RequestMessage.cpp AnswerMessage.cpp RemoteProcessorServer.cpp - BackgroundRemoteProcessorServerBuilder.cpp) + BackgroundRemoteProcessorServer.cpp) include(GenerateExportHeader) generate_export_header(remote-processor diff --git a/remote-processor/Socket.h b/remote-processor/Socket.h index 4acf3983e..020750bad 100644 --- a/remote-processor/Socket.h +++ b/remote-processor/Socket.h @@ -29,6 +29,12 @@ */ #include +/** Wraps and hides asio::ip::tcp::socket + * + * asio::ip::tcp::socket cannot be forward-declared because it is an + * inner-class. This class wraps the asio class in order for it to be + * forward-declared and avoid it to leak in client interfaces. + */ class Socket { public: From 3908a454ad6a8ed7d8a4485f4a18d626b1d06905 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Mon, 22 Feb 2016 11:55:53 +0100 Subject: [PATCH 3/7] CMake: update to CMake 3.x and clarify requirements We need CMake 3.x in order to have "interface" libraries (libs with no build instructions but useful for usage requirement forwarding of header-only libraries). Signed-off-by: David Wagner --- .travis.yml | 6 +++--- CMakeLists.txt | 8 +++++--- README.md | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 34ed0e7d1..5a7a5cc0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,8 +14,7 @@ compiler: # it will not be necessary once travis worker is based on ubuntu > 12.04. # Install SWIG for bindings generation # Install valgrind for memcheck tests -# Adding kubuntu-backports ppa for for cmake 2.8.12. -# it is needed in case of multiple python version on host +# Adding george-edison55-precise-backports ppa for for cmake 3.x. # Install python3-dev for the client simulator addons: apt: @@ -23,7 +22,7 @@ addons: # https://github.com/travis-ci/apt-source-whitelist/blob/master/ubuntu.json sources: - ubuntu-toolchain-r-test - - kubuntu-backports + - george-edison55-precise-backports - llvm-toolchain-precise # Travis white list of dpkg packages # https://github.com/travis-ci/apt-package-whitelist/blob/master/ubuntu-precise @@ -31,6 +30,7 @@ addons: - swig - valgrind - g++-4.8 + - cmake-data - cmake - python3-dev - libasio-dev diff --git a/CMakeLists.txt b/CMakeLists.txt index e8b5edaaa..3eae677e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,10 +26,12 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# working on 2.8.12 - broken on older versions. +# Known to work with CMake 3.2.2, might work with older 3.x versions, will not +# work with versions prior to 3.0.0. # Visual Studio 14 needs 3.3.0; see https://cmake.org/Bug/print_bug_page.php?bug_id=15552 -cmake_minimum_required(VERSION 2.8.12) -if(CMAKE_GENERATOR STRGREATER "Visual Studio 14 2015") +cmake_minimum_required(VERSION 3.2.2) +if((CMAKE_GENERATOR MATCHES "Visual Studio .*") + AND (CMAKE_GENERATOR STRGREATER "Visual Studio 14 2015")) cmake_minimum_required(VERSION 3.3.0) endif() diff --git a/README.md b/README.md index f5023f882..618981c56 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ sections: In order to compile you'll need, at the very least: -- CMake (v2.8.12 or later) (v3.3.0 or later on Windows); +- CMake (v3.2.2 or later) (v3.3.0 or later on Windows); - A C/C++ compiler supporting C++11; - libxml2 headers and libraries (Provided by the `libxml2-dev` on debian-based distributions); From a36dfe30a3929e14f67b186cb8885b23fbb98341 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Tue, 16 Feb 2016 13:36:40 +0100 Subject: [PATCH 4/7] Allow libremote-processor to be compiled without networking support Introduce an asio stub. In such a case, libremote-processor becomes useless but still acts as if it was working correctly. This is an easy way to have a version of libparameter that does not embed any networking code, which is required in some case for security compliance reasons. This can be achieved by turning the NETWORKING option OFF when configuring the CMake project. Signed-off-by: David Wagner --- CMakeLists.txt | 4 +- asio/CMakeLists.txt | 57 ++++++++++++++++ asio/stub/asio.hpp | 111 ++++++++++++++++++++++++++++++++ remote-process/CMakeLists.txt | 9 +-- remote-processor/CMakeLists.txt | 18 +----- 5 files changed, 175 insertions(+), 24 deletions(-) create mode 100644 asio/CMakeLists.txt create mode 100644 asio/stub/asio.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 3eae677e8..8bf794113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -49,6 +49,7 @@ option(REQUIREMENTS "Generate the html version of the 'requirements' documentati option(PYTHON_BINDINGS "Python library to use the Parameter Framework from python" ON) option(C_BINDINGS "Library to use the Parameter Framework using a C API" ON) option(FATAL_WARNINGS "Turn warnings into errors (-Werror flag)" ON) +option(NETWORKING "Set to OFF in order to stub networking code" ON) include(SetVersion.cmake) @@ -104,6 +105,7 @@ endif() add_subdirectory(xmlserializer) add_subdirectory(parameter) add_subdirectory(utility) +add_subdirectory(asio) add_subdirectory(remote-processor) add_subdirectory(remote-process) diff --git a/asio/CMakeLists.txt b/asio/CMakeLists.txt new file mode 100644 index 000000000..9c0ef115b --- /dev/null +++ b/asio/CMakeLists.txt @@ -0,0 +1,57 @@ +# Copyright (c) 2016, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. 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. +# +# 3. Neither the name of the copyright holder 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. + +add_library(asio INTERFACE) + +if (NETWORKING) + # Find ASIO (the standalone version, not Boost) If asio isn't installed in + # a standard directory, add the correct directory to CMAKE_PREFIX_PATH (see + # the main README for more information). + find_path(ASIO_DIR NAMES asio.hpp) + # Hide this variable from CMake GUIs and `cmake -L` + set_property(CACHE ASIO_DIR PROPERTY ADVANCED TRUE) + if (NOT ASIO_DIR) + message(SEND_ERROR + " ASIO header (asio.hpp) could not be found. + ASIO is used for networking. On Linux, you should install it using your + package manager. On Windows, please refer to the main README.") + endif() + + # Ubuntu 14.04 packages asio 1.10.1 and clang 3.4.1. + # In this environment, asio stand alone (set ASIO_STANDALONE) + # does not correcly detect that the stl has CHRONO support (c++11). + # Force the use of std::chrono by setting ASIO_HAS_STD_CHRONO + target_include_directories(asio SYSTEM INTERFACE "${ASIO_DIR}") + target_link_libraries(asio INTERFACE "${CMAKE_THREAD_LIBS_INIT}") + target_compile_definitions(asio + INTERFACE ASIO_STANDALONE + INTERFACE ASIO_HAS_STD_CHRONO) +else() + # Stubbed version + target_include_directories(asio INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/stub") +endif() diff --git a/asio/stub/asio.hpp b/asio/stub/asio.hpp new file mode 100644 index 000000000..b3145cf9e --- /dev/null +++ b/asio/stub/asio.hpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. 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. + * + * 3. Neither the name of the copyright holder 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. + */ +#pragma once + +/** @file + * + * Stubs ASIO interfaces called by libremote-processor. This is used when + * the user asks for networking support to be compiled out. + */ + +#include + +namespace asio +{ +struct dummy_base +{ + template + dummy_base(Args &&...) + { + } + void set_option(const dummy_base &) const {}; +}; +inline bool write(const dummy_base &, const dummy_base &, const dummy_base &) +{ + return true; +} +inline bool read(const dummy_base &, const dummy_base &, const dummy_base &) +{ + return true; +} +using buffer = dummy_base; +struct io_service : dummy_base +{ + using dummy_base::dummy_base; + + void run(const dummy_base &) const {}; + void stop() const {}; +}; +struct socket_base : dummy_base +{ + using dummy_base::dummy_base; + + using linger = dummy_base; + using enable_connection_aborted = dummy_base; + void close() const {}; +}; + +bool write(const dummy_base &, const dummy_base &, const dummy_base &); +bool read(const dummy_base &, const dummy_base &, const dummy_base &); + +struct error_code : dummy_base, std::error_code +{ +}; +namespace error +{ +static const error_code eof{}; +} + +namespace ip +{ +namespace tcp +{ +using v6 = dummy_base; +using no_delay = dummy_base; +using socket = socket_base; +struct endpoint : dummy_base +{ + using dummy_base::dummy_base; + + dummy_base protocol() const { return {}; }; +}; +struct acceptor : dummy_base +{ + using dummy_base::dummy_base; + + using reuse_address = dummy_base; + void open(const dummy_base &) const {}; + void bind(const dummy_base &) const {}; + void listen() const {}; + void async_accept(const dummy_base &, const dummy_base &) const {}; +}; +} +} +} diff --git a/remote-process/CMakeLists.txt b/remote-process/CMakeLists.txt index dbfb2ebc7..9c4906739 100644 --- a/remote-process/CMakeLists.txt +++ b/remote-process/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -32,11 +32,6 @@ set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads REQUIRED) target_link_libraries(remote-process - PRIVATE remote-processor pfw_utility - # Remote-process does not use thread, - # nevertheless it uses asio resolver wich may use a thread (for async resolve). - # As a result remote-process must link with a thread library although not - # using the corresponding symbols. - PRIVATE "${CMAKE_THREAD_LIBS_INIT}") + PRIVATE remote-processor pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS remote-process RUNTIME DESTINATION bin) diff --git a/remote-processor/CMakeLists.txt b/remote-processor/CMakeLists.txt index 5578ee4bf..ee21f55b6 100644 --- a/remote-processor/CMakeLists.txt +++ b/remote-processor/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2014-2015, Intel Corporation +# Copyright (c) 2014-2016, Intel Corporation # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, @@ -40,26 +40,12 @@ generate_export_header(remote-processor set(CMAKE_THREAD_PREFER_PTHREAD 1) find_package(Threads REQUIRED) -# Find ASIO (the standalone version, not Boost) -# If asio isn't installed in a standard directory, add the correct directory to -# CMAKE_PREFIX_PATH (see the main README for more information). -find_path(ASIO_DIR NAMES asio.hpp) -# Hide this variable from CMake GUIs and `cmake -L` -set_property(CACHE ASIO_DIR PROPERTY ADVANCED TRUE) -target_include_directories(remote-processor SYSTEM PRIVATE "${ASIO_DIR}") - -# Ubuntu 14.04 packages asio 1.10.1 and clang 3.4.1. -# In this environment, asio stand alone (set ASIO_STANDALONE) -# does not correcly detect that the stl has CHRONO support (c++11). -# Force the use of std::chrono by setting ASIO_HAS_STD_CHRONO -target_compile_definitions(remote-processor PRIVATE ASIO_STANDALONE ASIO_HAS_STD_CHRONO) - target_include_directories(remote-processor # Symbol export macro header PUBLIC "${CMAKE_CURRENT_BINARY_DIR}" # TODO: separate remote-processor's includes in half (public/private) PUBLIC .) -target_link_libraries(remote-processor PRIVATE pfw_utility ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(remote-processor PRIVATE pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) install(TARGETS remote-processor LIBRARY DESTINATION lib RUNTIME DESTINATION bin) From b34ba494aec3701f450ceae083698ab2f2721b42 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Tue, 16 Feb 2016 18:00:32 +0100 Subject: [PATCH 5/7] Stubbed networking: prevent buiding and running tuning code Compile-out test-platform and remote-process when NETWORKING==OFF. Also, have the Parameter Framework fail to start if the user requested the remote interface to be started but compiled networking support out at the same time. Signed-off-by: David Wagner --- asio/stub/asio.hpp | 8 +++++++- parameter/ParameterMgr.cpp | 9 +++++++-- remote-process/CMakeLists.txt | 14 ++++++++------ test/functional-tests-legacy/CMakeLists.txt | 4 +++- test/test-platform/CMakeLists.txt | 18 ++++++++++-------- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/asio/stub/asio.hpp b/asio/stub/asio.hpp index b3145cf9e..84a0ea4ec 100644 --- a/asio/stub/asio.hpp +++ b/asio/stub/asio.hpp @@ -58,7 +58,13 @@ inline bool read(const dummy_base &, const dummy_base &, const dummy_base &) using buffer = dummy_base; struct io_service : dummy_base { - using dummy_base::dummy_base; + template + io_service(Args &&...) + { + throw std::runtime_error("Stub constructor called. Did you forget to set the " + "'TuningAllowed' attribute to 'false' in the Parameter " + "Framework's toplevel configuration file?"); + } void run(const dummy_base &) const {}; void stop() const {}; diff --git a/parameter/ParameterMgr.cpp b/parameter/ParameterMgr.cpp index 3b2d182d5..f45056325 100644 --- a/parameter/ParameterMgr.cpp +++ b/parameter/ParameterMgr.cpp @@ -2855,8 +2855,13 @@ bool CParameterMgr::handleRemoteProcessingInterface(string &strError) auto port = getConstFrameworkConfiguration()->getServerPort(); - // The ownership of remoteComandHandler is given to Bg remote processor server. - _pRemoteProcessorServer = new BackgroundRemoteProcessorServer(port, createCommandHandler()); + try { + // The ownership of remoteComandHandler is given to Bg remote processor server. + _pRemoteProcessorServer = new BackgroundRemoteProcessorServer(port, createCommandHandler()); + } catch (std::runtime_error &e) { + strError = string("ParameterMgr: Unable to create Remote Processor Server: ") + e.what(); + return false; + } if (_pRemoteProcessorServer == NULL) { strError = "ParameterMgr: Unable to create Remote Processor Server"; diff --git a/remote-process/CMakeLists.txt b/remote-process/CMakeLists.txt index 9c4906739..e27a101e8 100644 --- a/remote-process/CMakeLists.txt +++ b/remote-process/CMakeLists.txt @@ -26,12 +26,14 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_executable(remote-process main.cpp) +if(NETWORKING) + add_executable(remote-process main.cpp) -set(CMAKE_THREAD_PREFER_PTHREAD 1) -find_package(Threads REQUIRED) + set(CMAKE_THREAD_PREFER_PTHREAD 1) + find_package(Threads REQUIRED) -target_link_libraries(remote-process - PRIVATE remote-processor pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) + target_link_libraries(remote-process + PRIVATE remote-processor pfw_utility asio ${CMAKE_THREAD_LIBS_INIT}) -install(TARGETS remote-process RUNTIME DESTINATION bin) + install(TARGETS remote-process RUNTIME DESTINATION bin) +endif() diff --git a/test/functional-tests-legacy/CMakeLists.txt b/test/functional-tests-legacy/CMakeLists.txt index 9fe4c52c5..2eb172472 100644 --- a/test/functional-tests-legacy/CMakeLists.txt +++ b/test/functional-tests-legacy/CMakeLists.txt @@ -26,7 +26,9 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -if(BUILD_TESTING) +# This test suite relies on remote-process - which isn't available when +# networking is disabled +if(BUILD_TESTING AND NETWORKING) find_package(PythonInterp 2 REQUIRED) set(PFW_ROOT ${PROJECT_BINARY_DIR}/tmp/test-parameters) diff --git a/test/test-platform/CMakeLists.txt b/test/test-platform/CMakeLists.txt index d94d4edac..533de3c5a 100644 --- a/test/test-platform/CMakeLists.txt +++ b/test/test-platform/CMakeLists.txt @@ -26,13 +26,15 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -add_executable(test-platform - main.cpp - TestPlatform.cpp) +if(NETWORKING) + add_executable(test-platform + main.cpp + TestPlatform.cpp) -target_link_libraries(test-platform - PRIVATE parameter pfw_utility remote-processor) -# Workaround because asio is still leaking to test-platform -target_link_libraries(test-platform PRIVATE asio) + target_link_libraries(test-platform + PRIVATE parameter pfw_utility remote-processor) + # Workaround because asio is still leaking to test-platform + target_link_libraries(test-platform PRIVATE asio) -install(TARGETS test-platform RUNTIME DESTINATION bin) + install(TARGETS test-platform RUNTIME DESTINATION bin) +endif() From 397aa60375627e94e34d6790b027f09e6f8109b3 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Tue, 23 Feb 2016 14:11:20 +0100 Subject: [PATCH 6/7] README: update documentation wrt. build dependencies Explain how optional dependencies can be avoided. Signed-off-by: David Wagner --- README.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 618981c56..59ae1e69d 100644 --- a/README.md +++ b/README.md @@ -77,16 +77,22 @@ In order to compile you'll need, at the very least: - A C/C++ compiler supporting C++11; - libxml2 headers and libraries (Provided by the `libxml2-dev` on debian-based distributions); + +If you want to use the remote command interface (`NETWORKING=ON` by default), +you'll also need: + - Standalone ASIO (1.10.6 or later) (Provided by `libasio-dev` on debian-based distributions) ASIO is C++ header-only ASynchronous-IO library. -If you want to compile the *Python bindings*, you'll also need: +If you want to compile the *Python bindings* (`PYTHON_BINDINGS=ON` by default), +you'll also need: - SWIG 2.0 (A binding generator); - Python2.7 development environment (Provided by `python2.7-dev` on debian-based distributions) -If you want to *compile and run the tests*, you'll also need: +If you want to *compile and run the tests* (`BUILD_TESTING=ON` by default), +you'll also need: - Catch (Provided by `catch` on debian-based distributions). Catch is a single-header test framework - as such you may also download it directly @@ -94,8 +100,9 @@ single-header test framework - as such you may also download it directly - Python2.7 (Provided by `python2.7` on debian-based distribution - it is preinstalled on most distributions). -If you want to *build the code documentation*, you'll need `doxygen` and -`graphviz`. This doc is already available to you - see the wiki. +If you want to *build the code documentation* (`DOXYGEN=OFF` by default), you'll +need `doxygen` and `graphviz`. This doc is already available to you - see the +wiki. **To list all available configuration options, try** `cmake -L` (you may also filter-out lines starting with `CMAKE_`). From 7c0b65b2ef314368597edd446b72e00a66083731 Mon Sep 17 00:00:00 2001 From: David Wagner Date: Tue, 23 Feb 2016 14:20:59 +0100 Subject: [PATCH 7/7] CI: test builds without asio nor bindings Signed-off-by: David Wagner --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 5a7a5cc0b..db18b6f98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,6 @@ addons: - cmake-data - cmake - python3-dev - - libasio-dev - clang-format-3.8 install: @@ -80,6 +79,13 @@ script: cmake -DCMAKE_INSTALL_PREFIX=../install . && make && make install ) + # Keep this last + - ( mkdir build_less_features && cd build_less_features && + rm -rf $PREFIX/asio-1.10.6 && + cmake -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Debug + -DNETWORKING=OFF -DPYTHON_BINDINGS=OFF -DC_BINDINGS=OFF .. && + make -j && + CTEST_OUTPUT_ON_FAILURE=1 make test ) after_success: # Push coverage info on codecov.io.