From 69fccdf5c633cf217caeb45e0a8398485d38e194 Mon Sep 17 00:00:00 2001 From: Tom Ritchford Date: Wed, 28 May 2014 14:38:28 -0400 Subject: [PATCH] Improve checking of library versions. * Correctly handle openSSL version checking on Ubuntu, Debian, OS/X. * Also check versions of openSSL, Boost, GCC and MSVC at C++ compile time. * Get rid of over-engineered runtime CheckLibraryVersions. --- SConstruct | 38 ++++- src/ripple_app/main/Main.cpp | 3 - src/ripple_app/ripple_app.unity.cpp | 18 --- src/ripple_basics/ripple_basics.unity.cpp | 1 - .../system/CheckLibraryVersions.cpp | 134 ++++-------------- .../system/CheckLibraryVersions.h | 38 ----- 6 files changed, 63 insertions(+), 169 deletions(-) delete mode 100644 src/ripple_basics/system/CheckLibraryVersions.h diff --git a/SConstruct b/SConstruct index dc7bbe2c4..5dae17718 100644 --- a/SConstruct +++ b/SConstruct @@ -46,16 +46,48 @@ TODO import collections import os +import platform import subprocess import sys import textwrap +import time import SCons.Action sys.path.append(os.path.join('src', 'beast', 'site_scons')) import Beast -#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------ + +def get_platform(): + plat = platform.system().upper() + if plat == 'LINUX': + plat = platform.linux_distribution()[0].upper() + return plat + +def parse_time(t): + return time.strptime(t, '%a %b %d %H:%M:%S %Z %Y') + +CHECK_PLATFORMS = 'DARWIN', 'DEBIAN', 'UBUNTU' +CHECK_COMMAND = 'openssl version -a' +CHECK_LINE = 'built on: ' +BUILD_TIME = 'Mon Apr 7 20:33:19 UTC 2014' +OPENSSL_ERROR = ( + 'Your openSSL was built on %s but we need a version on or after %s.') + +def check_openssl(platform): + if platform in CHECK_PLATFORMS: + for line in subprocess.check_output(CHECK_COMMAND.split()).splitlines(): + if line.startswith(CHECK_LINE): + line = line[len(CHECK_LINE):] + if parse_time(line) < parse_time(BUILD_TIME): + raise Exception(OPENSSL_ERROR % (line, BUILD_TIME)) + else: + break + else: + raise Exception("Didn't find any '%s' line in '$ %s'" % + (CHECK_LINE, CHECK_COMMAND)) + def import_environ(env): '''Imports environment settings into the construction environment''' @@ -187,6 +219,10 @@ def config_base(env): CXXCOMSTR='Compiling ' + Beast.blue('$SOURCES'), LINKCOMSTR='Linking ' + Beast.blue('$TARGET'), ) + platform = get_platform() + check_openssl(platform) + + env.Append(CPPDEFINES={'RIPPLE_' + platform: 1}) #git = Beast.Git(env) # TODO(TOM) if False: #git.exists: env.Append(CPPDEFINES={'GIT_COMMIT_ID' : '"%s"' % git.commit_id}) diff --git a/src/ripple_app/main/Main.cpp b/src/ripple_app/main/Main.cpp index cff234a1c..213562414 100644 --- a/src/ripple_app/main/Main.cpp +++ b/src/ripple_app/main/Main.cpp @@ -19,7 +19,6 @@ #include "../../beast/beast/unit_test.h" #include "../../beast/beast/streams/debug_ostream.h" -#include "../../ripple_basics/system/CheckLibraryVersions.h" namespace po = boost::program_options; @@ -165,8 +164,6 @@ runUnitTests (std::string pattern, std::string format) int run (int argc, char** argv) { // Make sure that we have the right OpenSSL and Boost libraries. - version::checkLibraryVersions(); - FatalErrorReporter reporter; using namespace std; diff --git a/src/ripple_app/ripple_app.unity.cpp b/src/ripple_app/ripple_app.unity.cpp index 556153888..fc03556c6 100644 --- a/src/ripple_app/ripple_app.unity.cpp +++ b/src/ripple_app/ripple_app.unity.cpp @@ -88,7 +88,6 @@ #include "node/SqliteFactory.cpp" #include "main/Application.cpp" - #include "main/Main.cpp" //------------------------------------------------------------------------------ @@ -109,23 +108,6 @@ struct ProtobufLibrary // int main (int argc, char** argv) { -#if defined(__GNUC__) && !defined(__clang__) - auto constexpr gccver = (__GNUC__ * 100 * 100) + - (__GNUC_MINOR__ * 100) + - __GNUC_PATCHLEVEL__; - - static_assert (gccver >= 40801, - "GCC version 4.8.1 or later is required to compile rippled."); -#endif - -#ifdef _MSC_VER - static_assert (_MSC_VER >= 1800, - "Visual Studio 2013 or later is required to compile rippled."); -#endif - - static_assert (BOOST_VERSION >= 105500, - "Boost version 1.55 or later is required to compile rippled"); - // // These debug heap calls do nothing in release or non Visual Studio builds. // diff --git a/src/ripple_basics/ripple_basics.unity.cpp b/src/ripple_basics/ripple_basics.unity.cpp index 660cf58e2..0711a8945 100644 --- a/src/ripple_basics/ripple_basics.unity.cpp +++ b/src/ripple_basics/ripple_basics.unity.cpp @@ -44,7 +44,6 @@ //------------------------------------------------------------------------------ #include "containers/RangeSet.cpp" -#include "system/CheckLibraryVersions.cpp" #include "log/Log.cpp" #include "log/LogFile.cpp" diff --git a/src/ripple_basics/system/CheckLibraryVersions.cpp b/src/ripple_basics/system/CheckLibraryVersions.cpp index 13814e032..79295765e 100644 --- a/src/ripple_basics/system/CheckLibraryVersions.cpp +++ b/src/ripple_basics/system/CheckLibraryVersions.cpp @@ -20,132 +20,50 @@ #include #include -#include "../../beast/beast/unit_test/suite.h" -#include "../../beast/modules/beast_core/diagnostic/SemanticVersion.h" #include #include -#include "CheckLibraryVersions.h" - namespace ripple { namespace version { -/** Both Boost and OpenSSL have integral version numbers. */ -typedef unsigned long long VersionNumber; +static const int BOOST_MINIMAL = 105500; +static_assert (BOOST_VERSION >= BOOST_MINIMAL, + "Boost version 1.55.0 or later is required to compile rippled."); -/** Minimal required boost version. */ -static const char boostMinimal[] = "1.55.0"; +#if defined(RIPPLE_UBUNTU) || defined(RIPPLE_DEBIAN) -/** Minimal required OpenSSL version. */ -static const char openSSLMinimal[] = "1.0.1-g"; +static const int OPENSSL_MINIMAL = 0x1000106fL; +static_assert (OPENSSL_VERSION_NUMBER >= OPENSSL_MINIMAL, + "openSSL version 1.0.1-f or later is required to compile rippled"); -std::string boostVersion(VersionNumber boostVersion = BOOST_VERSION) -{ - std::stringstream ss; - ss << (boostVersion / 100000) << "." - << (boostVersion / 100 % 1000) << "." - << (boostVersion % 100); - return ss.str(); -} +#else -std::string openSSLVersion(VersionNumber openSSLVersion = OPENSSL_VERSION_NUMBER) -{ - std::stringstream ss; - ss << (openSSLVersion / 0x10000000L) << "." - << (openSSLVersion / 0x100000 % 0x100) << "." - << (openSSLVersion / 0x1000 % 0x100); - auto patchNo = openSSLVersion % 0x10; - if (patchNo) - ss << '-' << char('a' + patchNo - 1); - return ss.str(); -} +static const int OPENSSL_MINIMAL = 0x10001070L; +static_assert (OPENSSL_VERSION_NUMBER >= OPENSSL_MINIMAL, + "openSSL version 1.0.1-g or later is required to compile rippled"); -void checkVersion(std::string name, std::string required, std::string actual) -{ - beast::SemanticVersion r, a; - if (!r.parse(required)) { - throw std::runtime_error("Didn't understand required version of " + - name + ": " + required); - } - if (!a.parse(actual)) { - throw std::runtime_error("Didn't understand actual version of " + - name + ": " + required); - } +#endif - if (a < r) { - throw std::runtime_error("Your " + name + " library is out of date.\n" + - "Your version: " + actual + "\n" + - "Required version: " + "\n"); - } -} +#if defined(__GNUC__) && !defined(__clang__) -void checkBoost(std::string version = boostVersion()) -{ - checkVersion("Boost", boostMinimal, version); -} +static const int GCC_MINIMAL = 40801; +auto constexpr GCC_VERSION_NUMBER = + (__GNUC__ * 100 * 100) + + (__GNUC_MINOR__ * 100) + + __GNUC_PATCHLEVEL__; -void checkOpenSSL(std::string version = openSSLVersion()) -{ - checkVersion("OpenSSL", openSSLMinimal, version); -} +static_assert (GCC_VERSION_NUMBER >= 40801, + "GCC version 4.8.1 or later is required to compile rippled."); -void checkLibraryVersions() -{ - checkBoost(); - checkOpenSSL(); -} +#endif -struct CheckLibraryVersions_test : beast::unit_test::suite -{ - void print_message() - { - log << "ssl minimal: " << openSSLMinimal << "\n" - << "ssl actual: " << openSSLVersion() << "\n" - << "boost minimal: " << boostMinimal << "\n" - << "boost actual: " << boostVersion() << "\n" - << std::flush; - } +#ifdef _MSC_VER - void test_bad_ssl() - { - std::string error; - try { - checkOpenSSL(openSSLVersion(0x0090819fL)); - } catch (std::runtime_error& e) { - error = e.what(); - } - auto expectedError = "Your OpenSSL library is out of date.\n" - "Your version: 0.9.8-o\n" - "Required version: "; - unexpected(error.find(expectedError) != 0, error); - } +static const int MSVC_MINIMAL = 1800; +static_assert (_MSC_VER >= 1800, + "Visual Studio 2013 or later is required to compile rippled."); - void test_bad_boost() - { - std::string error; - try { - checkBoost(boostVersion(105400)); - } catch (std::runtime_error& e) { - error = e.what(); - } - auto expectedError = "Your Boost library is out of date.\n" - "Your version: 1.54.0\n" - "Required version: "; - unexpected(error.find(expectedError) != 0, error); - } - - - void run() - { - print_message(); - checkLibraryVersions(); - - test_bad_ssl(); - test_bad_boost(); - } -}; - -BEAST_DEFINE_TESTSUITE(CheckLibraryVersions, ripple_basics, ripple); +#endif } // namespace version } // namespace ripple diff --git a/src/ripple_basics/system/CheckLibraryVersions.h b/src/ripple_basics/system/CheckLibraryVersions.h deleted file mode 100644 index 5bb150dde..000000000 --- a/src/ripple_basics/system/CheckLibraryVersions.h +++ /dev/null @@ -1,38 +0,0 @@ -//------------------------------------------------------------------------------ -/* - This file is part of rippled: https://github.com/ripple/rippled - Copyright (c) 2012, 2013 Ripple Labs Inc. - - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -//============================================================================== - -#ifndef RIPPLE_CHECKLIBRARYVERSIONS_H_INCLUDED -#define RIPPLE_CHECKLIBRARYVERSIONS_H_INCLUDED - -#include - -namespace ripple { -namespace version { - -/** Check all library versions against Ripple's version requirements. - - Throws std::runtime_error if one or more libraries are out-of-date and do - not meet the version requirements. - */ -void checkLibraryVersions(); - -} // namespace version -} // namespace ripple - -#endif