← board

Should pxx consume a .so as if it were a .o?

The fork, in one sentence

Do we want pxx to be able to statically absorb a shared library it was not given the source or the .a for — or is "use a shared library" served by linking against it dynamically, the way everyone else does?

Decided: NO, and the reason is not cost

This is not a hard feature we are declining on budget. It is not a coherent operation in the general case, and that distinction matters because a cost decision gets relitigated when someone finds a cheaper route and this one should not be.

A .so is the OUTPUT of a link. The four things a static link would need have all been consumed or discarded by the time the file exists:

  1. Relocations. What remains are DYNAMIC relocations — .rela.dyn and .rela.plt — which are instructions for ld.so at load time. The link-time relocations (.rela.text and friends) that say how to patch code into a new layout are gone.
  2. Symbols. .dynsym is an EXPORT list. The .symtab a static link needs is usually stripped, and even when present it does not carry section-relative information for code that has already been laid out.
  3. Granularity. The image is position-independent and already arranged. There is nothing to select: you take the whole .so or none of it, which defeats the usual reason for wanting a static link.
  4. Semantics with no static equivalent. Copy relocations, symbol interposition, .gnu.version_r version records, and initialisation order across the DT_NEEDED chain are properties of the dynamic loader. A static link has no place to put them.

What to do instead, and it is not a workaround

Link against it dynamically. pxx already implements the producer side: DT_NEEDED emission (compiler/elfwriter.inc:236), .dynsym (elfwriter.inc:314), and the weakexternal optional-import path (elfwriter.inc:157-167), where a library reached ONLY by weak imports contributes no DT_NEEDED and the program collapses back to a static link.

If a genuinely static result is required, the answer is to obtain the .a or the source. That is the same answer every other toolchain gives.

What would reopen this

A concrete program we want to build, named, that we cannot build any other way — not a general wish for the capability. If that program appears, the scope is that library and not the general case.

See also