Support for clang specific boost and protobuf dirs:

Clang does not understand gcc 5's new ABI. On linux systems
that default to the new ABI (such as ubuntu 15.10), building
with clang requires using C++ libraries built with the the old
gcc ABI.

When building with the clang protobuf lib, a common error is to
load the gcc protobuf library at run time. When set, PROTOBUF_ROOT
is added to rpath to make sure the correct lib is loaded.

Adds a script to install clang and download and build boost and
protobuf with boost.
This commit is contained in:
seelabs
2016-02-03 16:27:46 -05:00
committed by Nik Bougalis
parent 35ed095dbf
commit 41125a0a34
2 changed files with 128 additions and 27 deletions

View File

@@ -0,0 +1,79 @@
#!/usr/bin/env bash
#
# This scripts installs boost and protobuf built with clang. This is needed on
# ubuntu 15.10 when building with clang
# It will build these in a 'clang' subdirectory that it creates below the directory
# this script is run from. If a clang directory already exists the script will refuse
# to run.
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 ! hash clang 2>/dev/null; then
clang_version=3.7
sudo apt-get -y install clang-${clang_version}
update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${clang_version} 99 clang++
hash -r
if ! hash clang 2>/dev/null; then
echo "Please install clang"
exit 1
fi
fi
if [ ${ubuntu_release} != "15.10" ]; then
echo "clang specific boost and protobuf not needed"
exit 0
fi
if [ -d clang ]; then
echo "clang directory already exists. Cowardly refusing to run"
exit 1
fi
if ! hash wget 2>/dev/null; then
sudo apt-get -y install wget
hash -r
if ! hash wget 2>/dev/null; then
echo "Please install wget"
exit 1
fi
fi
num_procs=$(lscpu -p | grep -v '^#' | sort -u -t, -k 2,4 | wc -l) # pysical cores
mkdir clang
pushd clang > /dev/null
# Install protobuf
pb=protobuf-2.6.1
pb_tar=${pb}.tar.gz
wget -O ${pb_tar} https://github.com/google/protobuf/releases/download/v2.6.1/${pb_tar}
tar xf ${pb_tar}
rm ${pb_tar}
pushd ${pb} > /dev/null
./configure CC=clang CXX=clang++ CXXFLAGS='-std=c++14 -O3 -g'
make -j${num_procs}
popd > /dev/null
# Install boost
boost_ver=1.60.0
bd=boost_${boost_ver//./_}
bd_tar=${bd}.tar.gz
wget -O ${bd_tar} http://sourceforge.net/projects/boost/files/boost/${boost_ver}/${bd_tar}
tar xf ${bd_tar}
rm ${bd_tar}
pushd ${bd} > /dev/null
./bootstrap.sh
./b2 toolset=clang -j${num_procs}
popd > /dev/null
popd > /dev/null

View File

@@ -61,10 +61,16 @@ The following environment variables modify the build environment:
Path to the boost directory.
OPENSSL_ROOT
Path to the openssl directory.
PROTOBUF_DIR
Path to the protobuf directory. This is usually only needed when
the installed protobuf library uses a different ABI than clang
(as with ubuntu 15.10).
PROTOBUF_ROOT
Path to the protobuf directory.
CLANG_PROTOBUF_ROOT
Override the path to the protobuf directory for the clang toolset. This is
usually only needed when the installed protobuf library uses a different
ABI than clang (as with ubuntu 15.10).
CLANG_BOOST_ROOT
Override the path to the boost directory for the clang toolset. This is
usually only needed when the installed protobuf library uses a different
ABI than clang (as with ubuntu 15.10).
The following extra options may be used:
--ninja Generate a `build.ninja` build file for the specified target
@@ -356,21 +362,6 @@ def config_base(env):
,'-DBOOST_NO_AUTO_PTR'
])
try:
BOOST_ROOT = os.path.normpath(os.environ['BOOST_ROOT'])
env.Append(LIBPATH=[
os.path.join(BOOST_ROOT, 'stage', 'lib'),
])
env['BOOST_ROOT'] = BOOST_ROOT
except KeyError:
pass
try:
protobuf_dir = os.environ['PROTOBUF_DIR']
env.Append(LIBPATH=[protobuf_dir])
except KeyError:
pass
if Beast.system.windows:
try:
OPENSSL_ROOT = os.path.normpath(os.environ['OPENSSL_ROOT'])
@@ -444,21 +435,52 @@ def add_sanitizer (toolchain, env):
add_static_libs(env, [san_to_lib[san]])
env.Append(CPPDEFINES=['SANITIZER='+san_to_lib[san].upper()])
# Set toolchain and variant specific construction variables
def config_env(toolchain, variant, env):
if is_debug_variant(variant):
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
def add_boost_and_protobuf(toolchain, env):
def get_environ_value(candidates):
for c in candidates:
try:
return os.environ[c]
except KeyError:
pass
raise KeyError('Environment variable not set')
elif variant == 'release' or variant == 'profile':
env.Append(CPPDEFINES=['NDEBUG'])
if 'BOOST_ROOT' in env:
try:
br_cands = ['CLANG_BOOST_ROOT'] if toolchain == 'clang' else []
br_cands.append('BOOST_ROOT')
BOOST_ROOT = os.path.normpath(get_environ_value(br_cands))
env.Append(LIBPATH=[
os.path.join(BOOST_ROOT, 'stage', 'lib'),
])
env['BOOST_ROOT'] = BOOST_ROOT
if toolchain == 'gcc':
env.Append(CCFLAGS=['-isystem' + env['BOOST_ROOT']])
else:
env.Append(CPPPATH=[
env['BOOST_ROOT'],
])
except KeyError:
pass
try:
pb_cands = ['CLANG_PROTOBUF_ROOT'] if toolchain == 'clang' else []
pb_cands.append('PROTOBUF_ROOT')
PROTOBUF_ROOT = os.path.normpath(get_environ_value(pb_cands))
env.Append(LIBPATH=[PROTOBUF_ROOT + '/src/.libs'])
if not should_link_static() and toolchain in['clang', 'gcc']:
env.Append(LINKFLAGS=['-Wl,-rpath,' + PROTOBUF_ROOT + '/src/.libs'])
env['PROTOBUF_ROOT'] = PROTOBUF_ROOT
env.Append(CPPPATH=[env['PROTOBUF_ROOT'] + '/src',])
except KeyError:
pass
# Set toolchain and variant specific construction variables
def config_env(toolchain, variant, env):
add_boost_and_protobuf(toolchain, env)
if is_debug_variant(variant):
env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
elif variant == 'release' or variant == 'profile':
env.Append(CPPDEFINES=['NDEBUG'])
if should_link_static() and not Beast.system.linux:
raise Exception("Static linking is only implemented for linux.")