1# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
2# vim: set filetype=python:
3# This Source Code Form is subject to the terms of the Mozilla Public
4# License, v. 2.0. If a copy of the MPL was not distributed with this
5# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7# We support C++14, but we don't want to enable the sized deallocation
8# facilities in C++14 yet.
9check_and_add_gcc_flag("-fno-sized-deallocation", compiler=cxx_compiler)
10# Likewise for C++17 and aligned allocation.  It's not immediately obvious
11# from the clang and GCC documentation, but they both support this.
12check_and_add_gcc_flag("-fno-aligned-new", compiler=cxx_compiler)
13
14# Please keep these last in this file.
15add_old_configure_assignment("_COMPILATION_CFLAGS", compilation_flags.cflags)
16add_old_configure_assignment("_COMPILATION_CXXFLAGS", compilation_flags.cxxflags)
17add_old_configure_assignment("_COMPILATION_HOST_CFLAGS", compilation_flags.host_cflags)
18add_old_configure_assignment(
19    "_COMPILATION_HOST_CXXFLAGS", compilation_flags.host_cxxflags
20)
21
22
23option(
24    "--disable-new-pass-manager",
25    help="Use the legacy LLVM pass manager in clang builds",
26)
27
28
29@depends(
30    "--enable-new-pass-manager",
31    c_compiler,
32    host,
33    target,
34    "MOZ_PGO",
35    enable_fuzzing,
36    ubsan,
37)
38def pass_manager(enabled, compiler, host, target, pgo, enable_fuzzing, ubsan):
39    if compiler.type not in ("clang", "clang-cl"):
40        return None
41
42    # As of clang 13, the default pass manager is the new one.
43    if compiler.version >= "13.0.0":
44        if enabled:
45            return namespace(flags=None, enabled=True)
46        if compiler.type == "clang":
47            return namespace(flags=["-flegacy-pass-manager"], enabled=False)
48        if compiler.type == "clang-cl":
49            return namespace(flags=["-Xclang", "-flegacy-pass-manager"], enabled=False)
50
51    if not enabled:
52        return None
53    if compiler.version < "9.0.0":
54        if enabled.origin != "default":
55            die("--enable-new-pass-manager is only supported with clang >= 9")
56        return None
57
58    if host.os == "OSX":
59        # Some native Mac builds hang with the new pass manager. Given the
60        # inability to test in CI, don't take the risk of further breakage.
61        if enabled.origin != "default":
62            die(
63                "--enable-new-pass-manager causes problems on mac hosts with clang < 13"
64            )
65        return None
66    if target.os == "OSX" and not pgo:
67        # Also disable when cross-compiling to Mac, because plain-ish opt
68        # builds hang. Variants like asan and ccov work fine, but it would be
69        # too tedious to test them all here. PGO is the only thing that matters
70        # enough to make an exception for.
71        if enabled.origin != "default":
72            die(
73                "--enable-new-pass-manager causes problems on mac builds with clang < 13"
74            )
75        return None
76    if enable_fuzzing and compiler.version < "10.0.0":
77        # Clang 9 does not seem to play well with libFuzzer
78        if enabled.origin != "default":
79            die(
80                "--enable-new-pass-manager causes problems on fuzzing builds with clang < 10"
81            )
82        return None
83    if ubsan and compiler.version == "10.0.0":
84        # Clang 10.0.0 hangs with some ubsan-inserted code constructs.
85        # This was fixed in 10.0.1 (https://llvm.org/pr45835)
86        if enabled.origin != "default":
87            die(
88                "--enable-new-pass-manager causes problems with ubsan builds with clang 10.0.0"
89            )
90        return None
91    if compiler.type == "clang":
92        return namespace(flags=["-fexperimental-new-pass-manager"], enabled=True)
93    elif compiler.type == "clang-cl":
94        return namespace(
95            flags=["-Xclang", "-fexperimental-new-pass-manager"], enabled=True
96        )
97
98
99set_config("MOZ_PASS_MANAGER_FLAGS", pass_manager.flags)
100
101
102# Try to make builds more reproducible and allow sharing built artifacts across
103# source and object directories by using -ffile-prefix-map and friends.  To
104# "unwind" the prefix maps, use:
105#
106# (gdb) set substitute-path /topsrcdir/ $topsrcdir/
107#
108# (lldb) settings set target.source-map /topobjdir/ $topobjdir/
109#
110# See, for example, https://lldb.llvm.org/use/map.html.
111@depends(
112    path_remapping,
113    path_remappings,
114    c_compiler,
115)
116@imports(_from="os", _import="sep")
117def file_prefix_map_flags(path_remapping, path_remappings, compiler):
118    if "c" not in path_remapping:
119        return []
120
121    if (compiler.type == "gcc" and compiler.version < "8.1") or (
122        compiler.type in ("clang", "clang-cl") and compiler.version < "10.0.0"
123    ):
124        die(
125            f"Compiler of type {compiler.type} and version {compiler.version} "
126            "does not support --enable-path-remapping."
127        )
128
129    flags = []
130    for old, new in path_remappings:
131        # We would prefer to use just -ffile-prefix-map, but clang-cl doesn't
132        # seem to recognize it.
133        for flag in ("-fdebug-prefix-map", "-fmacro-prefix-map"):
134            flag = f"{flag}={old}={new}"
135            if compiler.type in ("gcc", "clang"):
136                flags.append(flag)
137            elif compiler.type == "clang-cl":
138                flags.extend(["-Xclang", flag])
139
140    return flags
141
142
143set_config("MOZ_FILE_PREFIX_MAP_FLAGS", file_prefix_map_flags)
144