Baiyan Huang
Baiyan Huang

Reputation: 6771

How to use c++ external library in bazel

I consider this a fairly fundamental requirement for a build system, but somehow it is not that straightforward - I've found 2 pieces of information, but without any luck yet:

But for both cases, I don't see a way to specify the path/to/precompiled/lib, then how suppose it should work? I tried to ln the library folder into the Bazel workspace, but also got no luck.

Would really appreciate if you could shed lights on how to use an external dependency in Bazel, or point me to a real, working example.

Upvotes: 2

Views: 5701

Answers (2)

Michael Krebs
Michael Krebs

Reputation: 8186

(Wow, bazel does not make it easy... at least not according to its documentation.)

I found the answer in How to link with libm.so and libdl.so with my bazel project? that worked for me, at least.

My header includes "just worked" for the libssl-dev package I installed in the system. I simply added the following to my BUILD in the cc_binary target:

linkopts = ["-lcrypto"],

Here are the docs for linkopts: https://bazel.build/reference/be/c-cpp#cc_binary.linkopts.

Upvotes: 0

Vertexwahn
Vertexwahn

Reputation: 8142

Take a look at https://github.com/justbuchanan/bazel_rules_qt to see how a precompiled Qt5 version can be used with Bazel. The problem with precompiled libs is that you need them for every OS, compiler(-settings), platform. If you only target a specific OS + host compiler and target platform then precompiled libs are fine.

Think also about bazelizing your third-party library. I did this for instance for OpenEXR and oneTBB. I also hacked together some scripting to convert Visual Studio Project files to Bazel BUILD files.

Here is an example of how to use a precompiled OpenCV version on Windows:

WORKSPACE.bazel:

workspace(name = "OpenCVDemo")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

# OpenCV
http_archive(
    name = "opencv",
    build_file = "//third_party:opencv.BUILD",
    strip_prefix = "opencv/build",
    # Release
    url = "https://github.com/opencv/opencv/releases/download/4.3.0/opencv-4.3.0-dldt-2020.2-vc16-avx2.zip",
)

opencv.BUILD:

package(default_visibility = ["//visibility:public"])

MAIN_MODULES = [
    "core",
    "imgproc",
    "imgcodecs",
    "videoio",
    "highgui",
    "video",
    "calib3d",
    "features2d",
    "objdetect",
    "dnn",
    "ml",
    "flann",
    "photo",
    "stitching",
    "gapi",
]

# https://stackoverflow.com/questions/56108940/how-to-specify-the-compiler-flags-to-be-used-in-opt-compilation-mode-by-my-own
config_setting(
    name = "fastbuild_mode",
    values = {"compilation_mode": "fastbuild"},
)

config_setting(
    name = "dbg_mode",
    values = {"compilation_mode": "dbg"},
)

cc_import(
    name = "tbb",
    shared_library = select({
        ":fastbuild_mode": "bin/tbb.dll",
        ":dbg_mode": "bin/tbb_debug.dll",
        "//conditions:default": "bin/tbb.dll",
    }),
)

[
    (
        cc_import(
            name = module,
            interface_library = select({
                ":fastbuild_mode": "lib/opencv_{}430.lib".format(module),
                ":dbg_mode": "lib/opencv_{}430d.lib".format(module),
                "//conditions:default": "lib/opencv_{}430.lib".format(module),
            }),
            shared_library = select({
                ":fastbuild_mode": "bin/opencv_{}430.dll".format(module),
                ":dbg_mode": "bin/opencv_{}430d.dll".format(module),
                "//conditions:default": "bin/opencv_{}430.dll".format(module),
            }),
        )
    )
    for module in MAIN_MODULES
]

cc_library(
    name = "opencv",
    hdrs = [
        "include/opencv2/calib3d.hpp",
        "include/opencv2/calib3d/calib3d.hpp",
        "include/opencv2/calib3d/calib3d_c.h",
        "include/opencv2/core.hpp",
        "include/opencv2/core/hal/interface.h",
        "include/opencv2/cvconfig.h",
        "include/opencv2/dnn.hpp",
        "include/opencv2/features2d.hpp",
        "include/opencv2/flann.hpp",
        "include/opencv2/flann/config.h",
        "include/opencv2/flann/defines.h",
        "include/opencv2/flann/miniflann.hpp",
        "include/opencv2/highgui.hpp",
        "include/opencv2/highgui/highgui.hpp",
        "include/opencv2/highgui/highgui_c.h",
        "include/opencv2/imgcodecs.hpp",
        "include/opencv2/imgproc.hpp",
        "include/opencv2/ml.hpp",
        "include/opencv2/ml/ml.inl.hpp",
        "include/opencv2/objdetect.hpp",
        "include/opencv2/opencv.hpp",
        "include/opencv2/opencv_modules.hpp",
        "include/opencv2/photo.hpp",
        "include/opencv2/stitching.hpp",
        "include/opencv2/video.hpp",
        "include/opencv2/video/background_segm.hpp",
        "include/opencv2/video/tracking.hpp",
        "include/opencv2/videoio.hpp",
        "include/opencv2/videoio/videoio_c.h",
    ],
    includes = ["include"],
    deps = MAIN_MODULES + [
        "tbb",
    ],
)

BUILD.bazel:

cc_binary(
    name = "OpenCVDemo",
    srcs = ["main.cpp"],
    deps = ["@opencv"],
)

Should work similar for other libraries

Upvotes: 4

Related Questions