Skip to content

runtime.library_dirs also lands on the link line, where it can shadow another package's library #304

Description

@Sunrisepeak

Summary

A package's runtime.library_dirs is also emitted as -L on the link line. The name
says runtime, and the field exists to make dlopen work, but a directory listed there
participates in symbol resolution at build time too — where it can shadow another
package's library and break the link.

Not asking for a behaviour change; the current semantics may well be intended. Asking for
it to be documented, because the failure is remote from its cause and the workaround is
non-obvious.

Where it came up

compat.vulkan-runtime (mcpp-index) is a symlink farm of host Vulkan ICD libraries, in
the shape compat.glx-runtime already uses for OpenGL: an mcpp binary runs under mcpp's
own glibc, so a bare-soname dlopen never searches the host's library path, and the
loader finds every ICD manifest and then fails to open a single driver.

The farm has to carry the ICDs' transitive dependencies, and some of those — libxcb, zlib
— are also packaged in the index. Harvesting the host's libxcb.so (the unversioned
development symlink) put it on -L ahead of compat.xcb, and the link failed:

ld: …/vulkan_runtime/lib/libxcb.so: undefined reference to `XauDisposeAuth'
ld: …/vulkan_runtime/lib/libxcb.so: undefined reference to `XauGetBestAuthByAddr'
ld: …/vulkan_runtime/lib/libxcb.so: undefined reference to `XdmcpWrap'

Nothing in that message points at runtime.library_dirs.

Reproduction

  1. A package declaring runtime = { library_dirs = { "<dir>" } }, where <dir> contains
    an unversioned libfoo.so for some foo the index also provides.
  2. A consumer that links -lfoo through the index package.
  3. mcpp build → the host copy wins and the link fails.

Confirmed on 0.0.109 by inspecting the generated build.ninja: the directory appears as
a plain -L… entry.

Workaround, which is arguably the right spelling anyway

Harvest only versioned sonames (lib*.so.*), never the bare .so. Versioned names
are invisible to the linker — it resolves -lfoo through libfoo.so/libfoo.a — and are
exactly what dlopen asks for. compat.glx-runtime never hit this because the GL family
it harvests is not otherwise linked from the index, so the collision never arose.

Suggested resolution

Either of these would have saved the debugging:

  • Document that runtime.library_dirs contributes to the link search path, with the
    "versioned sonames only" guidance for symlink-farm packages; or
  • Keep it out of the link line, if runtime-only was the intent.

Happy to send a docs patch if the first is the preferred direction.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions