Commit e5446261 authored by Mike Hommey's avatar Mike Hommey
Browse files

Bug 1724830 - Remove MOZ_LIBSTDCXX_*_VERSION. r=firefox-build-system-reviewers,andi

parent 139b1d25
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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 += [
+13 −28
Original line number Diff line number Diff line
@@ -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,
)


+2 −2
Original line number Diff line number Diff line
@@ -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",
+3 −12
Original line number Diff line number Diff line
@@ -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")
@@ -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", "")),
}
@@ -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
+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