Skip to content

fix(cmake): determine the fat runtime output object without rev - #412

Open
chrisburr wants to merge 1 commit into
VectorCamp:developfrom
chrisburr:fix/build-wrapper-drop-rev-dependency
Open

fix(cmake): determine the fat runtime output object without rev#412
chrisburr wants to merge 1 commit into
VectorCamp:developfrom
chrisburr:fix/build-wrapper-drop-rev-dependency

Conversation

@chrisburr

Copy link
Copy Markdown

In summary, on machines without the rev utility the fat build fails to link because the -o argument is not extracted correctly. This PR fixes it by avoiding rev and also fixes other potential issues (e.g. paths with spaces).

🤖 Click to see an LLM generated explanation that goes into more detail.

build_wrapper.sh extracted the -o argument by shelling out to rev:

OUT=$(echo "$@" | rev | cut -d ' ' -f 2- | rev | sed 's/.* -o \(.*\.o\).*/\1/')

rev is part of util-linux and is not present in every build environment; minimal container images routinely omit it. Because the pipeline is not run with set -o pipefail and sed still exits 0 when nothing matches, a missing rev does not fail here. Instead the extraction silently yields an empty OUT, nm is then invoked with no operand, the symbol list comes out empty, and objcopy is never run.

The fat runtime components are consequently left with unprefixed symbols and the final link fails with undefined references to avx2_, corei7_, simde_* and friends -- an error that gives no hint that a missing tool at the start of the build was the cause.

Walk the argument list instead. That needs no external tools, is not confused by paths containing spaces (the old echo "$@" flattened the arguments into one string before splitting on spaces), and takes the argument after the last -o rather than pattern-matching on a trailing .o. Fail loudly when no output object can be found, so a future regression surfaces at the point of failure rather than at link time.

Found while packaging 5.4.13 for conda-forge, whose Alma Linux 10 build image does not ship util-linux.

build_wrapper.sh extracted the -o argument by shelling out to `rev`:

    OUT=$(echo "$@" | rev | cut -d ' ' -f 2- | rev | sed 's/.* -o \(.*\.o\).*/\1/')

`rev` is part of util-linux and is not present in every build environment;
minimal container images routinely omit it. Because the pipeline is not run
with `set -o pipefail` and `sed` still exits 0 when nothing matches, a missing
`rev` does not fail here. Instead the extraction silently yields an empty
OUT, `nm` is then invoked with no operand, the symbol list comes out empty,
and `objcopy` is never run.

The fat runtime components are consequently left with unprefixed symbols and
the final link fails with undefined references to avx2_*, corei7_*, simde_*
and friends -- an error that gives no hint that a missing tool at the start
of the build was the cause.

Walk the argument list instead. That needs no external tools, is not confused
by paths containing spaces (the old `echo "$@"` flattened the arguments into
one string before splitting on spaces), and takes the argument after the last
-o rather than pattern-matching on a trailing `.o`. Fail loudly when no output
object can be found, so a future regression surfaces at the point of failure
rather than at link time.

Found while packaging 5.4.13 for conda-forge, whose Alma Linux 10 build image
does not ship util-linux.
@markos

markos commented Sep 1, 2026

Copy link
Copy Markdown

@chrisburr I'd prefer a solution, that uses eg. bash getopts or gnu getopt as the one-liner is really simple and almost self-explanatory. The dependency issue is really a non-issue as it's a tiny utility, however if it fails on paths with spaces, that's something that should be fixed. I might look at this in the next days.

@chrisburr

Copy link
Copy Markdown
Author

The dependency issue is a real one, when building this for conda-forge the build failed for exactly this reason. I'm not sure if we have it packaged to add as a build dep, but regardless, I think rev is the wrong tool for this.

@markos

markos commented Sep 1, 2026

Copy link
Copy Markdown

rev is part of bsdextrautils on Debian, so you could look at the corresponding package. Nevertheless, if getopts/getopt doesn't work, we'll go with your solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants