Search code examples
bazel

Bazel link library: How to change to link to built library?


I am new to bazel. I tried the tutorial below https://docs.bazel.build/versions/master/tutorial/cpp.html#use-multiple-packages

And to create a shared library, I added 'linkstatic = False' in cc_binary,

So BUILD file is

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")                                                                                  

cc_library(
    name = "hello-greet",
    srcs = ["hello-greet.cc"],
    hdrs = ["hello-greet.h"],
)

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    deps = [
        ":hello-greet",
        "//lib:hello-time"
    ],  
    linkstatic = False,
)

and after build, I confirmed that 'libhello-greet.so' was created under the bazel-bin directory. However, if I check the hello-world executable with ldd, it is as follows.

$ ldd hello-world
~snip~
libmain_Slibhello-greet.so => /home/foo/.cache/bazel/_bazel_wrs/8e7a6d8989ff6d697373ddbabde23fa3/execroot/__main__/bazel-out/k8-fastbuild/bin/main/./../_solib_k8/libmain_Slibhello-greet 0x00007f2706f84000)
liblib_Slibhello-time.so => /home/foo/.cache/bazel/_bazel_wrs/8e7a6d8989ff6d697373ddbabde23fa3/execroot/__main__/bazel-out/k8-fastbuild/bin/main/./../_solib_k8/liblib_Slibhello-time.so 0x00007f2706f81000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f2706462000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2706071000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2706da1000)

Why hello-world linking the library(libmain_Slibhello-greet.s) in the cache directory instead of linking the locally generated libhello-greet.so? How do I change it link to libhello-greet.so?


Solution

  • i think that the locally created directories are all Symlinks to the output directory ~/.chache/bazel as you can check with

    fed@fed-VirtualBox:~/cpp-tutorial/stage2/bazel-bin/main$ readlink -f libhello-greet.so
    /home/.cache/bazel/_bazel_fed/d6678e06051dff35967a6c61fe201847/execroot/__main__/bazel-out/k8-fastbuild/bin/main/libhello-greet.so
    

    You can find out more on the bazel output layout here https://docs.bazel.build/versions/master/output_directories.html . However, an alternative to have your final executable linked to a shared object under a certain path is to set your environment variable

    fed@fed-VirtualBox: LD_LIBRARY_PATH="/home/cpp-tutorial/stage2/main/lib/"
    fed@fed-VirtualBox: export LD_LIBRARY_PATH
    

    and then directly import the library in your BUILD file

    cc_import(
        name = "hello-greet",
        hdrs = ["hello-greet.h"],
        shared_library = "lib/libhello-greet.so",
    )
    
    cc_binary(
        name = "hello-world",
        srcs = ["hello-world.cc"],
        deps = [
            ":hello-greet",
        ],  
        linkstatic = False,
    )
    

    and then your final executable will be linked to the .so under your path

    fed@fed-VirtualBox:~/examples/cpp-tutorial/stage2$ ldd   bazel-bin/main/hello-world
        linux-vdso.so.1 (0x00007ffe72df2000)
        libhello-greet.so => /home/cpp-tutorial/stage2/main/lib/libhello-greet.so (0x00007f3bba04d000)
        libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3bb9e5a000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3bb9d0b000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f3bb9cf0000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3bb9afe000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3bba057000)