包括 <headers.h> 安装在非标准位置

Include <headers.h> installed in non standard location

我目前正在使用第三方库,它使用 angular 括号声明了 headers,就像标准库一样:

#include <header.h>

但是,这些 headers 安装在非标准位置,例如 /opt/company/software/version/part_software/include

使用像 MAKE 这样更传统的构建器,我可以只使用 CXXFLAGS 来指示 g++ 也在这个文件夹中查找库,最终归结为将 -I/opt/company/software/version/part_software/include 选项传递给 g++。

当尝试在 bazel 中做同样的事情时,使用 copts = [ "-I/opt/company/software/version/part_software/include" ],我得到一个“path outside of the execution root”错误。

据我了解,bazel 不喜欢安装 lib 的位置,因为构建需要可重现,并且包含位于执行根之外的库违反了此约束。

我遇到的一个丑陋的技巧是在 /usr/local/include 中创建 headers 的符号 link,并在 bazel 构建中使用 copts = [ "-I/usr/local/include" ]。但是,我发现这种方法很老套,我想找到一种更简单的方法来解决这个问题。


注意:我无法在 bazel 构建期间安装该程序,因为它使用了我无法控制的封闭安装程序。此安装程序不能 运行 在 bazel 的沙盒环境中,因为它需要在环境中无法访问的某些路径上写入。

所以,事实证明 bazelesque 包含第三方库的方法只是创建封装库的包。

多亏了这个有用的 discussion,我已经成功地用我的第三方库创建了一个包。

首先我们需要一个BUILD文件,这里命名为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
)

现在我们需要引用 WORKSPACE 文件中的 lib 子模块:

  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", 
      )

现在,我不再使用 copt 来引用所需的 headers,而是在需要时向 cc_rule 的 deps 添加一行,例如:

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