1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

SCons: Refactor Linux linker options with linker=<bfd|gold|lld|mold>

The new option is `linker` and lets the user specify the argument to
the`-fuse_ld=` linker flag directly. The supported options are:

- `default`: No change, typically uses GNU ld (bfd) unless the user or
  distro picked a different default `/usr/bin/ld`.
- `bfd`: GNU ld from binutils
- `gold`: GNU gold from binutils
- `lld`: lld from LLVM
- `mold`: mold, an extremely fast modern linker, not (yet) intended for
  use in production but great for development speed. Provided by distro
  `mold` package or needs to be compiled from source and installed to
  `/usr` otherwise.

Removes the `use_lld=yes` option, and make lld actually usable with GCC
too.

Not all the above are compatible or recommend for LTO, we recommend
using GNU ld with GCC LTO, or lld with LLVM ThinLTO.
This commit is contained in:
Rémi Verschelde
2022-07-21 11:35:38 +02:00
parent 2280f85bc5
commit c8479c0d4d
2 changed files with 37 additions and 20 deletions

View File

@@ -31,12 +31,12 @@ jobs:
proj-conv: true proj-conv: true
artifact: true artifact: true
- name: Editor with doubles and GCC sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes, ld.gold) - name: Editor with doubles and GCC sanitizers (target=debug, tools=yes, float=64, tests=yes, use_asan=yes, use_ubsan=yes, linker=gold)
cache-name: linux-editor-double-sanitizers cache-name: linux-editor-double-sanitizers
target: debug target: debug
tools: true tools: true
tests: true tests: true
sconsflags: float=64 use_asan=yes use_ubsan=yes LINKFLAGS="-fuse-ld=gold" sconsflags: float=64 use_asan=yes use_ubsan=yes linker=gold
proj-test: true proj-test: true
# Can be turned off for PRs that intentionally break compat with godot-cpp, # Can be turned off for PRs that intentionally break compat with godot-cpp,
# until both the upstream PR and the matching godot-cpp changes are merged. # until both the upstream PR and the matching godot-cpp changes are merged.
@@ -46,12 +46,12 @@ jobs:
# Skip 2GiB artifact speeding up action. # Skip 2GiB artifact speeding up action.
artifact: false artifact: false
- name: Editor with clang sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, use_lld=yes) - name: Editor with clang sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)
cache-name: linux-editor-llvm-sanitizers cache-name: linux-editor-llvm-sanitizers
target: debug target: debug
tools: true tools: true
tests: true tests: true
sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes use_lld=yes sconsflags: use_asan=yes use_ubsan=yes use_llvm=yes linker=lld
bin: "./bin/godot.linuxbsd.tools.64.llvm.san" bin: "./bin/godot.linuxbsd.tools.64.llvm.san"
build-mono: false build-mono: false
# Skip 2GiB artifact speeding up action. # Skip 2GiB artifact speeding up action.

View File

@@ -1,6 +1,7 @@
import os import os
import platform import platform
import sys import sys
from methods import get_compiler_version, using_gcc
def is_active(): def is_active():
@@ -27,9 +28,9 @@ def get_opts():
from SCons.Variables import BoolVariable, EnumVariable from SCons.Variables import BoolVariable, EnumVariable
return [ return [
EnumVariable("linker", "Linker program", "default", ("default", "bfd", "gold", "lld", "mold")),
BoolVariable("use_llvm", "Use the LLVM compiler", False), BoolVariable("use_llvm", "Use the LLVM compiler", False),
BoolVariable("use_lld", "Use the LLD linker", False), BoolVariable("use_thinlto", "Use ThinLTO (LLVM only, requires linker=lld, implies use_lto=yes)", False),
BoolVariable("use_thinlto", "Use ThinLTO", False),
BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True), BoolVariable("use_static_cpp", "Link libgcc and libstdc++ statically for better portability", True),
BoolVariable("use_coverage", "Test Godot coverage", False), BoolVariable("use_coverage", "Test Godot coverage", False),
BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False), BoolVariable("use_ubsan", "Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)", False),
@@ -111,15 +112,32 @@ def configure(env):
env["CXX"] = "clang++" env["CXX"] = "clang++"
env.extra_suffix = ".llvm" + env.extra_suffix env.extra_suffix = ".llvm" + env.extra_suffix
if env["use_lld"]: if env["linker"] != "default":
if env["use_llvm"]: print("Using linker program: " + env["linker"])
env.Append(LINKFLAGS=["-fuse-ld=lld"]) if env["linker"] == "mold" and using_gcc(env): # GCC < 12.1 doesn't support -fuse-ld=mold.
if env["use_thinlto"]: cc_version = get_compiler_version(env)
# A convenience so you don't need to write use_lto too when using SCons cc_semver = (int(cc_version["major"]), int(cc_version["minor"]))
env["use_lto"] = True 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: 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) sys.exit(255)
else:
env["use_lto"] = True # ThinLTO implies LTO
if env["use_coverage"]: if env["use_coverage"]:
env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"]) env.Append(CCFLAGS=["-ftest-coverage", "-fprofile-arcs"])
@@ -164,16 +182,15 @@ def configure(env):
env.Append(LINKFLAGS=["-fsanitize=memory"]) env.Append(LINKFLAGS=["-fsanitize=memory"])
if env["use_lto"]: 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(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))]) env.Append(LINKFLAGS=["-flto=" + str(env.GetOption("num_jobs"))])
else: else:
if env["use_lld"] and env["use_thinlto"]: env.Append(CCFLAGS=["-flto"])
env.Append(CCFLAGS=["-flto=thin"]) env.Append(LINKFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto=thin"])
else:
env.Append(CCFLAGS=["-flto"])
env.Append(LINKFLAGS=["-flto"])
if not env["use_llvm"]: if not env["use_llvm"]:
env["RANLIB"] = "gcc-ranlib" env["RANLIB"] = "gcc-ranlib"