From 31d0d2b2b86c09f10352f33d4e1d15cf4743ea98 Mon Sep 17 00:00:00 2001 From: Jan Christoph Uhde Date: Mon, 6 Mar 2017 13:50:54 +0100 Subject: [PATCH 01/10] move bootstrap.sh to scripts --- bootstrap.sh => scripts/bootstrap.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename bootstrap.sh => scripts/bootstrap.sh (100%) diff --git a/bootstrap.sh b/scripts/bootstrap.sh similarity index 100% rename from bootstrap.sh rename to scripts/bootstrap.sh From 2f2b4661bc71e0f3a6b96784b0404f1c3de639cf Mon Sep 17 00:00:00 2001 From: Jan Christoph Uhde Date: Mon, 6 Mar 2017 14:15:59 +0100 Subject: [PATCH 02/10] delete bootstrap script (moved to private repository) --- scripts/bootstrap.sh | 139 ------------------------------------------- 1 file changed, 139 deletions(-) delete mode 100755 scripts/bootstrap.sh diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh deleted file mode 100755 index 1466262cb2..0000000000 --- a/scripts/bootstrap.sh +++ /dev/null @@ -1,139 +0,0 @@ -#!/bin/bash - -# usage: -# ./boostrap.sh [--git] [--asan] [--clang] source_destination -# @author Jan Christoph Uhde - 2017 - -arg_git=false -arg_asan=false - -https_url="https://github.com/arangodb/arangodb.git" -git_url="git@github.com:arangodb/arangodb.git" - -build_type="RelWithDebInfo" -compiler=gcc - -args=() -for arg in "$@"; do - if [[ $arg == "--" ]]; then - break - fi - case $arg in - --git) - arg_git=true - ;; - --asan) - arg_asan=true - ;; - --clang) - compiler=clang - ;; - --gcc-arango) - compiler=gcc-arango - ;; - *) - args+=( "$arg" ) - ;; - esac -done - -configure_build(){ - local source_dir="$1" - - local asan="" - if $arg_asan; then - asan="-fsanitize=address -fsanitize=undefined -fno-sanitize=alignment -fno-sanitize=vptr" - fi - - case "$compiler" in - clang) - flags="$asan" - cxx="/usr/bin/clang++" - cc="/usr/bin/clang" - ;; - gcc-arango) - flags=" -lpthread $asan" - cxx="/opt/arangodb/bin/g++" - cc="/opt/arangodb/bin/gcc" - ;; - gcc) - flags=" -lpthread $asan" - cxx="/usr/bin/g++" - cc="/usr/bin/gcc" - ;; - esac - - cxx_flags="$flags -std=c++11" - CXX=$cxx \ - CC=$cc \ - CXXFLAGS="$cxx_flags" \ - CFLAGS="$flags" \ - cmake -DCMAKE_BUILD_TYPE=$build_type \ - -DUSE_MAINTAINER_MODE=On \ - -DUSE_BOOST_UNITTESTS=On \ - -DUSE_FAILURE_TESTS=On \ - -DUSE_ENTERPRISE=OFF \ - "$source_dir" - - if [[ $? -eq 0 ]]; then - echo "configuration successful (in $(pwd))" - make -j $(nproc) - else - echo "failed to configure (in $(pwd))" - fi -} - -bootstrap(){ - local branch="$2" - - local source_dir="$1" - local build_dir="${source_dir}-build" - mkdir -p "$build_dir" - - local url="$https_url" - if $git; then - url="$git_url" - fi - - #store path - current_dir="$(pwd)" - - if [[ -e $source_dir ]]; then - echo "A file/directory already exists in the chosen location!" - exit 1 - fi - - echo "cloning '$url' into '$source_dir'" - git clone "$url" "$source_dir" - - echo "changing into '$source_dir'" - cd $source_dir || { echo "can not change into $source_dir"; exit 1; } - - if [[ -n "$branch" ]]; then - echo "checking out '$branch'" - git checkout "$branch" || { echo "can not change into $source_dir"; exit 1; } - fi - - # TODO more error handling instead of: 'set -e' - set -e - echo "initialize submodules" - git submodule init - git submodule update --recursive - cd 3rdParty/V8/v8 - git submodule init - git submodule update --recursive - - echo "linking $current_dir/$build_dir to build" - ln -s "$current_dir/$build_dir" "$current_dir/$source_dir/build" - - cd "$current_dir/$build_dir" - set +e - - configure_build "$current_dir/$source_dir" - - # in a better language the build command should be here but by - # putting it at the end of configure_build unnecessary parsing is - # avoided. -} - -bootstrap "${args[@]}" From c6c9120e33c37f693f51f8a6cc2f84febdb2bd4a Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:20:45 +0100 Subject: [PATCH 03/10] another attempt to fix logger issues --- arangod/Indexes/Index.cpp | 1 + lib/Basics/AttributeNameParser.cpp | 60 ------------------------------ lib/Basics/AttributeNameParser.h | 32 ++++++++++++---- lib/Logger/LoggerStream.h | 8 +++- 4 files changed, 33 insertions(+), 68 deletions(-) diff --git a/arangod/Indexes/Index.cpp b/arangod/Indexes/Index.cpp index 487191245e..26ea5f740c 100644 --- a/arangod/Indexes/Index.cpp +++ b/arangod/Indexes/Index.cpp @@ -41,6 +41,7 @@ #include using namespace arangodb; +using namespace arangodb::basics; Index::Index( TRI_idx_iid_t iid, arangodb::LogicalCollection* collection, diff --git a/lib/Basics/AttributeNameParser.cpp b/lib/Basics/AttributeNameParser.cpp index 83229d3d7c..ce1e2d57be 100644 --- a/lib/Basics/AttributeNameParser.cpp +++ b/lib/Basics/AttributeNameParser.cpp @@ -205,63 +205,3 @@ bool arangodb::basics::TRI_AttributeNamesHaveExpansion( } return false; } - -//////////////////////////////////////////////////////////////////////////////// -/// @brief append the attribute name to an output stream -//////////////////////////////////////////////////////////////////////////////// - -std::ostream& operator<<(std::ostream& stream, - arangodb::basics::AttributeName const* name) { - stream << name->name; - if (name->shouldExpand) { - stream << "[*]"; - } - return stream; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief append the attribute name to an output stream -//////////////////////////////////////////////////////////////////////////////// - -std::ostream& operator<<(std::ostream& stream, - arangodb::basics::AttributeName const& name) { - stream << name.name; - if (name.shouldExpand) { - stream << "[*]"; - } - return stream; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief append the attribute names to an output stream -//////////////////////////////////////////////////////////////////////////////// - -std::ostream& operator<<( - std::ostream& stream, - std::vector const* attributes) { - size_t const n = attributes->size(); - for (size_t i = 0; i < n; ++i) { - if (i > 0) { - stream << "."; - } - stream << attributes[i]; - } - return stream; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief append the attribute names to an output stream -//////////////////////////////////////////////////////////////////////////////// - -std::ostream& operator<<( - std::ostream& stream, - std::vector const& attributes) { - size_t const n = attributes.size(); - for (size_t i = 0; i < n; ++i) { - if (i > 0) { - stream << "."; - } - stream << attributes[i]; - } - return stream; -} diff --git a/lib/Basics/AttributeNameParser.h b/lib/Basics/AttributeNameParser.h index 096ed80d99..fd5a0e737a 100644 --- a/lib/Basics/AttributeNameParser.h +++ b/lib/Basics/AttributeNameParser.h @@ -85,6 +85,18 @@ struct AttributeName { static bool namesMatch(std::vector const&, std::vector const&); + + friend std::ostream& operator<<(std::ostream& stream, arangodb::basics::AttributeName const* name) { + stream << name->name; + if (name->shouldExpand) { + stream << "[*]"; + } + return stream; + } + + friend std::ostream& operator<<(std::ostream& stream, arangodb::basics::AttributeName const& name) { + return operator<<(stream, &name); + } }; //////////////////////////////////////////////////////////////////////////////// @@ -126,14 +138,20 @@ void TRI_AttributeNamesJoinNested(std::vector const& input, //////////////////////////////////////////////////////////////////////////////// bool TRI_AttributeNamesHaveExpansion(std::vector const& input); -} + +static inline std::ostream& operator<<(std::ostream& stream, + std::vector const& attributes) { + size_t const n = attributes.size(); + for (size_t i = 0; i < n; ++i) { + if (i > 0) { + stream << "."; + } + stream << attributes[i]; + } + return stream; } -std::ostream& operator<<(std::ostream&, arangodb::basics::AttributeName const*); -std::ostream& operator<<(std::ostream&, arangodb::basics::AttributeName const&); -std::ostream& operator<<(std::ostream&, - std::vector const*); -std::ostream& operator<<(std::ostream&, - std::vector const&); +} +} #endif diff --git a/lib/Logger/LoggerStream.h b/lib/Logger/LoggerStream.h index b3d2876575..6f0cfa2172 100644 --- a/lib/Logger/LoggerStream.h +++ b/lib/Logger/LoggerStream.h @@ -78,7 +78,13 @@ class LoggerStream { template friend LoggerStream& operator<<(LoggerStream& out, T const& obj) { - out << obj; + out._out << obj; + return out; + } + + template + friend LoggerStream& operator<<(LoggerStream& out, T&& obj) { + out._out << obj; return out; } From 79f6a39c23ccaf6b08961d33294e689514412ea4 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:22:03 +0100 Subject: [PATCH 04/10] fix cppcheck errors --- arangod/Cache/Cache.cpp | 3 +-- arangod/Cache/Manager.cpp | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/arangod/Cache/Cache.cpp b/arangod/Cache/Cache.cpp index a9aa71b68b..a3ab5439c1 100644 --- a/arangod/Cache/Cache.cpp +++ b/arangod/Cache/Cache.cpp @@ -142,12 +142,11 @@ uint64_t Cache::usage() { } std::pair Cache::hitRates() { - double lifetimeRate = std::nan(""); double windowedRate = std::nan(""); uint64_t currentMisses = _findMisses.load(); uint64_t currentHits = _findHits.load(); - lifetimeRate = 100 * (static_cast(currentHits) / + double lifetimeRate = 100 * (static_cast(currentHits) / static_cast(currentHits + currentMisses)); if (_enableWindowedStats && _findStats.get() != nullptr) { diff --git a/arangod/Cache/Manager.cpp b/arangod/Cache/Manager.cpp index 274b255c43..b986c364e2 100644 --- a/arangod/Cache/Manager.cpp +++ b/arangod/Cache/Manager.cpp @@ -197,12 +197,10 @@ uint64_t Manager::globalAllocation() { } std::pair Manager::globalHitRates() { - double lifetimeRate = std::nan(""); double windowedRate = std::nan(""); - uint64_t currentMisses = _findMisses.load(); uint64_t currentHits = _findHits.load(); - lifetimeRate = 100 * (static_cast(currentHits) / + double lifetimeRate = 100 * (static_cast(currentHits) / static_cast(currentHits + currentMisses)); if (_enableWindowedStats && _findStats.get() != nullptr) { From c7acebe3c05bc13d75d987b324ea8d2dc7a3302d Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:30:42 +0100 Subject: [PATCH 05/10] Revert "another attempt to fix logger issues" This reverts commit c6c9120e33c37f693f51f8a6cc2f84febdb2bd4a. --- arangod/Indexes/Index.cpp | 1 - lib/Basics/AttributeNameParser.cpp | 60 ++++++++++++++++++++++++++++++ lib/Basics/AttributeNameParser.h | 32 ++++------------ lib/Logger/LoggerStream.h | 8 +--- 4 files changed, 68 insertions(+), 33 deletions(-) diff --git a/arangod/Indexes/Index.cpp b/arangod/Indexes/Index.cpp index 26ea5f740c..487191245e 100644 --- a/arangod/Indexes/Index.cpp +++ b/arangod/Indexes/Index.cpp @@ -41,7 +41,6 @@ #include using namespace arangodb; -using namespace arangodb::basics; Index::Index( TRI_idx_iid_t iid, arangodb::LogicalCollection* collection, diff --git a/lib/Basics/AttributeNameParser.cpp b/lib/Basics/AttributeNameParser.cpp index ce1e2d57be..83229d3d7c 100644 --- a/lib/Basics/AttributeNameParser.cpp +++ b/lib/Basics/AttributeNameParser.cpp @@ -205,3 +205,63 @@ bool arangodb::basics::TRI_AttributeNamesHaveExpansion( } return false; } + +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the attribute name to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<<(std::ostream& stream, + arangodb::basics::AttributeName const* name) { + stream << name->name; + if (name->shouldExpand) { + stream << "[*]"; + } + return stream; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the attribute name to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<<(std::ostream& stream, + arangodb::basics::AttributeName const& name) { + stream << name.name; + if (name.shouldExpand) { + stream << "[*]"; + } + return stream; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the attribute names to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<<( + std::ostream& stream, + std::vector const* attributes) { + size_t const n = attributes->size(); + for (size_t i = 0; i < n; ++i) { + if (i > 0) { + stream << "."; + } + stream << attributes[i]; + } + return stream; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief append the attribute names to an output stream +//////////////////////////////////////////////////////////////////////////////// + +std::ostream& operator<<( + std::ostream& stream, + std::vector const& attributes) { + size_t const n = attributes.size(); + for (size_t i = 0; i < n; ++i) { + if (i > 0) { + stream << "."; + } + stream << attributes[i]; + } + return stream; +} diff --git a/lib/Basics/AttributeNameParser.h b/lib/Basics/AttributeNameParser.h index fd5a0e737a..096ed80d99 100644 --- a/lib/Basics/AttributeNameParser.h +++ b/lib/Basics/AttributeNameParser.h @@ -85,18 +85,6 @@ struct AttributeName { static bool namesMatch(std::vector const&, std::vector const&); - - friend std::ostream& operator<<(std::ostream& stream, arangodb::basics::AttributeName const* name) { - stream << name->name; - if (name->shouldExpand) { - stream << "[*]"; - } - return stream; - } - - friend std::ostream& operator<<(std::ostream& stream, arangodb::basics::AttributeName const& name) { - return operator<<(stream, &name); - } }; //////////////////////////////////////////////////////////////////////////////// @@ -138,20 +126,14 @@ void TRI_AttributeNamesJoinNested(std::vector const& input, //////////////////////////////////////////////////////////////////////////////// bool TRI_AttributeNamesHaveExpansion(std::vector const& input); - -static inline std::ostream& operator<<(std::ostream& stream, - std::vector const& attributes) { - size_t const n = attributes.size(); - for (size_t i = 0; i < n; ++i) { - if (i > 0) { - stream << "."; - } - stream << attributes[i]; - } - return stream; +} } -} -} +std::ostream& operator<<(std::ostream&, arangodb::basics::AttributeName const*); +std::ostream& operator<<(std::ostream&, arangodb::basics::AttributeName const&); +std::ostream& operator<<(std::ostream&, + std::vector const*); +std::ostream& operator<<(std::ostream&, + std::vector const&); #endif diff --git a/lib/Logger/LoggerStream.h b/lib/Logger/LoggerStream.h index 6f0cfa2172..b3d2876575 100644 --- a/lib/Logger/LoggerStream.h +++ b/lib/Logger/LoggerStream.h @@ -78,13 +78,7 @@ class LoggerStream { template friend LoggerStream& operator<<(LoggerStream& out, T const& obj) { - out._out << obj; - return out; - } - - template - friend LoggerStream& operator<<(LoggerStream& out, T&& obj) { - out._out << obj; + out << obj; return out; } From d8dcba7d487b0aed0c4b45a5dbce75255ddf9fd8 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:30:47 +0100 Subject: [PATCH 06/10] Revert "fix compile errors in new clangs" This reverts commit 43a32b04c456ce6d769f80a48b3ec9388cb34e4c. --- lib/Logger/LoggerStream.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Logger/LoggerStream.h b/lib/Logger/LoggerStream.h index b3d2876575..2c263ef405 100644 --- a/lib/Logger/LoggerStream.h +++ b/lib/Logger/LoggerStream.h @@ -77,11 +77,11 @@ class LoggerStream { } template - friend LoggerStream& operator<<(LoggerStream& out, T const& obj) { - out << obj; - return out; + LoggerStream& operator<<(T const& obj) { + _out << obj; + return *this; } - + template LoggerStream& operator<<(std::pair const& obj) { _out << '(' << obj.first << ", " << obj.second << ')'; From ca89a25ad8a6c7a7f56fa366e20a5913d1bec327 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:31:13 +0100 Subject: [PATCH 07/10] try to use g++5.4 on travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8bbc535083..f71979105b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,8 +24,8 @@ addons: - ubuntu-toolchain-r-test - george-edison55-precise-backports packages: - - g++-4.9 - - gcc-4.9 + - g++-5.4 + - gcc-5.4 - binutils-gold - gdb - cmake-data From bbda879dee0f5750a8344c7ae08e3dc00a37e024 Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:43:31 +0100 Subject: [PATCH 08/10] use g++-5 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f71979105b..7da124c4fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,8 +24,8 @@ addons: - ubuntu-toolchain-r-test - george-edison55-precise-backports packages: - - g++-5.4 - - gcc-5.4 + - g++-5 + - gcc-5 - binutils-gold - gdb - cmake-data From bbda3fa9f5ca253353ca9d7a755bd8e0326d85ad Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:44:56 +0100 Subject: [PATCH 09/10] simplified some ostream kirmes --- lib/Basics/AttributeNameParser.cpp | 30 ------------------------------ lib/Basics/AttributeNameParser.h | 3 --- lib/Basics/debugging.h | 12 +++++++++++- lib/Logger/LoggerStream.h | 6 ------ 4 files changed, 11 insertions(+), 40 deletions(-) diff --git a/lib/Basics/AttributeNameParser.cpp b/lib/Basics/AttributeNameParser.cpp index 83229d3d7c..ff03fa651f 100644 --- a/lib/Basics/AttributeNameParser.cpp +++ b/lib/Basics/AttributeNameParser.cpp @@ -210,19 +210,6 @@ bool arangodb::basics::TRI_AttributeNamesHaveExpansion( /// @brief append the attribute name to an output stream //////////////////////////////////////////////////////////////////////////////// -std::ostream& operator<<(std::ostream& stream, - arangodb::basics::AttributeName const* name) { - stream << name->name; - if (name->shouldExpand) { - stream << "[*]"; - } - return stream; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief append the attribute name to an output stream -//////////////////////////////////////////////////////////////////////////////// - std::ostream& operator<<(std::ostream& stream, arangodb::basics::AttributeName const& name) { stream << name.name; @@ -236,23 +223,6 @@ std::ostream& operator<<(std::ostream& stream, /// @brief append the attribute names to an output stream //////////////////////////////////////////////////////////////////////////////// -std::ostream& operator<<( - std::ostream& stream, - std::vector const* attributes) { - size_t const n = attributes->size(); - for (size_t i = 0; i < n; ++i) { - if (i > 0) { - stream << "."; - } - stream << attributes[i]; - } - return stream; -} - -//////////////////////////////////////////////////////////////////////////////// -/// @brief append the attribute names to an output stream -//////////////////////////////////////////////////////////////////////////////// - std::ostream& operator<<( std::ostream& stream, std::vector const& attributes) { diff --git a/lib/Basics/AttributeNameParser.h b/lib/Basics/AttributeNameParser.h index 096ed80d99..e66622bde8 100644 --- a/lib/Basics/AttributeNameParser.h +++ b/lib/Basics/AttributeNameParser.h @@ -129,10 +129,7 @@ bool TRI_AttributeNamesHaveExpansion(std::vector const& input); } } -std::ostream& operator<<(std::ostream&, arangodb::basics::AttributeName const*); std::ostream& operator<<(std::ostream&, arangodb::basics::AttributeName const&); -std::ostream& operator<<(std::ostream&, - std::vector const*); std::ostream& operator<<(std::ostream&, std::vector const&); diff --git a/lib/Basics/debugging.h b/lib/Basics/debugging.h index f3d45c7110..399d40e1cd 100644 --- a/lib/Basics/debugging.h +++ b/lib/Basics/debugging.h @@ -114,6 +114,16 @@ void TRI_ShutdownDebugging(); void TRI_FlushDebugging(); void TRI_FlushDebugging(char const* file, int line, char const* message); +//////////////////////////////////////////////////////////////////////////////// +/// @brief dump pair contents to an ostream +//////////////////////////////////////////////////////////////////////////////// + +template +std::ostream& operator<<(std::ostream& stream, std::pair const& obj) { + stream << '(' << obj.first << ", " << obj.second << ')'; + return stream; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief dump vector contents to an ostream //////////////////////////////////////////////////////////////////////////////// @@ -209,7 +219,7 @@ std::ostream& operator<<(std::ostream& stream, } //////////////////////////////////////////////////////////////////////////////// -/// @brief dump unordered_map contents to an ostream +/// @brief dump map contents to an ostream //////////////////////////////////////////////////////////////////////////////// template diff --git a/lib/Logger/LoggerStream.h b/lib/Logger/LoggerStream.h index 2c263ef405..4b8176d833 100644 --- a/lib/Logger/LoggerStream.h +++ b/lib/Logger/LoggerStream.h @@ -82,12 +82,6 @@ class LoggerStream { return *this; } - template - LoggerStream& operator<<(std::pair const& obj) { - _out << '(' << obj.first << ", " << obj.second << ')'; - return *this; - } - private: std::stringstream _out; size_t _topicId; From f23b66194c16371d452f687092d8a023c931a2ed Mon Sep 17 00:00:00 2001 From: jsteemann Date: Mon, 6 Mar 2017 14:49:32 +0100 Subject: [PATCH 10/10] next g++-5 build attempt for travis --- Installation/travisCI/before_script.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Installation/travisCI/before_script.sh b/Installation/travisCI/before_script.sh index ec418e7f1f..8feb4cd4cd 100755 --- a/Installation/travisCI/before_script.sh +++ b/Installation/travisCI/before_script.sh @@ -7,10 +7,10 @@ mkdir -p $HOME/bin/gold chmod a+x $HOME/bin/gold/ld # prepare CCACHE -(echo '#!/bin/bash'; echo 'ccache /usr/bin/gcc-4.9 "$@"') > $HOME/bin/gcc +(echo '#!/bin/bash'; echo 'ccache /usr/bin/gcc-5 "$@"') > $HOME/bin/gcc chmod a+x $HOME/bin/gcc -(echo '#!/bin/bash'; echo 'ccache /usr/bin/g++-4.9 "$@"') > $HOME/bin/g++ +(echo '#!/bin/bash'; echo 'ccache /usr/bin/g++-5 "$@"') > $HOME/bin/g++ chmod a+x $HOME/bin/g++ # prepare files for unit test