Browse Source

Merge pull request #63283 from akien-mga/3.x-scons-linux-refactor-linker

Rémi Verschelde 3 years ago
parent
commit
364071c2c4
2 changed files with 40 additions and 17 deletions
  1. 2 2
      .github/workflows/linux_builds.yml
  2. 38 15
      platform/x11/detect.py

+ 2 - 2
.github/workflows/linux_builds.yml

@@ -27,11 +27,11 @@ jobs:
             build-mono: true
             artifact: true
 
-          - name: Editor and sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes)
+          - name: Editor and sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, linker=gold)
             cache-name: linux-editor-sanitizers
             target: debug
             tools: true
-            sconsflags: use_asan=yes use_ubsan=yes
+            sconsflags: use_asan=yes use_ubsan=yes linker=gold
             test: true
             bin: "./bin/godot.x11.tools.64s"
             build-mono: false

+ 38 - 15
platform/x11/detect.py

@@ -64,9 +64,10 @@ def get_opts():
     from SCons.Variables import BoolVariable, EnumVariable
 
     return [
+        EnumVariable("linker", "Linker program", "default", ("default", "bfd", "gold", "lld", "mold")),
         BoolVariable("use_llvm", "Use the LLVM compiler", False),
-        BoolVariable("use_lld", "Use the LLD linker", False),
-        BoolVariable("use_thinlto", "Use ThinLTO", False),
+        BoolVariable("use_lld", "Use the LLD linker (deprecated, use `linker=lld` instead).", False),
+        BoolVariable("use_thinlto", "Use ThinLTO (LLVM only, requires linker=lld, implies use_lto=yes)", False),
         BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
         BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
         BoolVariable("use_asan", "Use LLVM/GCC compiler address sanitizer (ASAN))", False),
@@ -146,14 +147,37 @@ def configure(env):
         env.extra_suffix = ".llvm" + env.extra_suffix
 
     if env["use_lld"]:
-        if env["use_llvm"]:
-            env.Append(LINKFLAGS=["-fuse-ld=lld"])
-            if env["use_thinlto"]:
-                # A convenience so you don't need to write use_lto too when using SCons
-                env["use_lto"] = True
+        if env["linker"] != "default":
+            print("Can't specify both `use_lld=yes` and a non-default `linker`. Remove `use_lld=yes`.")
+            sys.exit(255)
+        print("The `use_lld=yes` option is deprecated, use `linker=lld` instead.")
+        env["linker"] == "lld"
+
+    if env["linker"] != "default":
+        print("Using linker program: " + env["linker"])
+        if env["linker"] == "mold" and using_gcc(env):  # GCC < 12.1 doesn't support -fuse-ld=mold.
+            cc_semver = tuple(get_compiler_version(env))
+            if cc_semver < (12, 1):
+                found_wrapper = False
+                for path in ["/usr/libexec", "/usr/local/libexec", "/usr/lib", "/usr/local/lib"]:
+                    if os.path.isfile(path + "/mold/ld"):
+                        env.Append(LINKFLAGS=["-B" + path + "/mold"])
+                        found_wrapper = True
+                        break
+                if not found_wrapper:
+                    print("Couldn't locate mold installation path. Make sure it's installed in /usr or /usr/local.")
+                    sys.exit(255)
+            else:
+                env.Append(LINKFLAGS=["-fuse-ld=mold"])
         else:
-            print("Using LLD with GCC is not supported yet. Try compiling with 'use_llvm=yes'.")
+            env.Append(LINKFLAGS=["-fuse-ld=%s" % env["linker"]])
+
+    if env["use_thinlto"]:
+        if not env["use_llvm"] or env["linker"] != "lld":
+            print("ThinLTO is only compatible with LLVM and the LLD linker, use `use_llvm=yes linker=lld`.")
             sys.exit(255)
+        else:
+            env["use_lto"] = True  # ThinLTO implies LTO
 
     if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"] or env["use_msan"]:
         env.extra_suffix += "s"
@@ -192,16 +216,15 @@ def configure(env):
             env.Append(LINKFLAGS=["-fsanitize=memory"])
 
     if env["use_lto"]:
-        if not env["use_llvm"] and env.GetOption("num_jobs") > 1:
+        if env["use_thinlto"]:
+            env.Append(CCFLAGS=["-flto=thin"])
+            env.Append(LINKFLAGS=["-flto=thin"])
+        elif not env["use_llvm"] and env.GetOption("num_jobs") > 1:
             env.Append(CCFLAGS=["-flto"])
             env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))])
         else:
-            if env["use_lld"] and env["use_thinlto"]:
-                env.Append(CCFLAGS=["-flto=thin"])
-                env.Append(LINKFLAGS=["-flto=thin"])
-            else:
-                env.Append(CCFLAGS=["-flto"])
-                env.Append(LINKFLAGS=["-flto"])
+            env.Append(CCFLAGS=["-flto"])
+            env.Append(LINKFLAGS=["-flto"])
 
         if not env["use_llvm"]:
             env["RANLIB"] = "gcc-ranlib"