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.
This commit is contained in:
Tom Ritchford
2014-05-28 14:38:28 -04:00
committed by Vinnie Falco
parent 27e8d44a56
commit 69fccdf5c6
6 changed files with 63 additions and 169 deletions

View File

@@ -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})

View File

@@ -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;

View File

@@ -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.
//

View File

@@ -44,7 +44,6 @@
//------------------------------------------------------------------------------
#include "containers/RangeSet.cpp"
#include "system/CheckLibraryVersions.cpp"
#include "log/Log.cpp"
#include "log/LogFile.cpp"

View File

@@ -20,132 +20,50 @@
#include <sstream>
#include <vector>
#include "../../beast/beast/unit_test/suite.h"
#include "../../beast/modules/beast_core/diagnostic/SemanticVersion.h"
#include <boost/version.hpp>
#include <openssl/opensslv.h>
#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

View File

@@ -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 <string>
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