comparison gui_ze/gui_ze.bzl @ 173:827c6ac504cd hg-web

Merged in default here.
author MrJuneJune <me@mrjunejune.com>
date Mon, 19 Jan 2026 18:59:10 -0800
parents f3084bca7317
children 71ad34a8bc9a 8c74204fd362
comparison
equal deleted inserted replaced
151:c033667da5f9 173:827c6ac504cd
1 def _wasm_binary_impl(ctx):
2 """
3 Compile C source to WASM using clang --target=wasm32.
4 No libc - suitable for standalone WASM modules.
5
6 Requires LLVM with wasm32 support (e.g., Homebrew LLVM on macOS).
7 """
8 src = ctx.file.src
9 out = ctx.actions.declare_file(ctx.label.name + ".wasm")
10
11 # Shell script to find clang with wasm support and set PATH for wasm-ld
12 setup_cmd = """
13 export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH"
14 if [ -x /opt/homebrew/opt/llvm/bin/clang ]; then
15 CLANG=/opt/homebrew/opt/llvm/bin/clang
16 elif [ -x /usr/local/opt/llvm/bin/clang ]; then
17 CLANG=/usr/local/opt/llvm/bin/clang
18 else
19 CLANG=clang
20 fi
21 """
22
23 # Build clang command
24 cmd_parts = [
25 setup_cmd,
26 "$CLANG",
27 "--target=wasm32-unknown-unknown",
28 "-O2",
29 "-Wl,--no-entry",
30 "-Wl,--export-dynamic",
31 ]
32
33 # Add exported functions
34 for fn in ctx.attr.exports:
35 cmd_parts.append("-Wl,--export=" + fn)
36
37 cmd_parts.append("-o")
38 cmd_parts.append(out.path)
39 cmd_parts.append(src.path)
40
41 ctx.actions.run_shell(
42 inputs = [src],
43 outputs = [out],
44 command = " ".join(cmd_parts),
45 progress_message = "Compiling {} to WASM".format(src.basename),
46 execution_requirements = {"no-sandbox": "1"},
47 )
48
49 return [DefaultInfo(files = depset([out]))]
50
51 wasm_binary = rule(
52 implementation = _wasm_binary_impl,
53 attrs = {
54 "src": attr.label(
55 allow_single_file = [".c"],
56 mandatory = True,
57 doc = "The C source file to compile",
58 ),
59 "exports": attr.string_list(
60 default = [],
61 doc = "List of function names to export (without leading underscore)",
62 ),
63 },
64 )
65
1 def _foo_impl(ctx): 66 def _foo_impl(ctx):
2 out = ctx.actions.declare_file(ctx.label.name) 67 out = ctx.actions.declare_file(ctx.label.name)
3 ctx.actions.write( 68 ctx.actions.write(
4 output = out, 69 output = out,
5 content = "Hello!\n", 70 content = "Hello!\n",
134 ), 199 ),
135 "data": attr.label_list(allow_files=True), 200 "data": attr.label_list(allow_files=True),
136 "src_folder": attr.string(), 201 "src_folder": attr.string(),
137 }, 202 },
138 ) 203 )
204
205 def _bun_run_impl(ctx):
206 actual_exe = ctx.actions.declare_file(ctx.label.name)
207
208 # 1. Get the workspace name (crucial for runfiles paths)
209 workspace_name = ctx.workspace_name
210
211 # 2. Define the paths relative to the runfiles root
212 bun_path = ctx.executable._bun.short_path
213 src_path = ctx.file.src.short_path
214
215 # 3. Create the launcher script
216 # We use a template to handle the environment and pathing
217 script_content = """#!/bin/bash
218 # Find the runfiles directory
219 if [[ -z "$RUNFILES_DIR" ]]; then
220 if [[ -d "$0.runfiles" ]]; then
221 RUNFILES_DIR="$0.runfiles"
222 fi
223 fi
224
225 # Navigate to the workspace root inside runfiles
226 cd "$RUNFILES_DIR/{workspace}"
227 pwd
228 # Execute bun with the src file and any extra arguments
229 exec "./{bun_bin}" run "./{src_file}" "$@"
230 """.format(
231 workspace = workspace_name,
232 bun_bin = bun_path,
233 src_file = src_path
234 )
235
236 ctx.actions.write(
237 output = actual_exe,
238 content = script_content,
239 is_executable = True,
240 )
241
242 return [
243 DefaultInfo(
244 executable = actual_exe,
245 runfiles = ctx.runfiles(
246 files = [ctx.file.src] + ctx.files.data + ctx.files._bun_files
247 ).merge(ctx.attr._bun[DefaultInfo].default_runfiles),
248 ),
249 ]
250
251 # TODO: Fix the rules so that it can do relative import.
252 bun_run = rule(
253 implementation = _bun_run_impl,
254 executable = True,
255 attrs = {
256 "src": attr.label(allow_single_file = True, mandatory = True),
257 "data": attr.label_list(allow_files = True),
258 "_bun": attr.label(
259 default = Label("//third_party/bun:bun"),
260 executable = True,
261 cfg = "exec"
262 ),
263 "_bun_files": attr.label(default = Label("//third_party/bun:bun_files")),
264 },
265 )
266
139 267
140 def _move_files_into_dir_impl(ctx): 268 def _move_files_into_dir_impl(ctx):
141 srcs = ctx.files.srcs 269 srcs = ctx.files.srcs
142 outs = [] 270 outs = []
143 for src in srcs: 271 for src in srcs:
313 Generates: 441 Generates:
314 {name}_app: The .app bundle 442 {name}_app: The .app bundle
315 {name}_signed_app: The signed .app bundle 443 {name}_signed_app: The signed .app bundle
316 {name}_dmg: The final DMG file 444 {name}_dmg: The final DMG file
317 """ 445 """
446 macos_constraint = ["@platforms//os:macos"]
447
318 # 1. Build the .app bundle 448 # 1. Build the .app bundle
319 _macos_app( 449 _macos_app(
320 name = name + "_app", 450 name = name + "_app",
321 binary = binary, 451 binary = binary,
322 app_name = name, 452 app_name = name,
323 bundle_id = bundle_id, 453 bundle_id = bundle_id,
454 target_compatible_with = macos_constraint,
324 ) 455 )
325 456
326 # 2. Sign the .app 457 # 2. Sign the .app
327 _macos_signed_app( 458 _macos_signed_app(
328 name = name + "_signed_app", 459 name = name + "_signed_app",
329 app = ":" + name + "_app", 460 app = ":" + name + "_app",
330 app_name = name, 461 app_name = name,
462 target_compatible_with = macos_constraint,
331 ) 463 )
332 464
333 # 3. Create the DMG 465 # 3. Create the DMG
334 native.genrule( 466 native.genrule(
335 name = name + "_dmg", 467 name = name + "_dmg",
345 -srcfolder "$$SIGNEDDIR" \ 477 -srcfolder "$$SIGNEDDIR" \
346 -ov -format UDZO "$@" 478 -ov -format UDZO "$@"
347 """.format(name = name), 479 """.format(name = name),
348 local = 1, # Disable sandboxing for hdiutil 480 local = 1, # Disable sandboxing for hdiutil
349 tags = ["no-sandbox"], 481 tags = ["no-sandbox"],
350 ) 482 target_compatible_with = macos_constraint,
483 )