Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link archive to shared library with Bazel

Tags:

c++

bazel

Using Bazel, I'd like to link a position independent static archive directly to a shared library (not to the application using the shared library). Something like:

g++ -shared mylib.cpp archive.a -o libmylib.so
g++ mybin.cpp -lmylib -o mybin

Rationale: RedHat packages libelf as a static archive, that has some otherwise public symbols (e.g: elf_errmsg) marked as hidden: the archive must be linked to the module using it (in this case, the shared library): linking to the application is too late.

I tried:

  • Wrapping the archive in a cc_import rule
  • Adding the rule to the deps of the cc_library: doesn't work, archive gets linked to the app
  • Adding the rule to the srcs of the cc_library: doesn't work, archive gets linked to the app
  • Adding the archive file directly to the linkopts of the cc_library: almost works, but the archive gets linked to both the library and the binaries depending on it.
  • Renaming the archive to .lo or .pic.lo: doesn't work, archive gets linked to the app with -Wl,wholearchive
  • Adding alwayslink = True to the cc_import: doesn't work, archive gets linked to the app with -Wl,wholearchive
like image 506
erenon Avatar asked Oct 20 '25 04:10

erenon


1 Answers

Something like this should work for what you're trying to do:

cc_binary(
    name = "libmylib.so",
    srcs = ["mylib.cpp", "archive.a"],
    linkshared = True,
)

cc_library(
    name = "mylib",
    srcs = ["libmylib.so"],
    hdrs = ["mylib.hpp"],
)
cc_binary(
    name = "mybin",
    srcs = ["mybin.cpp"],
    deps = [":mylib"],
)

You can build a shared library (which is done as cc_binary(linkshared = True); this bit may not seem entirely intuitive) from your source and the library archive.

You can build a cc_library to use as a dependency of your other targets... and use that to build a cc_binary target.

In theory if this was just one time/place thing, you could probably shorten it like this (but it's more of a minimal length example):

cc_binary(
    name = "libmylib.so",
    srcs = ["mylib.cpp", "archive.a"],
    linkshared = True,
)

cc_binary(
    name = "mybin",
    srcs = ["mybin.cpp", "mylib.hpp", ":libmylib.so"],
)
like image 144
Ondrej K. Avatar answered Oct 22 '25 17:10

Ondrej K.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!