0

I am new to Bazel. I have a project which is built with Bazel. It also used some third-party libraries which are also build from bazel (from source).

I am now trying to export my project as a standalone library to others. I can compile my project as a so and copy related hpp files to a directory.

But I don't know how to deal with the third party libraries. Is there a fancy way to do this? Or any examples I can refer to?

My goal is to :

  1. Comile the project as a so file. Copy to a specfic directory. (DONE)
  2. Copy all the header files with tree structure. (DONE).
  3. Copy all the external libraries into the specfic directory as well (NEED HELP)
  4. Copy the external libraries' header files into the same header directory (NEED HELP)

output:

  • include/

    • my_library_name/
    • third_party_name1/
    • third_party_name2/
  • library/

    • libmy_library.so
    • libthird_party_name1.so
    • libthird_party_name2.so
ReneSun
  • 23
  • 2
  • 5
  • Are your project and the third-party libraries under the same _workspace_? – dms Dec 07 '21 at 00:26
  • You could make a genrule that takes the library objects as inputs and outputs a single tar file with all your files bundled up how you would like it deployed? – Laurenz Dec 07 '21 at 18:19
  • @dms No they are not in the same workspace. I imported them in the project's WORKSPACE and use as third_party. – ReneSun Dec 08 '21 at 02:43
  • @Laurenz Thanks for your suggestion. I am writing this genrule. But I am not sure how to copy the libraries. Since they are in bazel-bin/my_library_name/ & bazel-bin/external/third_party_name1. Should I hardcode the path and copy the libraries from there? Or is there a better way to do this? – ReneSun Dec 08 '21 at 02:45
  • If you have control over the third-party libraries BUILD files, you can use the `pkg_tar` rules to collect the output files (can add more info in a proper answer, if that's the case) – dms Dec 08 '21 at 05:16
  • @dms Yes. I have the control of the third-party libraries. and they are also built from source via Bazel. – ReneSun Dec 08 '21 at 06:28

1 Answers1

0

If you have control over the BUILD files of the third-party libraries, you could expose the header files separately and then use pkg_tar rules to collect the target files in the main project.

For example, assuming a folder structure like the following:

.
|-- project
|   |-- BUILD
|   |-- mylib
|   |   |-- BUILD
|   |   |-- mylib.cpp
|   |   `-- mylib.h
|   `-- WORKSPACE
`-- thirdparty
    |-- lib1
    |   |-- BUILD
    |   |-- lib1.cpp
    |   `-- lib1.h
    |-- lib2
    |   |-- BUILD
    |   |-- lib2.cpp
    |   `-- lib2.h
    `-- WORKSPACE

your third-party libraries BUILD files could expose a filegroup and a cc_library:

# thirdparty/lib1/BUILD

filegroup(
    name = "headers",
    srcs = ["lib1.h"],
    visibility = ["//visibility:public"],
)

cc_library(
    name = "lib1",
    hdrs = [":headers"],
    srcs=["lib1.cpp"],
    visibility = ["//visibility:public"],
)

The same pattern will apply to thirdparty/lib2/BUILD and project/mylib/BUILD.

Now in the main project you could have a main BUILD script that collects all the files into a tar archive:

# project/BUILD

load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar")

pkg_tar(
    name = "release_headers",
    srcs = [
        "//mylib:headers",
        "@thirdparty//lib1:headers",
        "@thirdparty//lib2:headers",
    ],
    package_dir = "include",
)

pkg_tar(
    name = "release_libs",
    srcs = [
        "//mylib",
        "@thirdparty//lib1",
        "@thirdparty//lib2",
    ],
    package_dir = "lib",
)

pkg_tar(
    name = "release",
    deps = [
        ":release_headers",
        ":release_libs",
    ],
)

Building :release should create a tar file with the desired structure:

$> bazel build :release
...
Target //:release up-to-date:
  bazel-bin/release.tar
...
$> tar -tf bazel-bin/release.tar
./
./include/
./include/mylib.h
./include/lib1.h
./include/lib2.h
./lib/
./lib/libmylib.a
./lib/libmylib.so
./lib/liblib1.a
./lib/liblib1.so
./lib/liblib2.a
./lib/liblib2.so

You can also have the pkg_tar rules for the third-party libraries in the third-party workspace for better modularity.

dms
  • 1,260
  • 7
  • 12