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-typeis forced torlibso rustc emits an object file containing everypub fn’s mangled symbol (cdylib would strip them — see I4g-6 pivot).--emitis forced toobjso we get a single.owe can hand to the linker ourselves.--out-diris redirected to a session-local cache so the patch artifact doesn’t clobber the originaltarget/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§
- ObjBuild
Plan - What
build_obj_planreturns — captured rustc args, edited so that runningrustcwith them produces a single.ocontaining everypub 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>.dylibLinux →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>.soeven when the dev session is on macOS. - object_
filename - Object filename rustc emits for
--emit=obj --crate-type=rlib:<crate>.owith hyphens converted to underscores. (Notably nolibprefix and no extension other than.o— cdylib’slib<crate>.dylibrules don’t apply here.) - set_
crate_ type - Force every
--crate-typearg 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
--emitto exactly one directive:obj=<path>. Strips every existing--emit(separated,=, comma-separated mix) and appends one fresh pair. Same fold-and-add semantics asset_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-dirwins for--crate-type cdylib).