Skip to content

MacOS: cc_library: Patch "library name" to mangled library name #7415

@aherrmann

Description

@aherrmann

Feature request:

On MacOS, when building a dynamic library from a cc_library target, Bazel should modify the "library name" of the resulting dynamic library to the mangled name relative to @rpath. E.g.

@rpath/libtests_Sindirect-link_Slibcbits.so

instead of the current

bazel-out/darwin-fastbuild/bin/tests/indirect-link/libcbits.so

Feature requests: what underlying problem are you trying to solve with this feature?

When building dynamic cc_library targets with Bazel on MacOS, then Bazel distinguishes between the unmangled library (e.g. bazel-out/darwin-fastbuild/bin/tests/indirect-link/libcbits.so), and the mangled library (e.g. bazel-out/darwin-fastbuild/bin/_solib_darwin/libtests_Sindirect-link_Slibcbits.so), which is a symbolic link to the former.

The "library name" of the library refers to the unmangled library:

$ otool -D bazel-out/darwin-fastbuild/bin/_solib_darwin/libtests_Sindirect-link_Slibcbits.so
bazel-out/darwin-fastbuild/bin/_solib_darwin/libtests_Sindirect-link_Slibcbits.so:
bazel-out/darwin-fastbuild/bin/tests/indirect-link/libcbits.so

If another target links against this library dynamically, then the linker will refer to that "library name" in the load command of the new binary. E.g.

          cmd LC_LOAD_DYLIB
         name bazel-out/darwin-fastbuild/bin/tests/indirect-link/libcbits.so ...

But, it should refer to the mangled library instead, because at runtime only the mangled library will be available. Ideally, using an @rpath relative path. I.e. it should be

          cmd LC_LOAD_DYLIB
         name @rpath/libtests_Sindirect-link_Slibcbits.so ...

At Bazel version 0.21, rules_haskell, for example, patched these load commands in a second step after linking. However, the Haskell compiler (GHC) also generates intermediate dynamic libraries during compilation, which will try to load dependencies based on the unpatched load commands, i.e. the unmangled libraries. rules_haskell works around this by also providing the unmangled libraries as inputs during compilation.

Bazel 0.22 further changed the C++ API. It seems that it is now no longer possible to access the unmangled versions of dynamic library dependencies. This breaks the above workaround for GHC, as we can no longer pass the unmangled libraries as inputs to the compilation step.

An alternative is to fix the problem at the root and change the "library name" of dynamic library dependencies to the mangled name relative to @rpath. E.g.
@rpath/libtests_Sindirect-link_Slibcbits.so. See tweag/rules_haskell@tweag:e08bb91...tweag:5f53b20#diff-16bf3bf49b42434b4d486afcf65678cbR109.
This new workaround in rules_haskell has to create copies of all C library dependencies to be able to modify their "library name", which seems wasteful. Note, that at runtime we can still use the regular mangled library dependencies. The patched versions are only required at link time to generate the correct load commands.

It seems that a better, less wasteful, solution would be to have Bazel generate dynamic libraries with such a "library name" right away.

cc @guibou @mboes
cc @plf who seems to have been working on this

What operating system are you running Bazel on?

MacOS Mojave

What's the output of bazel info release?

release 0.22.0- (@non-git)

If bazel info release returns "development version" or "(@Non-Git)", tell us how you built Bazel.

Using Nix.

Have you found anything relevant by searching the web?

https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3We're not considering working on this, but happy to review a PR. (No assignee)staleIssues or PRs that are stale (no activity for 30 days)team-Rules-CPPIssues for C++ rulestype: feature request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions