Automate process of using gcc5:

* SConstruct will set ABI based on ubuntu flavor
* Script to bring in packages for various ubuntu flavors
* Script to bring in packages for various fedora 22
* Remove unneeded environment variable from travis
* Script to build boost with correct API flags
* `--static` flag to control static linking
This commit is contained in:
seelabs
2015-10-20 19:44:33 -04:00
committed by Nik Bougalis
parent b6cb981a8b
commit ded2a5c076
7 changed files with 228 additions and 38 deletions

View File

@@ -10,7 +10,6 @@ env:
# to boost's .tar.gz.
- BOOST_ROOT=$HOME/boost_1_59_0
- BOOST_URL='http://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz?r=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fboost%2Ffiles%2Fboost%2F1.59.0%2Fboost_1_59_0.tar.gz%2Fdownload&ts=1441761349&use_mirror=skylineservers'
- RIPPLED_OLD_GCC_ABI=1
packages: &gcc5_pkgs

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
#
# This scripts installs the dependencies needed by rippled. It should be run
# with sudo.
#
if [ ! -f /etc/fedora-release ]; then
echo "This script is meant to be run on fedora"
exit 1
fi
fedora_release=$(grep -o '[0-9]*' /etc/fedora-release)
if (( $(bc <<< "${fedora_release} < 22") )); then
echo "This script is meant to run on fedora 22 or greater"
exit 1
fi
yum -y update
yum -y group install "Development Tools"
yum -y install gcc-c++ scons openssl-devel openssl-static protobuf-devel protobuf-static boost-devel boost-static libstdc++-static

39
Builds/Ubuntu/install_boost.sh Executable file
View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
#
# This script builds boost with the correct ABI flags for ubuntu
#
version=59
patch=0
if hash lsb_release 2>/dev/null; then
if [ $(lsb_release -si) == "Ubuntu" ]; then
ubuntu_release=$(lsb_release -sr)
fi
fi
if [ -z "${ubuntu_release}" ]; then
echo "System not supported"
exit 1
fi
extra_defines=""
if (( $(bc <<< "${ubuntu_release} < 15.1") )); then
extra_defines="define=_GLIBCXX_USE_CXX11_ABI=0"
fi
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # pysical cores
printf "\nBuild command will be: ./b2 -j${num_procs} ${extra_defines}\n\n"
boost_dir="boost_1_${version}_${patch}"
boost_tag="boost-1.${version}.${patch}"
git clone -b "${boost_tag}" --recursive https://github.com/boostorg/boost.git "${boost_dir}"
cd ${boost_dir}
git checkout --force ${boost_tag}
git submodule foreach git checkout --force ${boost_tag}
./bootstrap.sh
./b2 headers
./b2 -j${num_procs} ${extra_defines}
echo "Build command was: ./b2 -j${num_procs} ${extra_defines}"
echo "Don't forget to set BOOST_ROOT!"

View File

@@ -0,0 +1,55 @@
#!/usr/bin/env bash
#
# This scripts installs the dependencies needed by rippled. It should be run
# with sudo. For ubuntu < 15.10, it installs gcc 5 as the default compiler. gcc
# 5 is ABI incompatable with gcc 4. If needed, the following will switch back to
# gcc-4: `sudo update-alternatives --config gcc` and choosing the gcc-4
# option.
#
if hash lsb_release 2>/dev/null; then
if [ $(lsb_release -si) == "Ubuntu" ]; then
ubuntu_release=$(lsb_release -sr)
fi
fi
if [ -z "${ubuntu_release}" ]; then
echo "System not supported"
exit 1
fi
if [ ${ubuntu_release} == "12.04" ]; then
apt-get install python-software-properties
add-apt-repository ppa:afrank/boost
add-apt-repository ppa:ubuntu-toolchain-r/test
apt-get update
apt-get -y upgrade
apt-get -y install curl git scons ctags pkg-config protobuf-compiler libprotobuf-dev libssl-dev python-software-properties boost1.57-all-dev nodejs g++-5 g++-4.9
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 99 --slave /usr/bin/g++ g++ /usr/bin/g++-5
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 99 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9
exit 0
fi
if [ ${ubuntu_release} == "14.04" ] || [ ${ubuntu_release} == "15.04" ]; then
apt-get install python-software-properties
echo "deb [arch=amd64] http://mirrors.ripple.com/ubuntu/ trusty stable contrib" | sudo tee /etc/apt/sources.list.d/ripple.list
wget -O- -q http://mirrors.ripple.com/mirrors.ripple.com.gpg.key | sudo apt-key add -
add-apt-repository ppa:ubuntu-toolchain-r/test
apt-get update
apt-get -y upgrade
apt-get -y install curl git scons ctags pkg-config protobuf-compiler libprotobuf-dev libssl-dev python-software-properties boost-all-dev nodejs g++-5 g++-4.9
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 99 --slave /usr/bin/g++ g++ /usr/bin/g++-5
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 99 --slave /usr/bin/g++ g++ /usr/bin/g++-4.9
exit 0
fi
if [ ${ubuntu_release} == "15.10" ]; then
apt-get update
apt-get -y upgrade
apt-get -y install python-software-properties curl git scons ctags pkg-config protobuf-compiler libprotobuf-dev libssl-dev python-software-properties libboost-all-dev nodejs
exit 0
fi
echo "System not supported"
exit 1

View File

@@ -71,16 +71,15 @@ The following extra options may be used:
(see: https://martine.github.io/ninja/). Only gcc and clang targets
are supported.
GCC 5 support: There is transitional support for user-installed gcc 5. Setting
the environment variable: `RIPPLED_OLD_GCC_ABI` to one enables the transitional
support. Due to an ABI change between gcc 4 and gcc 5, it is assumed all
libraries are built with the old, gcc 4 ABI. Since no linux distro has upgraded
to gcc 5, this allows us to use the package manager to install rippled
dependencies and to easily switch between gcc 4 and gcc 5. It also means if the
user builds C++ dependencies themselves - such as boost - they must either be
built with gcc 4 or with the preprocessor flag `_GLIBCXX_USE_CXX11_ABI` set to
zero. When linux distros upgrade to gcc 5, the transitional support will be
removed.
--static On linux, link protobuf, openssl, libc++, and boost statically
GCC 5: If the gcc toolchain is used, gcc version 5 or better is required. On
linux distros that ship with gcc 4 (ubuntu < 15.10), rippled will force gcc
to use gcc4's ABI (there was an ABI change between versions). This allows us
to use the package manager to install rippled dependencies. It also means if
the user builds C++ dependencies themselves - such as boost - they must
either be built with gcc 4 or with the preprocessor flag
`_GLIBCXX_USE_CXX11_ABI` set to zero.
'''
#
@@ -115,6 +114,9 @@ import scons_to_ninja
AddOption('--ninja', dest='ninja', action='store_true',
help='generate ninja build file build.ninja')
AddOption('--static', dest='static', action='store_true',
help='On linux, link protobuf, openssl, libc++, and boost statically')
def parse_time(t):
l = len(t.split())
if l==5:
@@ -126,6 +128,17 @@ def parse_time(t):
UNITY_BUILD_DIRECTORY = 'src/ripple/unity/'
def memoize(function):
memo = {}
def wrapper(*args):
if args in memo:
return memo[args]
else:
rv = function(*args)
memo[args] = rv
return rv
return wrapper
def check_openssl():
if Beast.system.platform not in ['Debian', 'Ubuntu']:
return
@@ -277,6 +290,35 @@ def print_coms(target, source, env):
def is_debug_variant(variant):
return variant in ('debug', 'coverage')
@memoize
def is_ubuntu():
try:
return "Ubuntu" == subprocess.check_output(['lsb_release', '-si'],
stderr=subprocess.STDOUT).strip()
except:
return False
@memoize
def use_gcc4_abi(gcc_cmd):
if os.getenv('RIPPLED_OLD_GCC_ABI'):
return True
gcc_ver = ''
ubuntu_ver = None
try:
gcc_ver = subprocess.check_output([gcc_cmd, '-dumpversion'],
stderr=subprocess.STDOUT).strip()
if is_ubuntu():
ubuntu_ver = float(
subprocess.check_output(['lsb_release', '-sr'],
stderr=subprocess.STDOUT).strip())
except:
print("Unable to determine gcc version. Assuming native ABI.")
return False
if ubuntu_ver and ubuntu_ver < 15.1 and gcc_ver.startswith('5'):
return True
return False
#-------------------------------------------------------------------------------
# Set construction variables for the base environment
@@ -351,6 +393,31 @@ def add_static_libs(env, libs):
c += ' -l' + f
env['STATICLIBS'] = c
def get_libs(lib, static):
'''Returns a tuple of lists. The first element is the static libs,
the second element is the dynamic libs
'''
always_dynamic = ['dl', 'pthread', 'z', # for ubuntu
'gssapi_krb5', 'krb5', 'com_err', 'k5crypto', # for fedora
]
try:
cmd = ['pkg-config', '--static', '--libs', lib]
libs = subprocess.check_output(cmd,
stderr=subprocess.STDOUT).strip()
all_libs = [l[2:] for l in libs.split() if l.startswith('-l')]
if not static:
return ([], all_libs)
static_libs = []
dynamic_libs = []
for l in all_libs:
if l in always_dynamic:
dynamic_libs.append(l)
else:
static_libs.append(l)
return (static_libs, dynamic_libs)
except:
raise Exception('pkg-config failed for ' + lib)
# Set toolchain and variant specific construction variables
def config_env(toolchain, variant, env):
if is_debug_variant(variant):
@@ -367,13 +434,19 @@ def config_env(toolchain, variant, env):
env['BOOST_ROOT'],
])
if should_link_static() and not Beast.system.linux:
raise Exception("Static linking is only implemented for linux.")
if toolchain in Split('clang gcc'):
if Beast.system.linux:
add_static_libs(env, ['protobuf', 'ssl', 'crypto'])
env.Append(LIBS=['dl', 'pthread', 'z'])
env.Append(LINKFLAGS=['-pthread'])
# env.ParseConfig('pkg-config --static --cflags --libs openssl')
# env.ParseConfig('pkg-config --static --cflags --libs protobuf')
link_static = should_link_static()
for l in ['openssl', 'protobuf']:
static, dynamic = get_libs(l, link_static)
if static:
add_static_libs(env, static)
if dynamic:
env.Append(LIBS=dynamic)
env.ParseConfig('pkg-config --static --cflags ' + l)
env.Prepend(CFLAGS=['-Wall'])
env.Prepend(CXXFLAGS=['-Wall'])
@@ -425,23 +498,15 @@ def config_env(toolchain, variant, env):
'-Wno-unused-function',
])
else:
env.Append(LINKFLAGS=[
'-static-libstdc++',
])
if should_link_static():
env.Append(LINKFLAGS=[
'-static-libstdc++',
])
if toolchain == 'gcc':
if os.getenv('RIPPLED_OLD_GCC_ABI'):
gcc_ver = ''
try:
gcc_ver = subprocess.check_output(['gcc', '-dumpversion'],
stderr=subprocess.STDOUT).strip()
except:
pass
if gcc_ver.startswith('5'):
# remove rpath and CXX11_ABI flag when distro uses
# non-user installed gcc 5
env.Append(CPPDEFINES={
'-D_GLIBCXX_USE_CXX11_ABI' : 0
})
if use_gcc4_abi(env['CC'] if 'CC' in env else 'gcc'):
env.Append(CPPDEFINES={
'-D_GLIBCXX_USE_CXX11_ABI' : 0
})
env.Append(CCFLAGS=[
'-Wno-unused-but-set-variable',
@@ -460,7 +525,9 @@ def config_env(toolchain, variant, env):
]
env.Append(LIBS=['dl'])
if Beast.system.osx:
if should_link_static():
add_static_libs(env, boost_libs)
else:
# We prefer static libraries for boost
if env.get('BOOST_ROOT'):
static_libs = ['%s/stage/lib/lib%s.a' % (env['BOOST_ROOT'], l) for
@@ -468,6 +535,8 @@ def config_env(toolchain, variant, env):
if all(os.path.exists(f) for f in static_libs):
boost_libs = [File(f) for f in static_libs]
env.Append(LIBS=boost_libs)
if Beast.system.osx:
env.Append(LIBS=[
'crypto',
'protobuf',
@@ -478,7 +547,6 @@ def config_env(toolchain, variant, env):
'Foundation'
])
else:
add_static_libs(env, boost_libs)
env.Append(LIBS=['rt'])
if variant == 'release':
@@ -888,6 +956,13 @@ def should_prepare_targets(style, toolchain, variant):
if should_prepare_target(t, style, toolchain, variant):
return True
def should_link_static():
"""
Return True if libraries should be linked statically
"""
return GetOption('static')
def should_build_ninja(style, toolchain, variant):
"""
Return True if a ninja build file should be generated.

View File

@@ -17,10 +17,10 @@ done
export PATH=$PWD/bin:$PATH
# What versions are we ACTUALLY running?
if [ -x $HOME/bin/g++]; then
if [ -x $HOME/bin/g++ ]; then
$HOME/bin/g++ -v
fi
if [ -x $HOME/bin/clang]; then
if [ -x $HOME/bin/clang ]; then
$HOME/bin/clang -v
fi
# Avoid `spurious errors` caused by ~/.npm permission issues

View File

@@ -518,8 +518,8 @@ int main (int argc, char** argv)
(__GNUC_MINOR__ * 100) +
__GNUC_PATCHLEVEL__;
static_assert (gccver >= 40801,
"GCC version 4.8.1 or later is required to compile rippled.");
static_assert (gccver >= 50100,
"GCC version 5.1.0 or later is required to compile rippled.");
#endif
static_assert (BOOST_VERSION >= 105700,