Link 带边框的 CMake 包 cmake_external

Link CMake package with bazel cmake_external

到 link 带有 CMake 的 pytorch c++ 库,你真的只需要 find_package(Torch REQUIRED) 并使用

-DCMAKE_PREFIX_PATH=/absolute/path/to/libtorch

您可以在此处下载源代码:https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip CMake 教程在这里:https://pytorch.org/cppdocs/installing.html

我的 WORKSPACE 中有以下内容:

new_local_repository(
    name = "torch",
    build_file_content = all_content,
    path = "third_party/libtorch",
)

这在我的 BUILD

cmake_external(
    name = "torch",
    cache_entries = {
        "CMAKE_PREFIX_PATH": "/home/jackshi/projects/third_party/libtorch",
    },
    lib_source = "@torch//:all",
)

当我尝试 link 时,我得到 <dir> does not appear to contain CMakeList.txt 这是事实,但是,当您 link 它与 find_package(Torch REQUIRED) 时,不需要顶级 CMakeList.txt。 CMake 寻找 TorchConfig.cmake 。 bazel 可以在没有顶级 CMakeList.txt 的情况下为此包创建目标吗?它应该在寻找 TorchConfig.cmake 对吗?

此外,当文件是远程的,通过 http_archive 获取时,CMAKE_PREFIX_PATH 如何工作,你使用 ~/.cache/bazel 目录吗?

谢谢!

您的 link (https://download.pytorch.org/libtorch/nightly/cpu/libtorch-shared-with-deps-latest.zip) 不是源代码,它是完全编译的库。因此不需要CMake,因为它已经编译好了。

find_package 是一个 CMake 功能,它使用一种算法找到已经 编译的 依赖项,该算法搜索最常见的安装路径。即使在 CMake 中也不必编译您想查找的库。你不想在这里使用它,因为它是解决问题的CMake方式

您可以尝试三种方法:

  • 在 Bazel 中,您可以使用已经构建的库。为此,只需创建一个普通的 cc_library 规则,将已编译的库 *.a 添加为 srcs
cc_library(
    name = "torch",
    srcs = glob(["lib/*.so", "lib/*.a"]),
    hdrs = glob(["include/**/*.h", "include/**/*.h"]),
    includes = ["include"],
)

这种做法很糟糕,因为你无法控制这个库的构建过程。您从源代码编译的越多,您的构建堆栈就越好、越健壮。

# WORKSPACE file
 http_archive(
      name = "pytorch",
      urls = ["https://github.com/pytorch/pytorch/archive/v1.7.1.tar.gz"],
      strip_prefix  = "pytorch-1.7.1",
  )

# and then in your BUILD file

cc_binary(
  name = "my_supper_binary"
  srcs = ["main.cpp"],
  deps = ["@pytorch//:torch"],
)

Also, how does CMAKE_PREFIX_PATH work when the files are remote, acquired through http_archive, do you use ~/.cache/bazel directory?

不,对于每个操作,Bazel 使用称为沙盒的功能设置一个完整的所需环境。当您为由例如创建的工作空间定义 BUILD 文件时a http_archive,那么所有需要的依赖都会在那里,你不应该关心它,因为那个位置在动作完成后被删除了。使用正确的沙盒实现,您甚至无法读取 /home/jackshi/projects/third_party/libtorch,因为该路径不在您的 deps 中。 Bazel 对此非常认真,因为无法跟踪这种偷偷摸摸的依赖关系,因此您可以在此处更改一些内容,Bazel 将不会重新编译您的目标

然而,有时您想为 cmake_external 添加一些依赖项。使用 rules_foreign_cc 你可以这样做:

configure_make(
    name = "apr",
    lib_source = "@apr//:all",
    shared_libraries = ["libapr-1.so"],
    static_libraries = ["libapr-1.a"],
)

configure_make(
    name = "apr_util",
    configure_options = [
        "--with-apr=$$EXT_BUILD_DEPS$$/apr",
    ],
    lib_source = "@apr_util//:all",
    shared_libraries = ["libaprutil-1.so"],
    static_libraries = ["libaprutil-1.a"],
    deps = [":apr"],
)

是一个autotools的例子,不过没关系。 apr_util 目标取决于 apr。因此,在 apr_util 构建期间,apr 构建工件将在 $$EXT_BUILD_DEPS$$/apr 中可用。该路径专门创建用于该特定构建,稍后将被删除