Bug 657653. Check for libstdc++ versions in stdc++compat.cpp; r=ted,glandium

This commit is contained in:
Rafael Ávila de Espíndola 2011-06-08 22:35:24 -04:00
Родитель 53103940ec
Коммит 1dba5e3383
6 изменённых файлов: 108 добавлений и 8 удалений

73
build/autoconf/libstdcxx.py Executable file
Просмотреть файл

@ -0,0 +1,73 @@
#!/usr/bin/python
# This script find the version of libstdc++ and prints it as single number
# with 8 bits per element. For example, GLIBCXX_3.4.10 becomes
# 3 << 16 | 4 << 8 | 10 = 197642. This format is easy to use
# in the C preprocessor.
# We find out both the host and target versions. Since the output
# will be used from shell, we just print the two assignments and evaluate
# them from shell.
import os
import subprocess
import re
re_for_ld = re.compile('.*\((.*)\).*')
def parse_readelf_line(x):
"""Return the version from a readelf line that looks like:
0x00ec: Rev: 1 Flags: none Index: 8 Cnt: 2 Name: GLIBCXX_3.4.6
"""
return x.split(':')[-1].split('_')[-1].strip()
def parse_ld_line(x):
"""Parse a line from the output of ld -t. The output of gold is just
the full path, gnu ld prints "-lstdc++ (path)".
"""
t = re_for_ld.match(x)
if t:
return t.groups()[0].strip()
return x.strip()
def split_ver(v):
"""Covert the string '1.2.3' into the list [1,2,3]
"""
return [int(x) for x in v.split('.')]
def cmp_ver(a, b):
"""Compare versions in the form 'a.b.c'
"""
for (i, j) in zip(split_ver(a), split_ver(b)):
if i != j:
return i - j
return 0
def encode_ver(v):
"""Encode the version as a single number.
"""
t = split_ver(v)
return t[0] << 16 | t[1] << 8 | t[2]
def find_version(e):
"""Given the value of environment variable CXX or HOST_CXX, find the
version of the libstdc++ it uses.
"""
args = e.split()
args += ['-shared', '-Wl,-t']
p = subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
candidates = [x for x in p.stdout if 'libstdc++.so' in x]
assert len(candidates) == 1
libstdcxx = parse_ld_line(candidates[-1])
p = subprocess.Popen(['readelf', '-V', libstdcxx], stdout=subprocess.PIPE)
versions = [parse_readelf_line(x)
for x in p.stdout.readlines() if 'Name: GLIBCXX' in x]
last_version = sorted(versions, cmp = cmp_ver)[-1]
return encode_ver(last_version)
if __name__ == '__main__':
cxx_env = os.environ['CXX']
print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % find_version(cxx_env)
host_cxx_env = os.environ.get('HOST_CXX', cxx_env)
print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % find_version(host_cxx_env)

Просмотреть файл

@ -41,8 +41,21 @@
#include <string>
#endif
/* GLIBCXX_3.4.8 is from gcc 4.1.1 (111691)
GLIBCXX_3.4.9 is from gcc 4.2.0 (111690)
GLIBCXX_3.4.10 is from gcc 4.3.0 (126287)
GLIBCXX_3.4.11 is from gcc 4.4.0 (133006)
GLIBCXX_3.4.12 is from gcc 4.4.1 (147138)
GLIBCXX_3.4.13 is from gcc 4.4.2 (151127)
GLIBCXX_3.4.14 is from gcc 4.5.0 (151126)
GLIBCXX_3.4.15 is from gcc 4.6.0 (160071)
GLIBCXX_3.4.16 is form gcc 4.6.1 (172240) */
#define GLIBCXX_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c))
namespace std {
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 9)
/* Instantiate these templates to avoid GLIBCXX_3.4.9 symbol versions */
template ostream& ostream::_M_insert(double);
template ostream& ostream::_M_insert(long);
@ -51,7 +64,7 @@ namespace std {
template istream& istream::_M_extract(double&);
#endif
#ifdef DEBUG
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
/* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
* in debug builds */
template char *string::_S_construct_aux_2(size_type, char, allocator<char> const&);
@ -70,7 +83,7 @@ namespace std {
}
namespace std __attribute__((visibility("default"))) {
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
/* Hack to avoid GLIBCXX_3.4.14 symbol versions */
struct _List_node_base
{
@ -82,7 +95,7 @@ namespace std __attribute__((visibility("default"))) {
_List_node_base * const __last) throw();
/* Hack to avoid GLIBCXX_3.4.15 symbol versions */
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 15)
static void swap(_List_node_base& __x, _List_node_base& __y) throw ();
};
@ -98,7 +111,7 @@ namespace std __attribute__((visibility("default"))) {
void _M_transfer(_List_node_base * const __first,
_List_node_base * const __last) throw();
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 15)
static void swap(_List_node_base& __x, _List_node_base& __y) throw ();
#endif
};
@ -124,7 +137,7 @@ namespace std __attribute__((visibility("default"))) {
(std::_List_node_base * const)__last);
}
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 15)
void
_List_node_base::swap(_List_node_base& __x, _List_node_base& __y) throw ()
{
@ -134,9 +147,9 @@ namespace std __attribute__((visibility("default"))) {
}
#endif
#endif /* (__GNUC__ == 4) && (__GNUC_MINOR__ >= 5) */
#endif /*MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)*/
#if (__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)
#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 11)
/* Hack to avoid GLIBCXX_3.4.11 symbol versions
An inline definition of ctype<char>::_M_widen_init() used to be in
locale_facets.h before GCC 4.4, but moved out of headers in more

Просмотреть файл

@ -120,6 +120,8 @@ NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
USE_ELF_HACK = @USE_ELF_HACK@
STDCXX_COMPAT = @STDCXX_COMPAT@
MOZ_LIBSTDCXX_TARGET_VERSION=@MOZ_LIBSTDCXX_TARGET_VERSION@
MOZ_LIBSTDCXX_HOST_VERSION=@MOZ_LIBSTDCXX_HOST_VERSION@
INCREMENTAL_LINKER = @INCREMENTAL_LINKER@
MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@
MOZ_MAIL_NEWS = @MOZ_MAIL_NEWS@

Просмотреть файл

@ -907,6 +907,9 @@ endif # NO_PROFILE_GUIDED_OPTIMIZE
##############################################
stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_TARGET_VERSION)
host_stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_HOST_VERSION)
checkout:
$(MAKE) -C $(topsrcdir) -f client.mk checkout

Просмотреть файл

@ -7665,6 +7665,12 @@ MOZ_ARG_ENABLE_BOOL(stdcxx-compat,
AC_SUBST(STDCXX_COMPAT)
if test -n "$STDCXX_COMPAT"; then
eval $($_topsrcdir/build/autoconf/libstdcxx.py)
AC_SUBST(MOZ_LIBSTDCXX_TARGET_VERSION)
AC_SUBST(MOZ_LIBSTDCXX_HOST_VERSION)
fi
dnl ========================================================
dnl =
dnl = Profiling and Instrumenting

Просмотреть файл

@ -907,6 +907,9 @@ endif # NO_PROFILE_GUIDED_OPTIMIZE
##############################################
stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_TARGET_VERSION)
host_stdc++compat.$(OBJ_SUFFIX): CXXFLAGS+=-DMOZ_LIBSTDCXX_VERSION=$(MOZ_LIBSTDCXX_HOST_VERSION)
checkout:
$(MAKE) -C $(topsrcdir) -f client.mk checkout