cmd_script.bzl
1 # prelude/utils/cmd_script.bzl 2 # 3 # Wrap cmd_args as an executable script. 4 # 5 # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6 # PRELUDE ARCHAEOLOGY 7 # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8 # 9 # This wraps a cmd_args into a callable script, useful when you need to pass 10 # an executable + args as a single argument to another tool. 11 # 12 # Example (Rust linker wrapper): 13 # linker_cmd = cmd_args(linker, linker_flags) 14 # wrapper = cmd_script(ctx, "linker", linker_cmd) 15 # rustc_args.add("-Clinker={}".format(wrapper)) 16 # 17 # We only support Unix (sh) since we don't target Windows. 18 # 19 # ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 20 21 def cmd_script( 22 ctx: AnalysisContext, 23 name: str, 24 cmd: cmd_args, 25 quote: str | None = "shell") -> cmd_args: 26 """ 27 Wrap cmd_args in a shell script. 28 29 Args: 30 ctx: analysis context 31 name: script name (without .sh extension) 32 cmd: command to wrap 33 quote: quoting style ("shell" or None) 34 35 Returns: 36 cmd_args pointing to script with original cmd as hidden dep 37 """ 38 cmd_kwargs = {} if quote == None else {"quote": quote} 39 shell_quoted = cmd_args(cmd, **cmd_kwargs) 40 41 wrapper, _ = ctx.actions.write( 42 ctx.actions.declare_output("{}.sh".format(name)), 43 [ 44 "#!/usr/bin/env bash", 45 cmd_args(cmd_args(shell_quoted, delimiter = " \\\n"), format = "{} \"$@\"\n"), 46 ], 47 is_executable = True, 48 allow_args = True, 49 ) 50 51 return cmd_args(wrapper, hidden = cmd)