Conversation
Both build scripts run with `set -euo pipefail` and expand `"${TARGETS[@]}"`
(and `"${RUNNER[@]}"` in build_linux.sh) unconditionally, but both arrays are
empty in the default invocation: TARGETS only receives entries from `--target`,
which build_metal.sh documents as optional, and RUNNER only receives entries
from `--conda-env`.
Stock macOS /bin/bash is 3.2 and bash < 4.4 also treats an empty array as
unbound under `set -u`, so `scripts/build_metal.sh` without `--target` always
dies right after a successful configure:
-- Build files have been written to: <build dir>
scripts/build_metal.sh: line 324: TARGETS[@]: unbound variable
Use the ${arr[@]+"${arr[@]}"} form, which expands to nothing when the array is
empty and to the quoted elements otherwise, so the default invocations work
again without changing behaviour when targets or the conda runner are set.
Add scripts/check_build_scripts.sh and run it from mac-build before the configure step. It runs `bash -n` over scripts/*.sh, then drives build_metal.sh and build_linux.sh with stub cmake/xcrun executables and no --target under /bin/bash (3.2 on macOS), and requires both to reach the configure and `cmake --build` invocations instead of dying on `set -u`. Positive control — guards reverted in a scratch copy of the scripts, same harness: build_metal.sh: line 327: TARGETS[@]: unbound variable -> FAIL (exit 1) build_linux.sh: line 455: RUNNER[@]: unbound variable -> FAIL (exit 1) With the guards in place the check reports ok for both scripts, so the regression cannot come back silently on macOS.
Contributor
Author
|
Added the CI check you asked about (as a follow-up commit on this branch):
The point of pinning Positive control (same harness, guards reverted in a scratch copy of the scripts): $ scratch/scripts/check_build_scripts.sh
ok: /bin/bash -n passed for 4 scripts
--- build_metal output (tail) ---
/…/scripts/build_metal.sh: line 327: TARGETS[@]: unbound variable
FAIL: build_metal: … exited non-zero under /bin/bash (3.2.57(1)-release) # exit 1
# with only build_linux.sh reverted:
ok: build_metal completed under bash 3.2.57(1)-release
--- build_linux output (tail) ---
/…/scripts/build_linux.sh: line 455: RUNNER[@]: unbound variable
FAIL: build_linux: … exited non-zero under /bin/bash (3.2.57(1)-release) # exit 1With the fix in place the check prints |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
scripts/build_metal.sh(andscripts/build_linux.sh) run withset -euo pipefailand expand"${TARGETS[@]}"/"${RUNNER[@]}"unconditionally, but both arrays are empty in the default invocation:TARGETSonly receives entries from--target; the script's own usage listsscripts/build_metal.sh(no--target) as an example, and the flag is documented as optional.RUNNERonly receives entries from--conda-env.Stock macOS
/bin/bashis 3.2, and bash < 4.4 also treats an empty array as unbound underset -u. The script therefore always dies right after a successful configure — the build never starts:Changes
Use the
${arr[@]+"${arr[@]}"}form, which expands to nothing when the array is empty and to the quoted elements otherwise. Four lines, no behaviour change when targets or the conda runner are set:scripts/build_metal.sh: theTARGETSloop.scripts/build_linux.sh: theRUNNERcmake invocation, theBUILD_CMDarray, and theTARGETSloop (same mechanism, reachable on bash < 4.4).build_xcframework.shwas checked as well and needs no change — itslipo_inputsarray is only expanded after at least one element is appended, and${#ARCH_LIST[@]}is safe on an empty array in bash 3.2.Verification
macOS 26.5.2, Apple M4,
/bin/bash3.2.57.Before (unfixed, same tree as this PR's base):
After:
Both scripts also pass
/bin/bash -n. For thebuild_linux.shlines (not directly runnable on macOS) I drove the exact expansions through a stub harness on bash 3.2:Elements are preserved individually (the runner element containing a space stays a single argument), so this only removes the empty-array failure.
Notes
I could not find an existing report for this in the issue tracker. If you want it enforced, a
bash -n+ stub-expansion check in CI would catch a regression, but I kept the diff to the four lines since the repo has no shell-test harness wired into the workflows.