From f5ea42b11f9ea42765c00bf7dc2841c8f0b4cc5f Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 9 Nov 2017 10:07:26 -0800 Subject: [PATCH] at workaround for throw_out_of_range_fmt remove inadvertent change also dump glibcxx symbols on circle add glibc_workaround.cpp if option is chosen This reverts commit 751d9bff1672f6b8cbd2b5ebe2eb460223746806. add script that asserts on expected symbols check symbols for all modes, only error if symbols exist + ENABLE_GLIBC_WORKAROUND --- .travis.yml | 10 +++++--- SConstruct | 4 +++ circle.yml | 1 + scripts/check_glibcxx.sh | 36 +++++++++++++++++++++++++++ src/build.py | 7 ++++++ src/font_engine_freetype.cpp | 1 + src/glibc_workaround.cpp | 48 ++++++++++++++++++++++++++++++++++++ 7 files changed, 104 insertions(+), 3 deletions(-) create mode 100755 scripts/check_glibcxx.sh create mode 100644 src/glibc_workaround.cpp diff --git a/.travis.yml b/.travis.yml index d2065e4c3..0e769e93b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ matrix: - os: linux sudo: false compiler: ": clang" - env: JOBS=8 CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" TRIGGER=true + env: JOBS=8 CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" ENABLE_GLIBC_WORKAROUND=True TRIGGER=true addons: apt: sources: [ 'ubuntu-toolchain-r-test'] @@ -95,7 +95,7 @@ before_script: script: - export SCONSFLAGS='--debug=time' - - configure BENCHMARK=${BENCH} + - configure BENCHMARK=${BENCH} ENABLE_GLIBC_WORKAROUND=${ENABLE_GLIBC_WORKAROUND:-False} - cat config.log # we limit the `make` to 40 min # to ensure that slow builds still upload their @@ -108,4 +108,8 @@ script: # we allow visual failures with g++ for now: https://github.com/mapnik/mapnik/issues/3567 - if [[ ${RESULT} != 0 ]] && [[ ${CXX} =~ 'clang++' ]]; then false; fi; - enabled ${COVERAGE} coverage - - enabled ${BENCH} make bench \ No newline at end of file + - enabled ${BENCH} make bench + - ./scripts/check_glibcxx.sh + +after_success: + - enabled ${TRIGGER} trigger_downstream diff --git a/SConstruct b/SConstruct index a3f725c4f..54c88bd35 100644 --- a/SConstruct +++ b/SConstruct @@ -308,6 +308,7 @@ opts.AddVariables( BoolVariable('USE_CONFIG', "Use SCons user '%s' file (will also write variables after successful configuration)", 'True'), BoolVariable('NO_ATEXIT', 'Will prevent Singletons from being deleted atexit of main thread', 'False'), BoolVariable('NO_DLCLOSE', 'Will prevent plugins from being unloaded', 'False'), + BoolVariable('ENABLE_GLIBC_WORKAROUND', "Workaround known GLIBC symbol exports to allow building against libstdc++-4.8 without binaries needing throw_out_of_range_fmt", 'False'), # http://www.scons.org/wiki/GoFastButton # http://stackoverflow.com/questions/1318863/how-to-optimize-an-scons-script BoolVariable('FAST', "Make SCons faster at the cost of less precise dependency tracking", 'False'), @@ -1872,6 +1873,9 @@ if not preconfigured: if env['NO_DLCLOSE'] or env['COVERAGE']: env.Append(CPPDEFINES = '-DMAPNIK_NO_DLCLOSE') + if env['ENABLE_GLIBC_WORKAROUND']: + env.Append(CPPDEFINES = '-DMAPNIK_ENABLE_GLIBC_WORKAROUND') + # Mac OSX (Darwin) special settings if env['PLATFORM'] == 'Darwin': pthread = '' diff --git a/circle.yml b/circle.yml index 5624c66ae..02c414772 100644 --- a/circle.yml +++ b/circle.yml @@ -32,6 +32,7 @@ database: - ./.mason/mason link clang++ ${LLVM_VERSION} - ./configure CC="$(pwd)/mason_packages/.link/bin/clang" CXX="$(pwd)/mason_packages/.link/bin/ccache $(pwd)/mason_packages/.link/bin/clang++ -Qunused-arguments" - make + - nm src/libmapnik* | grep "GLIBCXX_3.4.2[0-9]" || true override: - psql -c 'create database template_postgis;' - psql -c 'create extension postgis;' -d template_postgis diff --git a/scripts/check_glibcxx.sh b/scripts/check_glibcxx.sh new file mode 100755 index 000000000..ae298939e --- /dev/null +++ b/scripts/check_glibcxx.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -eu +set -o pipefail +shopt -s nullglob + +: ' + +Ensure no GLIBCXX_3.4.2x symbols are present in the binary +if ENABLE_GLIBC_WORKAROUND is set. + +If symbols >= 3.4.20 then it means the binaries would not run on ubuntu trusty without upgrading libstdc++ + +' + +FINAL_RETURN_CODE=0 + +function check() { + local RESULT=0 + nm ${1} | grep "GLIBCXX_3.4.2[0-9]" > /tmp/out.txt || RESULT=$? + if [[ ${RESULT} != 0 ]]; then + echo "Success: GLIBCXX_3.4.2[0-9] symbols not present in binary (as expected)" + else + echo "$(cat /tmp/out.txt | c++filt)" + if [[ ${ENABLE_GLIBC_WORKAROUND:-false} == true ]]; then + FINAL_RETURN_CODE=1 + fi + fi +} + +for i in src/libmapnik*; do + echo "checking $i" + check $i +done + +exit ${FINAL_RETURN_CODE} diff --git a/src/build.py b/src/build.py index 6dd0f24a9..883f17cc3 100644 --- a/src/build.py +++ b/src/build.py @@ -307,6 +307,13 @@ cairo/process_markers_symbolizer.cpp cairo/process_group_symbolizer.cpp """) +if env['ENABLE_GLIBC_WORKAROUND']: + source += Split( + """ + glibc_workaround.cpp + """ + ) + if env['HAS_CAIRO']: lib_env.AppendUnique(LIBPATH=env['CAIRO_LIBPATHS']) lib_env.Append(CPPDEFINES = '-DHAVE_CAIRO') diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 4d504a8ff..e8bb492a0 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -53,6 +53,7 @@ namespace mapnik { template class MAPNIK_DECL singleton; + bool freetype_engine::is_font_file(std::string const& file_name) { // only accept files that will be matched by freetype2's `figurefiletype()` diff --git a/src/glibc_workaround.cpp b/src/glibc_workaround.cpp new file mode 100644 index 000000000..27c97f4dd --- /dev/null +++ b/src/glibc_workaround.cpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2017 Artem Pavlenko + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + *****************************************************************************/ + +#ifdef __linux__ + +#ifdef MAPNIK_ENABLE_GLIBC_WORKAROUND + +#include + +// https://github.com/bitcoin/bitcoin/pull/4042 +// allows building against libstdc++-dev-4.9 while avoiding +// GLIBCXX_3.4.20 dep +// This is needed because libstdc++ itself uses this API - its not +// just an issue of your code using it, ughhh + +namespace std +{ + +void __throw_out_of_range_fmt(const char *, ...) __attribute__((__noreturn__)); +void __throw_out_of_range_fmt(const char *err, ...) +{ + // Safe and over-simplified version. Ignore the format and print it as-is. + __throw_out_of_range(err); +} +} + +#endif // MAPNIK_ENABLE_GLIBC_WORKAROUND + +#endif // __linux__