Loading build/moz.build +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ if CONFIG["OS_ARCH"] == "WINNT": else: DIRS += ["unix"] if CONFIG["MOZ_LIBSTDCXX_TARGET_VERSION"] or CONFIG["MOZ_LIBSTDCXX_HOST_VERSION"]: if CONFIG["MOZ_STDCXX_COMPAT"]: DIRS += ["unix/stdc++compat"] CRAMTEST_MANIFESTS += [ Loading build/moz.configure/toolchain.configure +13 −28 Original line number Diff line number Diff line Loading @@ -2471,50 +2471,35 @@ add_old_configure_assignment( # Libstdc++ compatibility hacks # ============================================================== # @depends(target, host) def target_or_host_is_linux(target, host): return any(t.os == "GNU" and t.kernel == "Linux" for t in (target, host)) option( "--enable-stdcxx-compat", env="MOZ_STDCXX_COMPAT", help="Enable compatibility with older libstdc++", when=depends(target, host)( lambda target, host: any( t.os == "GNU" and t.kernel == "Linux" for t in (target, host) ) ), when=target_or_host_is_linux, ) @template def libstdcxx_version(var, compiler): @depends(compiler, when="--enable-stdcxx-compat") @checking(var, lambda v: v and "GLIBCXX_%s" % v.dotted) @imports(_from="mozbuild.configure.libstdcxx", _import="find_version") @imports(_from="__builtin__", _import="Exception") def version(compiler): try: result = find_version( compiler.wrapper + [compiler.compiler] + compiler.flags ) except Exception: die("Couldn't determine libstdc++ version") if result: return namespace( dotted=result[0], encoded=str(result[1]), ) set_config(var, version.encoded) return version @depends("--enable-stdcxx-compat", when=target_or_host_is_linux) def stdcxx_compat(value): if value: return True set_config("MOZ_STDCXX_COMPAT", True, when=stdcxx_compat) add_gcc_flag( "-D_GLIBCXX_USE_CXX11_ABI=0", cxx_compiler, when=libstdcxx_version("MOZ_LIBSTDCXX_TARGET_VERSION", cxx_compiler), when=stdcxx_compat, ) add_gcc_flag( "-D_GLIBCXX_USE_CXX11_ABI=0", host_cxx_compiler, when=libstdcxx_version("MOZ_LIBSTDCXX_HOST_VERSION", host_cxx_compiler), when=stdcxx_compat, ) Loading build/unix/stdc++compat/moz.build +2 −2 Original line number Diff line number Diff line Loading @@ -4,11 +4,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. if CONFIG["MOZ_LIBSTDCXX_TARGET_VERSION"]: if CONFIG["OS_TARGET"] == "Linux": Library("stdc++compat") SOURCES += ["stdc++compat.cpp"] if CONFIG["MOZ_LIBSTDCXX_HOST_VERSION"]: if CONFIG["HOST_OS_ARCH"] == "Linux": HostLibrary("host_stdc++compat") HOST_SOURCES += [ "stdc++compat.cpp", Loading python/mozbuild/mozbuild/action/check_binary.py +3 −12 Original line number Diff line number Diff line Loading @@ -15,11 +15,7 @@ from distutils.version import StrictVersion as Version import buildconfig from mozbuild.action.util import log_build_task from mozbuild.util import memoize from mozpack.executables import ( get_type, ELF, UNKNOWN, ) from mozpack.executables import get_type, ELF, UNKNOWN STDCXX_MAX_VERSION = Version("3.4.19") Loading @@ -27,14 +23,9 @@ CXXABI_MAX_VERSION = Version("1.3.7") GLIBC_MAX_VERSION = Version("2.17") LIBGCC_MAX_VERSION = Version("4.8") HOST = { "MOZ_LIBSTDCXX_VERSION": buildconfig.substs.get("MOZ_LIBSTDCXX_HOST_VERSION"), "platform": buildconfig.substs["HOST_OS_ARCH"], "readelf": "readelf", } HOST = {"platform": buildconfig.substs["HOST_OS_ARCH"], "readelf": "readelf"} TARGET = { "MOZ_LIBSTDCXX_VERSION": buildconfig.substs.get("MOZ_LIBSTDCXX_TARGET_VERSION"), "platform": buildconfig.substs["OS_TARGET"], "readelf": "{}readelf".format(buildconfig.substs.get("TOOLCHAIN_PREFIX", "")), } Loading Loading @@ -286,7 +277,7 @@ def checks(target, binary): if "clang-plugin" in binary: target = HOST checks = [] if target["MOZ_LIBSTDCXX_VERSION"]: if buildconfig.substs.get("MOZ_STDCXX_COMPAT") and target["platform"] == "Linux": checks.append(check_binary_compat) # Disabled for local builds because of readelf performance: See bug 1472496 Loading python/mozbuild/mozbuild/configure/libstdcxx.pydeleted 100755 → 0 +0 −94 Original line number Diff line number Diff line #!/usr/bin/python # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # 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. from __future__ import absolute_import, print_function import os import subprocess import re import six 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 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(args): """Given a base command line for a compiler, find the version of the libstdc++ it uses. """ args += ["-shared", "-Wl,-t"] p = subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) candidates = [six.ensure_text(x, encoding="ascii") for x in p.stdout] candidates = [x for x in candidates if "libstdc++.so" in x] candidates = [x for x in candidates if "skipping incompatible" not in x] if not candidates: raise Exception( """Couldn't find libstdc++ candidates! command line: %s""" % args ) if len(candidates) != 1: raise Exception( """Too many libstdc++ candidates! command line: %s candidates: %s""" % (args, "\n".join(candidates)) ) libstdcxx = parse_ld_line(candidates[-1]) p = subprocess.Popen(["readelf", "-V", libstdcxx], stdout=subprocess.PIPE) lines = [six.ensure_text(x, encoding="ascii") for x in p.stdout] versions = [parse_readelf_line(x) for x in lines if "Name: GLIBCXX" in x] last_version = sorted(versions, key=split_ver)[-1] return (last_version, encode_ver(last_version)) if __name__ == "__main__": """Given the value of environment variable CXX or HOST_CXX, find the version of the libstdc++ it uses. """ cxx_env = os.environ["CXX"] print("MOZ_LIBSTDCXX_TARGET_VERSION=%s" % find_version(cxx_env.split())[1]) host_cxx_env = os.environ.get("HOST_CXX", cxx_env) print("MOZ_LIBSTDCXX_HOST_VERSION=%s" % find_version(host_cxx_env.split())[1]) Loading
build/moz.build +1 −1 Original line number Diff line number Diff line Loading @@ -18,7 +18,7 @@ if CONFIG["OS_ARCH"] == "WINNT": else: DIRS += ["unix"] if CONFIG["MOZ_LIBSTDCXX_TARGET_VERSION"] or CONFIG["MOZ_LIBSTDCXX_HOST_VERSION"]: if CONFIG["MOZ_STDCXX_COMPAT"]: DIRS += ["unix/stdc++compat"] CRAMTEST_MANIFESTS += [ Loading
build/moz.configure/toolchain.configure +13 −28 Original line number Diff line number Diff line Loading @@ -2471,50 +2471,35 @@ add_old_configure_assignment( # Libstdc++ compatibility hacks # ============================================================== # @depends(target, host) def target_or_host_is_linux(target, host): return any(t.os == "GNU" and t.kernel == "Linux" for t in (target, host)) option( "--enable-stdcxx-compat", env="MOZ_STDCXX_COMPAT", help="Enable compatibility with older libstdc++", when=depends(target, host)( lambda target, host: any( t.os == "GNU" and t.kernel == "Linux" for t in (target, host) ) ), when=target_or_host_is_linux, ) @template def libstdcxx_version(var, compiler): @depends(compiler, when="--enable-stdcxx-compat") @checking(var, lambda v: v and "GLIBCXX_%s" % v.dotted) @imports(_from="mozbuild.configure.libstdcxx", _import="find_version") @imports(_from="__builtin__", _import="Exception") def version(compiler): try: result = find_version( compiler.wrapper + [compiler.compiler] + compiler.flags ) except Exception: die("Couldn't determine libstdc++ version") if result: return namespace( dotted=result[0], encoded=str(result[1]), ) set_config(var, version.encoded) return version @depends("--enable-stdcxx-compat", when=target_or_host_is_linux) def stdcxx_compat(value): if value: return True set_config("MOZ_STDCXX_COMPAT", True, when=stdcxx_compat) add_gcc_flag( "-D_GLIBCXX_USE_CXX11_ABI=0", cxx_compiler, when=libstdcxx_version("MOZ_LIBSTDCXX_TARGET_VERSION", cxx_compiler), when=stdcxx_compat, ) add_gcc_flag( "-D_GLIBCXX_USE_CXX11_ABI=0", host_cxx_compiler, when=libstdcxx_version("MOZ_LIBSTDCXX_HOST_VERSION", host_cxx_compiler), when=stdcxx_compat, ) Loading
build/unix/stdc++compat/moz.build +2 −2 Original line number Diff line number Diff line Loading @@ -4,11 +4,11 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. if CONFIG["MOZ_LIBSTDCXX_TARGET_VERSION"]: if CONFIG["OS_TARGET"] == "Linux": Library("stdc++compat") SOURCES += ["stdc++compat.cpp"] if CONFIG["MOZ_LIBSTDCXX_HOST_VERSION"]: if CONFIG["HOST_OS_ARCH"] == "Linux": HostLibrary("host_stdc++compat") HOST_SOURCES += [ "stdc++compat.cpp", Loading
python/mozbuild/mozbuild/action/check_binary.py +3 −12 Original line number Diff line number Diff line Loading @@ -15,11 +15,7 @@ from distutils.version import StrictVersion as Version import buildconfig from mozbuild.action.util import log_build_task from mozbuild.util import memoize from mozpack.executables import ( get_type, ELF, UNKNOWN, ) from mozpack.executables import get_type, ELF, UNKNOWN STDCXX_MAX_VERSION = Version("3.4.19") Loading @@ -27,14 +23,9 @@ CXXABI_MAX_VERSION = Version("1.3.7") GLIBC_MAX_VERSION = Version("2.17") LIBGCC_MAX_VERSION = Version("4.8") HOST = { "MOZ_LIBSTDCXX_VERSION": buildconfig.substs.get("MOZ_LIBSTDCXX_HOST_VERSION"), "platform": buildconfig.substs["HOST_OS_ARCH"], "readelf": "readelf", } HOST = {"platform": buildconfig.substs["HOST_OS_ARCH"], "readelf": "readelf"} TARGET = { "MOZ_LIBSTDCXX_VERSION": buildconfig.substs.get("MOZ_LIBSTDCXX_TARGET_VERSION"), "platform": buildconfig.substs["OS_TARGET"], "readelf": "{}readelf".format(buildconfig.substs.get("TOOLCHAIN_PREFIX", "")), } Loading Loading @@ -286,7 +277,7 @@ def checks(target, binary): if "clang-plugin" in binary: target = HOST checks = [] if target["MOZ_LIBSTDCXX_VERSION"]: if buildconfig.substs.get("MOZ_STDCXX_COMPAT") and target["platform"] == "Linux": checks.append(check_binary_compat) # Disabled for local builds because of readelf performance: See bug 1472496 Loading
python/mozbuild/mozbuild/configure/libstdcxx.pydeleted 100755 → 0 +0 −94 Original line number Diff line number Diff line #!/usr/bin/python # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # 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. from __future__ import absolute_import, print_function import os import subprocess import re import six 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 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(args): """Given a base command line for a compiler, find the version of the libstdc++ it uses. """ args += ["-shared", "-Wl,-t"] p = subprocess.Popen(args, stderr=subprocess.STDOUT, stdout=subprocess.PIPE) candidates = [six.ensure_text(x, encoding="ascii") for x in p.stdout] candidates = [x for x in candidates if "libstdc++.so" in x] candidates = [x for x in candidates if "skipping incompatible" not in x] if not candidates: raise Exception( """Couldn't find libstdc++ candidates! command line: %s""" % args ) if len(candidates) != 1: raise Exception( """Too many libstdc++ candidates! command line: %s candidates: %s""" % (args, "\n".join(candidates)) ) libstdcxx = parse_ld_line(candidates[-1]) p = subprocess.Popen(["readelf", "-V", libstdcxx], stdout=subprocess.PIPE) lines = [six.ensure_text(x, encoding="ascii") for x in p.stdout] versions = [parse_readelf_line(x) for x in lines if "Name: GLIBCXX" in x] last_version = sorted(versions, key=split_ver)[-1] return (last_version, encode_ver(last_version)) if __name__ == "__main__": """Given the value of environment variable CXX or HOST_CXX, find the version of the libstdc++ it uses. """ cxx_env = os.environ["CXX"] print("MOZ_LIBSTDCXX_TARGET_VERSION=%s" % find_version(cxx_env.split())[1]) host_cxx_env = os.environ.get("HOST_CXX", cxx_env) print("MOZ_LIBSTDCXX_HOST_VERSION=%s" % find_version(host_cxx_env.split())[1])