naming and dynamic linking behavior of shared library in Bazel

3,049 views
Skip to first unread message

Hu David

unread,
Nov 27, 2015, 12:15:42 AM11/27/15
to bazel-discuss
Hi,

I have three files --- main.c   hello.c   hello2.c

The main function will call hello() in hello.c, hello() will call hello2() in hello2.c
Thus,
main.c depend on hello.c. 
hello.c depend on hello2.c


I would like to compile hello & hello2 as shared libraries and dynamically linked.

The following is my BUILD file:

load("/tools/build_defs/pkg/pkg", "pkg_tar")

filegroup(
    name = "all_files",
    srcs = ["main", "hello", "hello2"],
)

cc_binary(
    name = "main",
    srcs = ["main.c"],
    deps = [":hello"],
    linkstatic = 0,
)

cc_library(
    name = "hello",
    srcs = ["hello.c"],
    deps = [":hello2"],
)

cc_library(
    name = "hello2",
    srcs = ["hello2.c"],
)

pkg_tar(
    name = "final",
    files = ["main"],
    extension = "tar.gz",
)

After I execute bazel build //:all_files, I got the binary & libraries:
  bazel-bin/libhello.a
  bazel-bin/libhello.so
  bazel-bin/libhello2.a
  bazel-bin/libhello2.so
  bazel-bin/main

Then I objdump -p bazel-bin/main | grep NEEDED :
  NEEDED               liblibhello.so
  NEEDED               liblibhello2.so
  NEEDED               libstdc++.so.6
  NEEDED               libc.so.6

And objdump -p bazel-bin/libhello.so | grep NEEDED :
  NEEDED               libstdc++.so.6
  NEEDED               libc.so.6


I have three questions about the result:

1.)
Can I control the naming of liblibhello.so & liblibhello2.so in the main binary, seems like Bazel determine the naming of dynamic linking by its own way.
I would like to put all these libraries & executable to the target machine's filesystem(ex. /usr/lib, /usr/bin). However, the naming convention seems different from the traditional one (libXXXXX.so). Or do I miss something here?

2.)
Though the dependency graph is:  main --> hello --> hello2 , Bazel put the indirect dependency (liblibhello2.so) to main.
I would like to have the following result:
objdump -p bazel-bin/main | grep NEEDED
  NEEDED               liblibhello.so
  ..

objdump -p bazel-bin/libhello.so | grep NEEDED :
  NEEDED               liblibhello2.so
  ..

Is there any way to control this dynamic linking information in Bazel?

3.)
When bazel build //:final , I only get the main executable in the tarball. Is there any way to instruct Bazel automatically includes all the needed (deps) shared libraries in the tarball?

Thanks.

Damien Martin-guillerez

unread,
Nov 27, 2015, 8:28:15 AM11/27/15
to Hu David, bazel-discuss
1/ No it is not possible, the naming is lib%{name}.so. You can control it by doing a cc_binary with the name you want (yes that's a bit weird).

2/ Same answer as 1/ do a cc_binary...

3/ It is because we should pack the runfiles tree probably, you can sort things out by using a statically linked binary. Can you file a FR on github for having an option to pkg_tar to add the runfile tree?

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/36d81dfe-384f-4f8f-9a91-031cfebfb8f9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Hu David

unread,
Nov 29, 2015, 11:32:09 PM11/29/15
to bazel-discuss, chi...@gmail.com
Thanks Damien.

After I change the rule to:

cc_binary(
    name = "libhello2.so",
    linkshared = 1,
    srcs = ["hello2.c"],
)

cc_binary(
    linkshared = 1,
    name = "libhello.so",
    srcs = ["hello.c", ":libhello2.so"],
)

cc_binary(
    name = "main",
    srcs = ["main.c", "libhello.so"],
)

I got the following message when compile (bazel build //:main): 

/usr/bin/ld: warning: libhello2.so, needed by bazel-out/local_linux-fastbuild/bin/_solib_local/_U_S_S_Cmain___U/libhello.so, not found (try using -rpath or -rpath-link)

bazel-out/local_linux-fastbuild/bin/_solib_local/_U_S_S_Cmain___U/libhello.so: undefined reference to `hello2'
collect2: error: ld returned 1 exit status

ERROR: /root/test/BUILD:20:1: Linking of rule '//:main' failed: gcc failed: error executing command
  (cd /root/.cache/bazel/_bazel_root/0ad3a1308b10afb9d4a36f7a97ce8ee8/test && \
  exec env - \
  /usr/bin/gcc -o bazel-out/local_linux-fastbuild/bin/main '-Wl,-rpath,$ORIGIN/_solib_local/_U_S_S_Cmain___U' -Lbazel-out/local_linux-fastbuild/bin/_solib_local/_U_S_S_Cmain___U -B/usr/bin/ -Wl,-z,relro,-z,now -no-canonical-prefixes -pass-exit-codes '-Wl,--build-id=md5' '-Wl,--hash-style=gnu' -Wl,-S -Wl,@bazel-out/local_linux-fastbuild/bin/main-2.params): gcc failed: error executing command
  (cd /root/.cache/bazel/_bazel_root/0ad3a1308b10afb9d4a36f7a97ce8ee8/test && \
  exec env - \
  /usr/bin/gcc -o bazel-out/local_linux-fastbuild/bin/main '-Wl,-rpath,$ORIGIN/_solib_local/_U_S_S_Cmain___U' -Lbazel-out/local_linux-fastbuild/bin/_solib_local/_U_S_S_Cmain___U -B/usr/bin/ -Wl,-z,relro,-z,now -no-canonical-prefixes -pass-exit-codes '-Wl,--build-id=md5' '-Wl,--hash-style=gnu' -Wl,-S -Wl,@bazel-out/local_linux-fastbuild/bin/main-2.params).
Target //:main failed to build

I know adding "libhello2.so" to the srcs of main could pass the build but it does not satisfy my second question in previous post. I guess it is something related to -rpath-link. Is there any option of cc_binary() that could let Bazel auto-resolve the dependency of [main --> hello --> hello2] when linking? How should I modify my BUILD file? Thanks.

David

Damien Martin-guillerez

unread,
Nov 30, 2015, 3:06:26 AM11/30/15
to Hu David, bazel-discuss, lbe...@google.com, ulf...@google.com
Hi Hu,
+Lukács T. Berki or +Ulf Adams might have a better idea on how do so.

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.

Lukács T. Berki

unread,
Nov 30, 2015, 7:14:21 AM11/30/15
to Damien Martin-guillerez, Hu David, bazel-discuss, ulf...@google.com
I don't have much wisdom to add here... the double "lib" prefix doesn't make much sense on the surface, but it kinda does because if you have a rule called "x" both in packages a and b, in order for them not to clash, you have to distinguish them somehow, and they way we do it is to encode the package name into the name of the .so, and thus they'd be "liba_Sx.so" and "libb_Sx.so". 

Maybe Ulf has a plan how to sort this out?
--
Lukács T. Berki | Software Engineer | lbe...@google.com | 

Google Germany GmbH | Maximillianstr. 11-15 | 80539 München | Germany | Geschäftsführer: Matthew Scott Sucherman, Paul Terence Manicle | Registergericht und -nummer: Hamburg, HRB 86891

Hu David

unread,
Dec 2, 2015, 3:44:06 AM12/2/15
to bazel-discuss, dmar...@google.com, chi...@gmail.com, ulf...@google.com
Yeah, seems like Bazel does this library name mangling because it put all the needed libraries to the same directory.

>> 1/ No it is not possible, the naming is lib%{name}.so. You can control it by doing a cc_binary with the name you want (yes that's a bit weird).
>> 2/ Same answer as 1/ do a cc_binary...

I do feel a bit weird since I have to use cc_binary to build the shared library only because the naming (libXXX.so) issue.
Is there any plan to add/enhance the cc_library's attribute to fix this? Maybe a (fully) user defined name for the library? Or, this is not an issue in most of the use cases of Bazel?

David

Thiago Farina

unread,
Dec 2, 2015, 8:55:26 PM12/2/15
to Hu David, bazel-discuss
On Wed, Dec 2, 2015 at 6:44 AM, Hu David <chi...@gmail.com> wrote:
Yeah, seems like Bazel does this library name mangling because it put all the needed libraries to the same directory.

>> 1/ No it is not possible, the naming is lib%{name}.so. You can control it by doing a cc_binary with the name you want (yes that's a bit weird).
>> 2/ Same answer as 1/ do a cc_binary...

I do feel a bit weird since I have to use cc_binary to build the shared library only because the naming (libXXX.so) issue.
Is there any plan to add/enhance the cc_library's attribute to fix this? Maybe a (fully) user defined name for the library?
+1!

--
Thiago Farina

Kamal Marhubi

unread,
Dec 3, 2015, 1:01:19 PM12/3/15
to Damien Martin-guillerez, Hu David, bazel-discuss
On Fri, Nov 27, 2015 at 8:28 AM 'Damien Martin-guillerez' via bazel-discuss <bazel-...@googlegroups.com> wrote:
3/ It is because we should pack the runfiles tree probably, you can sort things out by using a statically linked binary. Can you file a FR on github for having an option to pkg_tar to add the runfile tree?

In case anyone else is looking for it, this was filed yesterday as:

https://github.com/bazelbuild/bazel/issues/671
Reply all
Reply to author
Forward
0 new messages