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:
cc_import
ruledeps
of the cc_library
: doesn't work, archive gets linked to the appsrcs
of the cc_library
: doesn't work, archive gets linked to the applinkopts
of the cc_library
: almost works, but the archive gets linked to both the library and the binaries depending on it..lo
or .pic.lo
: doesn't work, archive gets linked to the app with -Wl,wholearchive
alwayslink = True
to the cc_import
: doesn't work, archive gets linked to the app with -Wl,wholearchive
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"],
)