Bazel C++ 如何包含一个需要从 github 克隆的库,然后在它可以链接之前构建?

Bazel C++ how to include a library that needs to be cloned from github then build before it can be linked?

我需要使用的库是:https://github.com/madler/zlib .

要单独安装,我可以这样做:

git clone https://github.com/madler/zlib
cd zlib
make 

然后我可以通过包含“-lz”标志在编译期间使用它,例如:

g++ -o main main.cpp std=c++17 -lz

我想让“安装 zlib 并构建”成为我的 bazel 构建的一部分,而不是要求用户手动克隆和构建 zlib。

我的 Bazel 构建文件如下:

load("@rules_cc//cc:defs.bzl", "cc_binary")

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
    copts = ["-std=c++17","-O3"],
    linkopts = ["-lz"]
)

我应该添加什么,以便当我 运行 “bazel build ...”时,zlib 也被克隆并安装 (make)?

编辑:hello-world.cc 测试编译的程序:

#include <ctime>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <optional>
#include <vector>
#include <zlib.h>

class GzReader {
 private:
  static constexpr int BUFFER_SIZE = 1 << 20;
  const std::string filename_;
  gzFile file_;
  char *buffer_;
  int line_size_, idx_, last_idx_;                                          
  bool finished_;
  size_t line_count_;

 public:
  GzReader() = delete;

  explicit GzReader(std::string filename) : filename_(filename) {
    file_ = gzopen(filename_.c_str(), "r");
    if (!file_) {
      throw std::runtime_error("Could not open file");
    }

    buffer_ = new char[BUFFER_SIZE + 1];
    line_count_ = 0;
    idx_ = 0;
    last_idx_ = 0;
    line_size_ = gzread(file_, buffer_, BUFFER_SIZE);
    buffer_[line_size_] = '[=14=]';
    finished_ = (line_size_ == 0);
  }

  ~GzReader() { 
    delete[] buffer_; 
    gzclose(file_); 
  }
};

static const char *file_name = "text.gz";
int main() {
  GzReader reader(file_name);  
  return 0;
}

不幸的是,Bazel 没有对不提供 Bazel BUILD 文件的依赖项的原生支持。

您必须使用 bazel 封装来设置您自己的 zlib 镜像。

或者,有一个库 here 使之成为可能,但它需要一些努力。

他们提供了专门针对 zlib 的示例。

创建一个zlib.BUILD,内容如下:

# Copied from https://github.com/protocolbuffers/protobuf/blob/master/third_party/zlib.BUILD

#  Copyright 2008 Google Inc.  All rights reserved.
#
#  Redistribution and use in source and binary forms, with or without
#  modification, are permitted provided that the following conditions are
#  met:
#
#      * Redistributions of source code must retain the above copyright
#  notice, this list of conditions and the following disclaimer.
#      * Redistributions in binary form must reproduce the above
#  copyright notice, this list of conditions and the following disclaimer
#  in the documentation and/or other materials provided with the
#  distribution.
#      * Neither the name of Google Inc. nor the names of its
#  contributors may be used to endorse or promote products derived from
#  this software without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
#  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
#  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
#  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
#  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
#  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
#  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
#  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
#  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
#  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#  Code generated by the Protocol Buffer compiler is owned by the owner
#  of the input file used when generating it.  This code is not
#  standalone and requires a support library to be linked with it.  This
#  support library is itself covered by the above license.

load("@rules_cc//cc:defs.bzl", "cc_library")

licenses(["notice"])  # BSD/MIT-like license (for zlib)

_ZLIB_HEADERS = [
    "crc32.h",
    "deflate.h",
    "gzguts.h",
    "inffast.h",
    "inffixed.h",
    "inflate.h",
    "inftrees.h",
    "trees.h",
    "zconf.h",
    "zlib.h",
    "zutil.h",
]

_ZLIB_PREFIXED_HEADERS = ["zlib/include/" + hdr for hdr in _ZLIB_HEADERS]

# In order to limit the damage from the `includes` propagation
# via `:zlib`, copy the public headers to a subdirectory and
# expose those.
genrule(
    name = "copy_public_headers",
    srcs = _ZLIB_HEADERS,
    outs = _ZLIB_PREFIXED_HEADERS,
    cmd = "cp $(SRCS) $(@D)/zlib/include/",
)

cc_library(
    name = "zlib",
    srcs = [
        "adler32.c",
        "compress.c",
        "crc32.c",
        "deflate.c",
        "gzclose.c",
        "gzlib.c",
        "gzread.c",
        "gzwrite.c",
        "infback.c",
        "inffast.c",
        "inflate.c",
        "inftrees.c",
        "trees.c",
        "uncompr.c",
        "zutil.c",
        # Include the un-prefixed headers in srcs to work
        # around the fact that zlib isn't consistent in its
        # choice of <> or "" delimiter when including itself.
    ] + _ZLIB_HEADERS,
    hdrs = _ZLIB_PREFIXED_HEADERS,
    copts = select({
        "@bazel_tools//src/conditions:windows": [],
        "//conditions:default": [
            "-Wno-unused-variable",
            "-Wno-implicit-function-declaration",
        ],
    }),
    includes = ["zlib/include/"],
    visibility = ["//visibility:public"],
)

添加到您的 WORKSPACE:

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

maybe(
    http_archive,
    name = "net_zlib_zlib",
    build_file = "@openexr//:bazel/third_party/zlib.BUILD",
    sha256 = "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1",
    strip_prefix = "zlib-1.2.11",
    urls = [
        "https://zlib.net/zlib-1.2.11.tar.gz",
        "https://mirror.bazel.build/zlib.net/zlib-1.2.11.tar.gz",
    ],
)

添加到 cc_binarydeps 属性:

deps = [
    "@net_zlib_zlib//:zlib",
],

示例:OpenEXR 依赖于 zlib - 请参阅 here