Skip to content

Commit 0803767

Browse files
authored
Add a fixed-cpu serial resource size (#1511)
This size's cpu is hard-coded to 1 with no setting to change it, so it can be used to disable parallel builds on broken packages.
1 parent fc7ed21 commit 0803767

2 files changed

Lines changed: 64 additions & 27 deletions

File tree

foreign_cc/private/resource_sets.bzl

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ _SIZES = {
1919
"cpu": 4,
2020
"mem": 500,
2121
},
22+
"serial": {
23+
"cpu": 1,
24+
"fixed_cpu": True,
25+
"mem": 250,
26+
},
2227
"small": {
2328
"cpu": 2,
2429
"mem": 250,
@@ -32,6 +37,9 @@ _SIZES = {
3237
def _bazelrc_line(name, value):
3338
return "common --@rules_foreign_cc//foreign_cc/settings:{}={}".format(name, value)
3439

40+
def _is_fixed(cfg, resource):
41+
return cfg.get("fixed_{}".format(resource), False)
42+
3543
def _setting(size, resource, mode):
3644
if size == _DEFAULT_SIZE:
3745
short_name = _DEFAULT_SIZE
@@ -47,7 +55,12 @@ def _setting(size, resource, mode):
4755

4856
def create_settings():
4957
"""create the settings that configure these functions."""
50-
settings = {"size_default": _DEFAULT_SIZE}
58+
settings = {
59+
"size_default": {
60+
"sort_key": (0, 0, 0, ""),
61+
"value": _DEFAULT_SIZE,
62+
},
63+
}
5164
string_flag(
5265
name = "size_default",
5366
build_setting_default = _DEFAULT_SIZE,
@@ -59,33 +72,40 @@ def create_settings():
5972
if not cfg:
6073
fail("invalid size cfg", size)
6174

62-
# keep this in sync with the docs and the above helper!
63-
cpu_name = "size_{}_cpu".format(size)
64-
cpu_default = _SIZES[size]["cpu"]
65-
int_flag(
66-
name = cpu_name,
67-
build_setting_default = cpu_default,
68-
visibility = ["//visibility:public"],
69-
)
70-
settings[cpu_name] = cpu_default
71-
72-
mem_name = "size_{}_mem".format(size)
73-
mem_default = _SIZES[size]["mem"]
74-
int_flag(
75-
name = mem_name,
76-
build_setting_default = mem_default,
77-
visibility = ["//visibility:public"],
78-
)
79-
settings[mem_name] = mem_default
75+
for resource in ["cpu", "mem"]:
76+
if _is_fixed(cfg, resource):
77+
continue
78+
79+
name = "size_{}_{}".format(size, resource)
80+
default = cfg[resource]
81+
int_flag(
82+
name = name,
83+
build_setting_default = default,
84+
visibility = ["//visibility:public"],
85+
)
86+
87+
# Keep the generated bazelrc grouped by descending size, with
88+
# fixed-resource variants after non-fixed ones when values tie.
89+
settings[name] = {
90+
"sort_key": (
91+
1,
92+
-cfg["cpu"],
93+
-cfg["mem"],
94+
1 if cfg.get("fixed_cpu", False) or cfg.get("fixed_mem", False) else 0,
95+
size,
96+
0 if resource == "cpu" else 1,
97+
),
98+
"value": default,
99+
}
80100

81101
expand_template(
82102
name = "settings_script",
83103
out = "settings.sh",
84104
template = Label(":settings.sh.in"),
85105
substitutions = {
86106
"{{SETTINGS_BAZELRC_LINES}}": "\n".join([
87-
_bazelrc_line(name, settings[name])
88-
for name in sorted(settings.keys())
107+
_bazelrc_line(name, settings[name]["value"])
108+
for name in sorted(settings.keys(), key = lambda name: settings[name]["sort_key"])
89109
]),
90110
},
91111
)
@@ -108,21 +128,26 @@ Set the approximate size of this build. This does two things:
108128
requested parallelization; examples are CMAKE_BUILD_PARALLEL_LEVEL for cmake
109129
or MAKEFLAGS for autotools.
110130
2. Sets the resource_set attribute on the action to tell bazel how many cores
111-
are being used, so it schedules appropriately. The sizes map to labels,
112-
which can be used to override the meaning of the sizes. See
113-
@rules_foreign_cc//foreign_cc/settings:size_{size}_{cpu|mem}.
131+
are being used, so it schedules appropriately.
114132
133+
The sizes map to labels, which can be used to override the meaning of the
134+
sizes. See @rules_foreign_cc//foreign_cc/settings:size_{size}_{cpu|mem}.
115135
Running `bazel run @rules_foreign_cc//foreign_cc/settings` will print out all
116136
the settings in bazelrc format for easy customization.
137+
138+
The `serial` size is special: it sets cpu=1, and provides no override for cpu
139+
(just mem), so `serial` can be used for packages that are known-broken for
140+
parallelization.
117141
""",
118142
),
119143
} | {
120144
_setting(size = size, resource = resource, mode = "key"): attr.label(
121145
default = _setting(size, resource, mode = "label"),
122146
providers = [BuildSettingInfo],
123147
)
124-
for size in _SIZES.keys()
148+
for size, cfg in _SIZES.items()
125149
for resource in ["cpu", "mem"]
150+
if not _is_fixed(cfg, resource)
126151
} | {
127152
_setting(size = _DEFAULT_SIZE, resource = None, mode = "key"): attr.label(
128153
default = _setting(size = _DEFAULT_SIZE, resource = None, mode = "label"),
@@ -159,8 +184,9 @@ def get_resource_set(attr):
159184
if size == _DEFAULT_SIZE:
160185
return None, 0, 0
161186

162-
cpu_value = _get_size_config(attr, size, "cpu")
163-
mem_value = _get_size_config(attr, size, "mem")
187+
cfg = _SIZES[size]
188+
cpu_value = cfg["cpu"] if _is_fixed(cfg, "cpu") else _get_size_config(attr, size, "cpu")
189+
mem_value = cfg["mem"] if _is_fixed(cfg, "mem") else _get_size_config(attr, size, "mem")
164190

165191
if cpu_value < 0:
166192
fail("cpu must be >= 0")

test/env_test/BUILD.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ env_test_make(
4141
},
4242
)
4343

44+
env_test_make(
45+
name = "make_serial",
46+
check_makevars = STANDARD_VARS | {
47+
"GNUMAKEFLAGS": "",
48+
"MAKEFLAGS": " -j1 -- PREFIX={{INSTALLDIR}}",
49+
},
50+
make_attrs = {
51+
"resource_size": "serial",
52+
},
53+
)
54+
4455
env_test_ninja(
4556
name = "ninja_default",
4657
check_shellvars = STANDARD_VARS | {

0 commit comments

Comments
 (0)