@@ -133,6 +133,65 @@ load(
133133 "releases" ,
134134)
135135
136+ def _write_zig_wrapper (ctx : AnalysisContext , name : str , zig_artifact : Artifact , subcmd : str ) -> cmd_args :
137+ """Write a zig wrapper script that resolves paths from its own location.
138+
139+ Uses BASH_SOURCE to calculate the script's directory, then constructs
140+ paths relative to that location. This ensures the script works regardless
141+ of the caller's working directory - go_go_wrapper changes to a temporary
142+ directory which breaks scripts using relative paths.
143+
144+ Also expands nested @argsfile references since zig cc doesn't support them.
145+ """
146+ script = ctx .actions .declare_output ("{}.sh" .format (name ))
147+ ctx .actions .write (
148+ script ,
149+ [
150+ "#!/usr/bin/env bash" ,
151+ 'SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"' ,
152+ # Expand nested @argsfile references - zig cc doesn't support them
153+ # Write expanded args to a temp file to handle shell quoting correctly
154+ 'expand_argsfile() {' ,
155+ ' local file="$1"' ,
156+ ' while IFS= read -r line || [[ -n "$line" ]]; do' ,
157+ ' if [[ "$line" == @* ]]; then' ,
158+ ' expand_argsfile "${line:1}"' ,
159+ ' else' ,
160+ ' echo "$line"' ,
161+ ' fi' ,
162+ ' done < "$file"' ,
163+ '}' ,
164+ 'args=()' ,
165+ 'argfile_n=0' ,
166+ 'for arg in "$@"; do' ,
167+ ' if [[ "$arg" == @* ]]; then' ,
168+ ' file="${arg:1}"' ,
169+ ' if [[ -f "$file" ]]; then' ,
170+ ' tmpfile="$BUCK_SCRATCH_PATH/argsfile_$argfile_n"' ,
171+ ' argfile_n=$((argfile_n + 1))' ,
172+ ' expand_argsfile "$file" > "$tmpfile"' ,
173+ ' args+=("@$tmpfile")' ,
174+ ' else' ,
175+ ' args+=("$arg")' ,
176+ ' fi' ,
177+ ' else' ,
178+ ' args+=("$arg")' ,
179+ ' fi' ,
180+ 'done' ,
181+ cmd_args (
182+ 'exec "$SCRIPT_DIR/' ,
183+ cmd_args (zig_artifact , relative_to = (script , 1 )),
184+ '" ' ,
185+ subcmd ,
186+ ' "${args[@]}"' ,
187+ delimiter = "" ,
188+ ),
189+ ],
190+ is_executable = True ,
191+ allow_args = True ,
192+ )
193+ return cmd_args (script , hidden = zig_artifact )
194+
136195ZigReleaseInfo = provider (
137196 # @unsorted-dict-items
138197 fields = {
@@ -326,31 +385,42 @@ def _get_linker_type(os: str) -> LinkerType:
326385def _cxx_zig_toolchain_impl (ctx : AnalysisContext ) -> list [Provider ]:
327386 dist = ctx .attrs .distribution [ZigDistributionInfo ]
328387 zig = ctx .attrs .distribution [RunInfo ]
388+ zig_artifact = ctx .attrs .distribution [DefaultInfo ].default_outputs [0 ]
329389 target = ["-target" , ctx .attrs .target ] if ctx .attrs .target else []
330- zig_cc = cmd_script (
331- actions = ctx .actions ,
332- name = "zig_cc" ,
333- cmd = cmd_args (zig , "cc" ),
334- language = ScriptLanguage ("bat" if dist .os == "windows" else "sh" ),
335- )
336- zig_cxx = cmd_script (
337- actions = ctx .actions ,
338- name = "zig_cxx" ,
339- cmd = cmd_args (zig , "c++" ),
340- language = ScriptLanguage ("bat" if dist .os == "windows" else "sh" ),
341- )
342- zig_ar = cmd_script (
343- actions = ctx .actions ,
344- name = "zig_ar" ,
345- cmd = cmd_args (zig , "ar" ),
346- language = ScriptLanguage ("bat" if dist .os == "windows" else "sh" ),
347- )
348- zig_ranlib = cmd_script (
349- actions = ctx .actions ,
350- name = "zig_ranlib" ,
351- cmd = cmd_args (zig , "ranlib" ),
352- language = ScriptLanguage ("bat" if dist .os == "windows" else "sh" ),
353- )
390+
391+ # On Unix, use BASH_SOURCE-based wrapper scripts that resolve paths
392+ # relative to the script's location. This ensures they work when invoked
393+ # from different working directories (go_go_wrapper changes to a temp dir).
394+ if dist .os == "windows" :
395+ zig_cc = cmd_script (
396+ actions = ctx .actions ,
397+ name = "zig_cc" ,
398+ cmd = cmd_args (zig , "cc" ),
399+ language = ScriptLanguage ("bat" ),
400+ )
401+ zig_cxx = cmd_script (
402+ actions = ctx .actions ,
403+ name = "zig_cxx" ,
404+ cmd = cmd_args (zig , "c++" ),
405+ language = ScriptLanguage ("bat" ),
406+ )
407+ zig_ar = cmd_script (
408+ actions = ctx .actions ,
409+ name = "zig_ar" ,
410+ cmd = cmd_args (zig , "ar" ),
411+ language = ScriptLanguage ("bat" ),
412+ )
413+ zig_ranlib = cmd_script (
414+ actions = ctx .actions ,
415+ name = "zig_ranlib" ,
416+ cmd = cmd_args (zig , "ranlib" ),
417+ language = ScriptLanguage ("bat" ),
418+ )
419+ else :
420+ zig_cc = _write_zig_wrapper (ctx , "zig_cc" , zig_artifact , "cc" )
421+ zig_cxx = _write_zig_wrapper (ctx , "zig_cxx" , zig_artifact , "c++" )
422+ zig_ar = _write_zig_wrapper (ctx , "zig_ar" , zig_artifact , "ar" )
423+ zig_ranlib = _write_zig_wrapper (ctx , "zig_ranlib" , zig_artifact , "ranlib" )
354424 return [ctx .attrs .distribution [DefaultInfo ]] + cxx_toolchain_infos (
355425 internal_tools = ctx .attrs ._cxx_internal_tools [CxxInternalTools ],
356426 platform_name = dist .arch ,
0 commit comments