Search code examples
c++11bazel

Include <headers.h> installed in non standard location


I'm currently working with a third party library, which has headers declared using angular brackets, like a standard library :

#include <header.h>

However, these headers are installed in a non standard place, something like /opt/company/software/version/part_software/include

With a more traditional builder like MAKE, I can just use CXXFLAGS to indicate to g++ to look in this folder too for libraries, which finally comes down to pass a -I/opt/company/software/version/part_software/include option to g++.

When trying to do the same thing in bazel, using copts = [ "-I/opt/company/software/version/part_software/include" ], I get a "path outside of the execution root" error.

It's my understanding that bazel don't like the place where the lib is installed because the build needs to be reproducible, and including a library located outside the execution root violate this constraint.

A ugly hack I've come with is to create symbolic link of the headers in /usr/local/include, and use copts = [ "-I/usr/local/include" ] in the bazel build. However, I find this approach very hacky, and I'd like to find a more bazely approach to the problem.


Note : I can't install the program during the bazel build, as it uses a closed installer on which I have no control over. This installer can't be run in the bazel's sandboxed environment, as it needs to write on certain paths not accessible within the environment.


Solution

  • So, it turns out that the bazelesque way of including a third part library is simply to create package encapsulating the library.

    Thanks to this useful discussion, I've managed to create a package with my third party library.

    First we need a BUILD file, here named package_name.BUILD

    package(
        default_visibility = ["//visibility:public"]
    )
    
    cc_library(
        name = "third_party_lib_name", #name to reference the third party library in other BUILD files
        srcs = [
            "external/soft/lib/some_lib.so", #.so files to include in the lib
            "software/lib/os/arch/lib_some_plugin.so",
        ],
        hdrs = glob([ # the glob takes all the headers needed
            "software/include/**/*.h",
            "software/include/**/*.hpp",
        ]), 
        includes = ["software/include/"], # Specify which files are included when we use the library
    )
    

    Now we need to reference the lib a a submodule in the WORKSPACE file :

      new_local_repository(
          name = "package_name",
          path = "opt/company/software/version",
          # build_file: path to the BUILD file, here in the same directory that the main WORKSPACE one
          build_file = __workspace_dir__ + "/package_name.BUILD", 
          )
    

    Now, instead of using copt to references the needed headers, I'm just adding a line to the deps of the cc_rule when needed, e.g :

    cc_library(
        name="some_internal_lib",
        srcs = ["some_internal_lib.cc"],
        deps = [
             "@package_name//:third_party_lib_name", #referencing the third party lib
               ],
    )