Mercurial
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 ) |