【问题标题】:Link CMake package with bazel cmake_external将 CMake 包与 bazel cmake_external 链接
【发布时间】:2021-02-25 02:41:29
【问题描述】:

要将 pytorch c++ 库与 CMake 链接,您真的只需要 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",
)

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

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

谢谢!

【问题讨论】:

    标签: bazel bazel-rules


    【解决方案1】:

    您的链接 (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"],
    )
    

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

    不,对于每个操作,Bazel 使用称为沙盒的功能设置一个完整的所需环境。当您为例如创建的工作区定义 BUILD 文件时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"],
    )
    

    这是一个自动工具示例,但没关系。 apr_util 目标取决于 apr。因此,在apr_util 构建期间,apr 构建工件将在$$EXT_BUILD_DEPS$$/apr 中可用。该路径专门用于该特定构建,稍后将被删除

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-22
      相关资源
      最近更新 更多