Skip to main content

Module thin_build

Module thin_build 

Source
Expand description

Thin-rebuild driver — produce a patch dylib from a single captured rustc invocation by editing as few of its args as possible.

§Design principle: “minimal edit, verbatim everything else”

Whisker does not want to re-derive linker / sysroot / SDK args itself — those are the parts most likely to break across OS versions, NDK upgrades, Xcode releases, glibc CSU layout changes, and so on. Instead we capture cargo+rustc’s full invocation in I4g-4 and replay it here, changing only the handful of args that have to differ for a hot-patch dylib:

  • --crate-type is forced to rlib so rustc emits an object file containing every pub fn’s mangled symbol (cdylib would strip them — see I4g-6 pivot).
  • --emit is forced to obj so we get a single .o we can hand to the linker ourselves.
  • --out-dir is redirected to a session-local cache so the patch artifact doesn’t clobber the original target/ output.

Everything else — target triple, sysroot, link-args, optimisation level, cfg flags, -L search paths, -l link directives — is preserved verbatim. That is the whole point: rustc + cargo already know how to make the linker happy on this OS / SDK combo, and we lean on that.

After rustc emits the .o, [build_link_plan] (X2b) takes the captured linker invocation, drops its object inputs (we have a fresh one), substitutes our .o and -o, and adds -undefined dynamic_lookup (macOS) / --unresolved-symbols=ignore-all (Linux) so unresolved symbols are deferred to the host process at dlopen time. The result is a .so / .dylib that re-exports back into the original binary for everything except the patched function bodies — exactly what subsecond::apply_patch expects.

Structs§

ObjBuildPlan
What build_obj_plan returns — captured rustc args, edited so that running rustc with them produces a single .o containing every pub fn’s mangled symbol.

Functions§

build_obj_plan
Edit a captured rustc invocation so that running it produces an object file containing every pub fn’s mangled symbol — the input to the linker step in [build_link_plan].
library_filename
Platform-specific cdylib filename for the host OS. Matches what rustc itself emits for --crate-type cdylib: macOS → lib<crate>.dylib Linux → lib<crate>.so (Android uses the same convention) Windows → <crate>.dll
library_filename_for_os
Cross-platform variant: produce the cdylib filename for the patch target OS (which may differ from the host). The hot- patch dylib has to match the on-device shared-library naming convention, not the host’s — Android wants lib<crate>.so even when the dev session is on macOS.
object_filename
Object filename rustc emits for --emit=obj --crate-type=rlib: <crate>.o with hyphens converted to underscores. (Notably no lib prefix and no extension other than .o — cdylib’s lib<crate>.dylib rules don’t apply here.)
set_crate_type
Force every --crate-type arg to a single value (new_kind). rustc allows the flag to repeat (one binary can be multiple crate-types in one invocation); for a hot-patch we always want exactly one — cdylib. The fold-and-add behaviour is:
set_emit_obj
Force --emit to exactly one directive: obj=<path>. Strips every existing --emit (separated, =, comma-separated mix) and appends one fresh pair. Same fold-and-add semantics as set_crate_type.
set_out_dir
Redirect rustc’s output directory. Same fold-and-add semantics as set_crate_type: strip every existing form, append one fresh pair. Handles --out-dir <DIR>, --out-dir=<DIR>, and the -o <PATH> short form (rare in cargo invocations but possible — we drop it because --out-dir wins for --crate-type cdylib).