Skip to content

Commit a25e960

Browse files
[bazel] Enable windows builds?
1 parent 6a57d79 commit a25e960

File tree

5 files changed

+655
-63
lines changed

5 files changed

+655
-63
lines changed

.bazelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ common --grpc_keepalive_time=30s
3737
# This limits both in-flight executions and concurrent downloads. Even with high number
3838
# of jobs execution will still be limited by CPU cores, so this just pays a bit of
3939
# memory in exchange for higher download concurrency.
40-
common --jobs=30
40+
common --jobs=100
4141

4242
common:remote --extra_execution_platforms=//:rbe
4343
common:remote --remote_executor=grpcs://remote.buildbuddy.io

.github/workflows/bazel.yml

Lines changed: 231 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ jobs:
3636
target: aarch64-unknown-linux-musl
3737
- os: ubuntu-24.04
3838
target: x86_64-unknown-linux-musl
39-
# TODO: Enable Windows once we fix the toolchain issues there.
40-
#- os: windows-latest
41-
# target: x86_64-pc-windows-gnullvm
39+
40+
# Windows
41+
- os: windows-latest
42+
target: x86_64-pc-windows-gnullvm
4243
runs-on: ${{ matrix.os }}
4344

4445
# Configure a human readable name for each job
@@ -97,6 +98,233 @@ jobs:
9798
# Use a very short path to reduce argv/path length issues.
9899
"BAZEL_STARTUP_ARGS=--output_user_root=C:\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
99100
101+
- name: Dump rustc args for proc-macro crates (Windows)
102+
if: runner.os == 'Windows'
103+
shell: bash
104+
run: |
105+
set -euo pipefail
106+
TMP_DIR="${RUNNER_TEMP:-/tmp}"
107+
EXEC_ROOT="$(bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc info execution_root)"
108+
export EXEC_ROOT
109+
echo "EXEC_ROOT=$EXEC_ROOT"
110+
echo "OUTPUT_PATH=$(bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc info output_path)"
111+
echo "BAZEL_BIN=$(bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc info bazel-bin)"
112+
# Build a few known-problem crates (ignore failures) so any copy actions run.
113+
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc \
114+
build \
115+
--remote_download_outputs=all \
116+
@@rules_rs++crate+crates__dtor-0.1.0//:dtor \
117+
@@rules_rs++crate+crates__thiserror-1.0.69//:thiserror \
118+
@@rules_rs++crate+crates__tokio-1.48.0//:tokio || true
119+
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc aquery \
120+
--host_platform=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
121+
--platforms=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
122+
--output=textproto \
123+
'mnemonic("Rustc", @@rules_rs++crate+crates__dtor-0.1.0//:dtor)' > "$TMP_DIR/aquery_dtor.txt"
124+
grep -E 'dtor_proc_macro|transitive_crates|--extern=' "$TMP_DIR/aquery_dtor.txt" || true
125+
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc aquery \
126+
--host_platform=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
127+
--platforms=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
128+
--output=textproto \
129+
'mnemonic("Rustc", @@rules_rs++crate+crates__thiserror-1.0.69//:thiserror)' > "$TMP_DIR/aquery_thiserror.txt"
130+
grep -E 'thiserror_impl|transitive_crates|--extern=' "$TMP_DIR/aquery_thiserror.txt" || true
131+
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc aquery \
132+
--host_platform=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
133+
--platforms=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
134+
--output=textproto \
135+
'mnemonic("Rustc", @@rules_rs++crate+crates__tokio-1.48.0//:tokio)' > "$TMP_DIR/aquery_tokio.txt"
136+
grep -E 'tokio_macros|transitive_crates|--extern=' "$TMP_DIR/aquery_tokio.txt" || true
137+
python - <<'PY'
138+
import os
139+
import re
140+
exec_root = os.environ.get("EXEC_ROOT", "")
141+
def resolve(path):
142+
if exec_root and not os.path.isabs(path):
143+
return os.path.join(exec_root, path)
144+
return path
145+
def check(path):
146+
resolved = resolve(path)
147+
exists = os.path.exists(resolved)
148+
print(f"{path} -> {resolved} {'EXISTS' if exists else 'MISSING'}")
149+
if os.path.isdir(resolved):
150+
entries = sorted(os.listdir(resolved))
151+
print(f"{resolved} entries: {entries[:10]}")
152+
def scan(label, filename):
153+
text = open(filename, "r", encoding="utf-8").read()
154+
print(f"== {label} ==")
155+
for match in re.findall(r'arguments: "--extern=[^=]+=([^"]+)"', text):
156+
check(match)
157+
for match in re.findall(r'arguments: "-Ldependency=([^"]+)"', text):
158+
check(match)
159+
tmp_dir = os.environ.get("RUNNER_TEMP", "/tmp")
160+
scan("dtor", os.path.join(tmp_dir, "aquery_dtor.txt"))
161+
scan("thiserror", os.path.join(tmp_dir, "aquery_thiserror.txt"))
162+
scan("tokio", os.path.join(tmp_dir, "aquery_tokio.txt"))
163+
PY
164+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-fastbuild/bin/external/rules_rs++crate+crates__dtor-0.1.0" || true
165+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-fastbuild/bin/external/rules_rs++crate+crates__dtor-0.1.0/dtor_transitive_crates" || true
166+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-fastbuild/bin/external/rules_rs++crate+crates__thiserror-1.0.69" || true
167+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-fastbuild/bin/external/rules_rs++crate+crates__thiserror-1.0.69/thiserror_transitive_crates" || true
168+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-fastbuild/bin/external/rules_rs++crate+crates__tokio-1.48.0" || true
169+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-fastbuild/bin/external/rules_rs++crate+crates__tokio-1.48.0/tokio_transitive_crates" || true
170+
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc \
171+
aquery \
172+
--host_platform=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
173+
--platforms=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
174+
--output=textproto \
175+
'mnemonic("CopyToDirectory", @@rules_rs++crate+crates__dtor-0.1.0//:dtor)' \
176+
> "$TMP_DIR/aquery_copy_dtor.txt" || true
177+
python - <<'PY'
178+
import os
179+
import re
180+
path = os.path.join(os.environ.get("RUNNER_TEMP", "/tmp"), "aquery_copy_dtor.txt")
181+
if not os.path.exists(path):
182+
print("aquery_copy_dtor.txt missing")
183+
raise SystemExit(0)
184+
text = open(path, "r", encoding="utf-8").read().splitlines()
185+
actions = []
186+
artifacts = {}
187+
current_action = None
188+
for line in text:
189+
if line.strip().startswith("action "):
190+
if current_action:
191+
actions.append(current_action)
192+
current_action = {"inputs": [], "outputs": [], "mnemonic": None}
193+
if "mnemonic:" in line and current_action is not None:
194+
m = re.search(r'mnemonic: "([^"]+)"', line)
195+
if m:
196+
current_action["mnemonic"] = m.group(1)
197+
if "input_dep_set_ids:" in line and current_action is not None:
198+
current_action["inputs"].append(int(line.split(":")[1].strip()))
199+
if "output_ids:" in line and current_action is not None:
200+
current_action["outputs"].append(int(line.split(":")[1].strip()))
201+
if line.strip().startswith("artifact {"):
202+
pass
203+
if current_action:
204+
actions.append(current_action)
205+
for i, line in enumerate(text):
206+
if line.strip().startswith("artifact {"):
207+
path_val = None
208+
id_val = None
209+
j = i + 1
210+
while j < len(text) and "}" not in text[j]:
211+
if "id:" in text[j]:
212+
id_val = int(text[j].split(":")[1].strip())
213+
if "path:" in text[j]:
214+
path_val = text[j].split("path:")[1].strip().strip('"')
215+
j += 1
216+
if id_val is not None and path_val is not None:
217+
artifacts[id_val] = path_val
218+
for action in actions:
219+
if action.get("mnemonic") != "CopyToDirectory":
220+
continue
221+
print("== CopyToDirectory action ==")
222+
print("inputs:")
223+
for dep in action["inputs"]:
224+
print(f" dep_set_id: {dep}")
225+
print("outputs:")
226+
for out_id in action["outputs"]:
227+
print(f" output_id: {out_id} path={artifacts.get(out_id)}")
228+
print("== artifacts (filtered) ==")
229+
for id_val, path_val in artifacts.items():
230+
if "dtor_transitive_crates" in path_val or "dtor_proc_macro" in path_val:
231+
print(f"{id_val}: {path_val}")
232+
PY
233+
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc \
234+
aquery \
235+
--host_platform=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
236+
--platforms=@toolchains_llvm_bootstrapped//platforms:windows_amd64 \
237+
--output=textproto \
238+
'mnemonic("Rustc", @@rules_rs++crate+crates__tokio-1.48.0//:tokio)' \
239+
> "$TMP_DIR/aquery_tokio_rustc.txt" || true
240+
grep -E 'action|mnemonic|tools_dep_set_ids|tool|tokio_macros' "$TMP_DIR/aquery_tokio_rustc.txt" || true
241+
python - <<'PY'
242+
import os
243+
import re
244+
path = os.path.join(os.environ.get("RUNNER_TEMP", "/tmp"), "aquery_tokio_rustc.txt")
245+
if not os.path.exists(path):
246+
print("aquery_tokio_rustc.txt missing")
247+
raise SystemExit(0)
248+
text = open(path, "r", encoding="utf-8").read().splitlines()
249+
artifacts = {}
250+
dep_sets = {}
251+
action = None
252+
in_action = False
253+
in_dep_set = False
254+
current_dep_set = None
255+
for line in text:
256+
stripped = line.strip()
257+
if stripped.startswith("actions {"):
258+
in_action = True
259+
action = {"mnemonic": None, "tool_dep_sets": []}
260+
if in_action and "mnemonic:" in line:
261+
m = re.search(r'mnemonic: "([^"]+)"', line)
262+
if m:
263+
action["mnemonic"] = m.group(1)
264+
if in_action and "tools_dep_set_ids:" in line:
265+
action["tool_dep_sets"].append(int(line.split(":")[1].strip()))
266+
if in_action and stripped == "}":
267+
if action and action.get("mnemonic") == "Rustc":
268+
break
269+
in_action = False
270+
if stripped.startswith("dep_set_of_files {"):
271+
in_dep_set = True
272+
current_dep_set = {"direct_artifact_ids": [], "transitive_dep_set_ids": [], "id": None}
273+
if in_dep_set and "id:" in line and current_dep_set is not None:
274+
current_dep_set["id"] = int(line.split(":")[1].strip())
275+
if in_dep_set and "direct_artifact_ids:" in line and current_dep_set is not None:
276+
current_dep_set["direct_artifact_ids"].append(int(line.split(":")[1].strip()))
277+
if in_dep_set and "transitive_dep_set_ids:" in line and current_dep_set is not None:
278+
current_dep_set["transitive_dep_set_ids"].append(int(line.split(":")[1].strip()))
279+
if in_dep_set and stripped == "}":
280+
if current_dep_set and current_dep_set["id"] is not None:
281+
dep_sets[current_dep_set["id"]] = current_dep_set
282+
in_dep_set = False
283+
current_dep_set = None
284+
for i, line in enumerate(text):
285+
if line.strip().startswith("artifact {"):
286+
path_val = None
287+
id_val = None
288+
j = i + 1
289+
while j < len(text) and "}" not in text[j]:
290+
if "id:" in text[j]:
291+
id_val = int(text[j].split(":")[1].strip())
292+
if "path:" in text[j]:
293+
path_val = text[j].split("path:")[1].strip().strip('"')
294+
j += 1
295+
if id_val is not None and path_val is not None:
296+
artifacts[id_val] = path_val
297+
print("== tokio Rustc tools dep sets ==")
298+
if not action:
299+
print("Rustc action not found")
300+
raise SystemExit(0)
301+
print(action["tool_dep_sets"])
302+
def expand_dep_set(dep_set_id, seen=None):
303+
if seen is None:
304+
seen = set()
305+
if dep_set_id in seen:
306+
return []
307+
seen.add(dep_set_id)
308+
dep = dep_sets.get(dep_set_id, {})
309+
result = list(dep.get("direct_artifact_ids", []))
310+
for trans_id in dep.get("transitive_dep_set_ids", []):
311+
result.extend(expand_dep_set(trans_id, seen))
312+
return result
313+
tool_artifact_ids = []
314+
for dep_set_id in action["tool_dep_sets"]:
315+
tool_artifact_ids.extend(expand_dep_set(dep_set_id))
316+
print("== tokio tool artifacts (filtered) ==")
317+
for art_id in tool_artifact_ids:
318+
path_val = artifacts.get(art_id)
319+
if not path_val:
320+
continue
321+
if "tokio_macros" in path_val or "dtor_proc_macro" in path_val or "thiserror_impl" in path_val:
322+
print(f"{art_id}: {path_val}")
323+
PY
324+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-opt-exec/bin/external/rules_rs++crate+crates__tokio-macros-2.6.0" || true
325+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-opt-exec/bin/external/rules_rs++crate+crates__dtor-proc-macro-0.0.6" || true
326+
ls -la "$EXEC_ROOT/bazel-out/windows_amd64-opt-exec/bin/external/rules_rs++crate+crates__thiserror-impl-1.0.69" || true
327+
100328
- name: bazel test //...
101329
env:
102330
BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}

MODULE.bazel

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,9 @@ bazel_dep(name = "platforms", version = "1.0.0")
22
bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.3.1")
33
archive_override(
44
module_name = "toolchains_llvm_bootstrapped",
5-
integrity = "sha256-9ks21bgEqbQWmwUIvqeLA64+Jk6o4ZVjC8KxjVa2Vw8=",
6-
strip_prefix = "toolchains_llvm_bootstrapped-e3775e66a7b6d287c705ca0cd24497ef4a77c503",
7-
urls = ["https://github.com/cerisier/toolchains_llvm_bootstrapped/archive/e3775e66a7b6d287c705ca0cd24497ef4a77c503/master.tar.gz"],
8-
patch_strip = 1,
9-
patches = [
10-
"//patches:llvm_toolchain_archive_params.patch",
11-
],
5+
integrity = "sha256-4/2h4tYSUSptxFVI9G50yJxWGOwHSeTeOGBlaLQBV8g=",
6+
strip_prefix = "toolchains_llvm_bootstrapped-d20baf67e04d8e2887e3779022890d1dc5e6b948",
7+
urls = ["https://github.com/cerisier/toolchains_llvm_bootstrapped/archive/d20baf67e04d8e2887e3779022890d1dc5e6b948/master.tar.gz"],
128
)
139

1410
osx = use_extension("@toolchains_llvm_bootstrapped//toolchain/extension:osx.bzl", "osx")
@@ -41,6 +37,7 @@ single_version_override(
4137
"//patches:rules_rust.patch",
4238
"//patches:rules_rust_windows_gnu.patch",
4339
"//patches:rules_rust_musl.patch",
40+
"//patches:rules_rust_direct_deps.patch",
4441
],
4542
)
4643

patches/llvm_toolchain_archive_params.patch

Lines changed: 0 additions & 52 deletions
This file was deleted.

0 commit comments

Comments
 (0)