Skip to content

Commit 999792f

Browse files
committed
[tools] Use mold linker on Linux debug builds
1 parent 6e077b1 commit 999792f

File tree

10 files changed

+60
-2
lines changed

10 files changed

+60
-2
lines changed

BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ install_test(
132132
":install",
133133
_INSTALL_TEST_COMMANDS,
134134
],
135+
env = {"COMPILATION_MODE": "$(COMPILATION_MODE)"},
135136
tags = [
136137
# Running acceptance tests under coverage (kcov) probably burns more CI
137138
# time and flakiness compared to any upside.

setup/ubuntu/source_distribution/packages-jammy-test-only.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
curl
22
kcov
33
libstdc++6-10-dbg
4+
mold
45
python3-dateutil
56
python3-dbg
67
python3-flask

setup/ubuntu/source_distribution/packages-noble-test-only.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
curl
22
libstdc++6-10-dbg
3+
mold
34
python3-dateutil
45
python3-dbg
56
python3-flask

tools/install/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ drake_py_unittest(
5353
# Runs `install_test_helper` unit tests.
5454
drake_py_unittest(
5555
name = "install_test_helper_test",
56+
env = {"COMPILATION_MODE": "$(COMPILATION_MODE)"},
5657
deps = [":install_test_helper"],
5758
)
5859

tools/install/install_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,8 @@ def main():
9797

9898

9999
if __name__ == '__main__':
100+
if install_test_helper.IS_JAMMY_DEBUG:
101+
print("Skipping: ld.mold is too old")
102+
sys.exit(0)
103+
100104
main()

tools/install/install_test_helper.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
import errno
22
import os
3+
import platform
34
import signal
45
import stat
56
import subprocess
67
import sys
78
import time
89

910

11+
# Delete all of this skip logic when jammy support is removed.
12+
def _is_jammy_debug():
13+
is_debug = os.environ.get("COMPILATION_MODE") == "dbg"
14+
is_jammy = (
15+
platform.system() == 'Linux'
16+
and platform.freedesktop_os_release().get('VERSION_CODENAME')
17+
== 'jammy')
18+
return is_jammy and is_debug
19+
20+
21+
IS_JAMMY_DEBUG = _is_jammy_debug()
22+
23+
1024
def _make_read_only(path):
1125
current = stat.S_IMODE(os.lstat(path).st_mode)
1226
os.chmod(path, current & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))

tools/install/test/install_test_helper_test.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,45 @@
11
import os
22
import unittest
33
import install_test_helper
4+
from install_test_helper import IS_JAMMY_DEBUG
45

56

67
class TestInstallTestHelperTest(unittest.TestCase):
8+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
79
def test_get_install_dir(self):
810
self.assertIn("TEST_TMPDIR", os.environ)
911
self.assertIn('installation', install_test_helper.get_install_dir())
1012

13+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
1114
def test_create_temporary_dir(self):
1215
subdirectory_name = "tmp"
1316
tmp_dir = install_test_helper.create_temporary_dir(subdirectory_name)
1417
self.assertIn(subdirectory_name, tmp_dir)
1518
self.assertTrue(os.path.isdir(tmp_dir))
1619

20+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
1721
def test_get_python_executable(self):
1822
self.assertIn("python3", install_test_helper.get_python_executable())
1923

24+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
2025
def test_run_and_kill(self):
2126
python = install_test_helper.get_python_executable()
2227
install_test_helper.run_and_kill([python, "-c",
2328
"import time; time.sleep(5)"], 0.5,
2429
from_install_dir=False)
2530

31+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
2632
def test_check_call(self):
2733
python = install_test_helper.get_python_executable()
2834
install_test_helper.check_call([python, "--help"])
2935

36+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
3037
def test_check_output(self):
3138
python = install_test_helper.get_python_executable()
3239
output = install_test_helper.check_output([python, "--help"])
3340
self.assertIn('PYTHONPATH', output)
3441

42+
@unittest.skipIf(IS_JAMMY_DEBUG, "ld.mold is too old")
3543
def test_read_only(self):
3644
tmp_dir = os.environ['TEST_TMPDIR']
3745
tmp_file = os.path.join(tmp_dir, "test_file")

tools/lint/library_lint_reporter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ def main():
6363
# Filter out false positives. All C++ code is OK to depend on these.
6464
item for item in extra_deps
6565
if not (item.startswith("//tools/cc_toolchain:")
66-
or "@bazel_tools//" in item)
66+
or "@bazel_tools//" in item
67+
or item.startswith("//tools/skylark"))
6768
]
6869
if extra_deps:
6970
print(("ERROR: Extra deps in {}'s drake_cc_package_library.").format(

tools/skylark/BUILD.bazel

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1+
load("@bazel_skylib//lib:selects.bzl", "selects")
12
load("//tools/lint:lint.bzl", "add_lint_tests")
23
load("//tools/skylark:drake_py.bzl", "drake_py_binary", "drake_py_unittest")
34

45
package(default_visibility = ["//visibility:public"])
56

7+
config_setting(
8+
name = "debug",
9+
values = {"compilation_mode": "dbg"},
10+
)
11+
612
config_setting(
713
name = "linux",
814
constraint_values = ["@platforms//os:linux"],
@@ -13,6 +19,14 @@ config_setting(
1319
constraint_values = ["@platforms//os:osx"],
1420
)
1521

22+
selects.config_setting_group(
23+
name = "linux_debug",
24+
match_all = [
25+
":linux",
26+
":debug",
27+
],
28+
)
29+
1630
drake_py_binary(
1731
name = "rewrite_osx_ar_hidden",
1832
srcs = ["rewrite_osx_ar_hidden.py"],

tools/skylark/drake_cc.bzl

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,12 @@ def _platform_copts(rule_copts, rule_gcc_copts, rule_clang_copts, cc_test = 0):
129129
"//conditions:default": [],
130130
})
131131

132+
# The BASE_LINKOPTS are used for all drake_cc_{binary,library,test} rules.
133+
BASE_LINKOPTS = select({
134+
"@drake//tools/skylark:linux_debug": ["-fuse-ld=mold"],
135+
"//conditions:default": [],
136+
})
137+
132138
def _check_library_deps_blacklist(name, deps):
133139
"""Report an error if a library should not use something from deps."""
134140
if not deps:
@@ -596,6 +602,7 @@ def drake_cc_library(
596602
copts = [],
597603
clang_copts = [],
598604
gcc_copts = [],
605+
linkopts = [],
599606
linkstatic = 1,
600607
internal = False,
601608
compile_once_per_scalar = False,
@@ -649,6 +656,7 @@ def drake_cc_library(
649656
should be surrounded with `#if DRAKE_ONCE_PER_SCALAR_PHASE == 0`.
650657
"""
651658
new_copts = _platform_copts(copts, gcc_copts, clang_copts)
659+
new_linkopts = BASE_LINKOPTS + linkopts
652660
new_tags = kwargs.pop("tags", None) or []
653661
if internal:
654662
if install_hdrs_exclude != []:
@@ -690,6 +698,7 @@ def drake_cc_library(
690698
deps = deps + add_deps,
691699
implementation_deps = implementation_deps,
692700
copts = new_copts,
701+
linkopts = new_linkopts,
693702
linkstatic = linkstatic,
694703
declare_installed_headers = declare_installed_headers,
695704
install_hdrs_exclude = install_hdrs_exclude,
@@ -783,6 +792,7 @@ def drake_cc_binary(
783792
defaults using test_rule_args=["-f", "--bar=42"] or test_rule_size="baz".
784793
"""
785794
new_copts = _platform_copts(copts, gcc_copts, clang_copts)
795+
new_linkopts = BASE_LINKOPTS + linkopts
786796
new_srcs, add_deps = _maybe_add_pruned_private_hdrs_dep(
787797
base_name = name,
788798
srcs = srcs,
@@ -801,7 +811,7 @@ def drake_cc_binary(
801811
testonly = testonly,
802812
linkshared = linkshared,
803813
linkstatic = linkstatic,
804-
linkopts = linkopts,
814+
linkopts = new_linkopts,
805815
features = [
806816
# We should deduplicate symbols while linking (for a ~6% reduction
807817
# in disk use), to conserve space in CI; see #18545 for details.
@@ -839,6 +849,7 @@ def drake_cc_test(
839849
copts = [],
840850
gcc_copts = [],
841851
clang_copts = [],
852+
linkopts = [],
842853
allow_network = None,
843854
display = False,
844855
num_threads = None,
@@ -868,6 +879,7 @@ def drake_cc_test(
868879
kwargs = incorporate_display(kwargs, display = display)
869880
kwargs = incorporate_num_threads(kwargs, num_threads = num_threads)
870881
new_copts = _platform_copts(copts, gcc_copts, clang_copts, cc_test = 1)
882+
new_linkopts = BASE_LINKOPTS + linkopts
871883
new_srcs, add_deps = _maybe_add_pruned_private_hdrs_dep(
872884
base_name = name,
873885
srcs = srcs,
@@ -882,6 +894,7 @@ def drake_cc_test(
882894
args = args,
883895
deps = deps + add_deps,
884896
copts = new_copts,
897+
linkopts = new_linkopts,
885898
features = [
886899
# We should deduplicate symbols while linking (for a ~6% reduction
887900
# in disk use), to conserve space in CI; see #18545 for details.

0 commit comments

Comments
 (0)