Skip to content

fix(linker): say how to fix a missing bridge archive, and document the search - #1022

Open
Guikingone wants to merge 3 commits into
mainfrom
fix/517-bridge-archive-discovery
Open

Guikingone wants to merge 3 commits into
mainfrom
fix/517-bridge-archive-discovery

Conversation

@Guikingone

Copy link
Copy Markdown
Collaborator

Closes #517.

Copying the elephc binary out of its build tree makes every --web/bridge build fail at link time, with nothing to go on:

Linker error: required Elephc bridge `elephc_web` could not be found

The archives are separate files — they have to travel with the compiler. The issue asked for either documentation or an install-layout fallback, and both already half-existed while neither was discoverable: find_archive has always checked the binary's own directory and its sibling lib/, and every bridge has had an ELEPHC_<NAME>_LIB_DIR override, but the only place either was written down was one clause inside the --print-capabilities table row.

The diagnostic

LinkError::MissingBridge now carries the archive, the override variable and the directories actually consulted, so the message names the way out:

Linker error: required Elephc bridge `elephc_web` could not be found
  needs: libelephc_web.a
  looked in:
    /opt/tools/bin
    /opt/tools/lib
    target/debug
    target/release

Set ELEPHC_WEB_LIB_DIR to a directory containing libelephc_web.a, or keep the
bridge archives next to the elephc binary (or in a sibling lib/).
`elephc --print-capabilities` lists every archive this binary can need.

The searched list is not a second copy of the candidate list. find_archive, find_named_archive and the error all read one archive_search_dirs, so a candidate added to discovery cannot go unreported — which also removed the duplicated candidate-building each of those two functions carried.

A LinkOrigin::Bridge item the table does not describe has no archive, override or candidate list, so it renders the bare first line rather than inventing any of the three.

The documentation

A "Where bridge archives are found" section in docs/compiling/linking-and-conditional-compilation.md: the two supported layouts, the five-step resolution order, why it never comes up in a source checkout (the archive is built on demand there), and the message above. The --print-capabilities row now points at it instead of carrying a one-clause summary.

Measured

All three paths, with a debug binary copied out of the tree:

binary alone, nothing beside it the message above
<dir>/bin/elephc + <dir>/lib/libelephc_*.a compiles
ELEPHC_WEB_LIB_DIR etc. pointing at a directory of archives compiles

Two new unit tests: one asserts the message names the archive, the override and every directory archive_search_dirs reports; one pins the bare rendering for a bridge outside the table.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KSAAWPyNBq6dP2b5puN3wr

@github-actions github-actions Bot added area:triage No primary component could be inferred from changed paths. size:s Small pull request. type:fix Corrects broken or incompatible behavior. labels Sep 15, 2026
@greptile-apps

greptile-apps Bot commented Sep 15, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; the previous diagnostic and regression-coverage concerns are fully addressed with no new actionable failures identified.

Summary

The PR makes missing bridge-archive failures actionable and documents the archive resolution model.

  • Extends MissingBridge with the required archive, environment override, and directories actually searched.
  • Distinguishes override failures from ordinary fallback-search failures.
  • Centralizes bridge archive search-directory construction.
  • Documents supported archive layouts and resolution precedence.
  • Adds unit and end-to-end regression coverage for ordinary, override, and unknown-bridge diagnostics.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Bridge archive required] --> B{Override set and non-empty?}
  B -->|Yes| C[Validate archive in override directory]
  C -->|Valid| D[Use override archive]
  C -->|Invalid or absent| E[Report override directory and explain fallback was skipped]
  B -->|No| F[Build ordered archive_search_dirs list]
  F --> G{Archive found?}
  G -->|Yes| H[Use first matching archive]
  G -->|No| I{Source workspace available?}
  I -->|Yes| J[Build bridge archive on demand]
  I -->|No| K[Report archive, override variable, and searched directories]
Loading

Reviews (5) · Last reviewed commit: "test(cli): exercise the override diagnos..."

Comment thread src/linker/bridges.rs
@Guikingone Guikingone self-assigned this Sep 15, 2026
Comment thread src/linker/bridges.rs
@Guikingone
Guikingone force-pushed the fix/517-bridge-archive-discovery branch from 49c987a to 9d372a0 Compare September 16, 2026 21:09
…e search

Closes #517.

Copying the `elephc` binary out of its build tree makes every `--web`/bridge
build fail at link time, with nothing to go on:

    Linker error: required Elephc bridge `elephc_web` could not be found

The archives are separate files; they have to travel with the compiler. The
issue asked for either documentation or an install-layout fallback -- both
already half-existed and neither was discoverable. `find_archive` has always
checked the binary's own directory and its sibling `lib/`, and every bridge has
had an `ELEPHC_<NAME>_LIB_DIR` override, but the only place either was written
down was one clause inside the `--print-capabilities` table row.

## The diagnostic

`LinkError::MissingBridge` now carries the archive, the override variable and the
directories actually consulted, so the message names the way out:

    Linker error: required Elephc bridge `elephc_web` could not be found
      needs: libelephc_web.a
      looked in:
        /opt/tools/bin
        /opt/tools/lib
        target/debug
        target/release

    Set ELEPHC_WEB_LIB_DIR to a directory containing libelephc_web.a, or keep
    the bridge archives next to the elephc binary (or in a sibling lib/).
    `elephc --print-capabilities` lists every archive this binary can need.

The searched list is not a second copy of the candidate list: `find_archive`,
`find_named_archive` and the error all read one `archive_search_dirs`, so a
candidate added to discovery cannot go unreported. That also removed the
duplicated candidate-building `find_archive` and `find_named_archive` each
carried.

A `LinkOrigin::Bridge` item the table does not describe has no archive, override
or candidate list, so it renders the bare first line rather than inventing any of
the three.

## The documentation

A "Where bridge archives are found" section in
docs/compiling/linking-and-conditional-compilation.md: the two supported
layouts, the five-step resolution order, why it never comes up in a source
checkout (the archive is built on demand), and the message above. The
`--print-capabilities` row now points at it.

## Measured

All three paths verified with a debug binary copied out of the tree:

- binary alone, nothing beside it -- the message above
- `<dir>/bin/elephc` + `<dir>/lib/libelephc_*.a` -- compiles
- `ELEPHC_WEB_LIB_DIR` / `ELEPHC_PHAR_LIB_DIR` / `ELEPHC_MAGICIAN_LIB_DIR`
  pointing at a directory of archives -- compiles

Two new unit tests: one asserts the message names the archive, the override and
every directory `archive_search_dirs` reports, and one pins the bare rendering
for a bridge outside the table.

Claude-Session: https://claude.ai/code/session_01KSAAWPyNBq6dP2b5puN3wr
Review follow-up on #517. `ELEPHC_<NAME>_LIB_DIR` REPLACES the search rather
than joining it: `archive_path` returns on a non-empty override before a single
fallback is consulted. The failure still rendered the generic message, so it
listed four directories it had not read and then recommended a location the
override would ignore:

    ELEPHC_WEB_LIB_DIR=/opt/stage/lib elephc --web app.php

    required Elephc bridge `elephc_web` could not be found
      needs: libelephc_web.a
      looked in:
        /opt/tools/bin        <- never read
        /opt/tools/lib        <- never read, and where the archive actually is
        target/debug          <- never read
        target/release        <- never read

    Set ELEPHC_WEB_LIB_DIR to a directory containing libelephc_web.a, or keep
    the bridge archives next to the elephc binary (or in a sibling lib/).

Someone who has already done the recommended thing reads that and stays broken,
because the one fact that would fix it -- the override wins and points somewhere
empty -- is the fact the message omits.

`missing_override_error` records the directory that WAS read and marks it as the
override; `Display` then gives the opposite advice, naming unsetting the variable
as a way out and dropping the suggestion the override would override:

    ELEPHC_WEB_LIB_DIR is set to /opt/stage/lib, which takes priority over every
    other location -- the elephc binary's own directory, a sibling lib/ and the
    build tree were NOT consulted. Put libelephc_web.a in /opt/stage/lib, point
    ELEPHC_WEB_LIB_DIR somewhere that has it, or unset ELEPHC_WEB_LIB_DIR to
    search those locations again.

The same path carried a second misreport: `ELEPHC_MAGICIAN_LIB_DIR` resolves TWO
archives, and the override branch of `magician_curl_archive_path` reported the
plain `libelephc_magician.a` for a missing `libelephc_magician_curl.a` -- sending
someone to look for a file that is present and fine. The validator now takes the
filename it is actually checking.

Measured end to end: the message above is this binary's real output for
`ELEPHC_WEB_LIB_DIR=/tmp/definitely-not-here elephc --web`, and the same build
with the variable unset links.

Claude-Session: https://claude.ai/code/session_01KSAAWPyNBq6dP2b5puN3wr
Review follow-up, and a fair one: the unit tests call `validate_override_archive`
directly, so they pin the MESSAGE and say nothing about which message a user
gets. Routing is the part that decides that, and it could go back to
`validate_archive` with every existing assertion still green.

`test_cli_bridge_override_miss_reports_the_override_not_the_fallbacks` runs the
compiler: `ELEPHC_WEB_LIB_DIR` set to an empty directory, `--web`, and the real
`archive_path`. It asserts the override is named, that the message says the
override stopped the search, that unsetting it is offered, and that NONE of the
fallback directories appear -- then re-runs the same build with the variable
unset and requires it to link, which is what makes that last sentence actionable
rather than decorative.

Verified against the regression it guards: putting the override branch back on
`validate_archive` leaves the unit tests passing and fails this one.

Through the CLI rather than in-process on purpose. The override reaches the
compiler as a CHILD process environment variable, so it cannot race the other
tests sharing this process.

Claude-Session: https://claude.ai/code/session_01KSAAWPyNBq6dP2b5puN3wr
@Guikingone
Guikingone force-pushed the fix/517-bridge-archive-discovery branch from 9d372a0 to 7ca39af Compare September 18, 2026 13:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:triage No primary component could be inferred from changed paths. size:s Small pull request. type:fix Corrects broken or incompatible behavior.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bridge staticlibs (libelephc_web.a etc.) must sit next to the elephc binary or --web link fails

1 participant