我有一个通过CMake构建的项目,需要大量手动安装额外的deps。我想迁移这个项目到Bazel,并使这些库自动下载。我找到了一个Boost的解决方案,但是我不知道如何添加icu4c和其他通过其他工具构建的库。
发布于 2022-09-03 11:49:28
使用Bazel使用第三方库的方法有很多。选择的方法取决于第三方库的不同属性,例如:第三方库是否已经支持Bazel?库是否仅作为预构建包使用?库是否使用代码生成器或任何其他工具,或传递依赖关系?
考虑到使用{fmt}作为构建系统的CMake示例,您可以按照以下步骤进行操作:
第一种方法:注入构建文件
在您的WORKSPACE文件中,您可以执行如下操作:
maybe(
new_git_repository,
name = "fmt",
branch = "master",
remote = "https://github.com/fmtlib/fmt",
build_file = "//third_party:fmt.BUILD",
)相应的fmt.BUILD文件可以如下所示:
cc_library(
name = "fmt",
srcs = [
#"src/fmt.cc", # No C++ module support
"src/format.cc",
"src/os.cc",
],
hdrs = [
"include/fmt/args.h",
"include/fmt/chrono.h",
"include/fmt/color.h",
"include/fmt/compile.h",
"include/fmt/core.h",
"include/fmt/format.h",
"include/fmt/format-inl.h",
"include/fmt/locale.h",
"include/fmt/os.h",
"include/fmt/ostream.h",
"include/fmt/printf.h",
"include/fmt/ranges.h",
"include/fmt/xchar.h",
],
includes = [
"include",
"src",
],
strip_include_prefix = "include",
visibility = ["//visibility:public"],
)优势:
缺点:
fmt.BUILD文件。BUILD文件也需要一些时间和{fmt}的知识。构建这个库的最佳实践是什么?第二种方法: Bazelize {fmt}
将WORKSPACE文件和BUILD文件添加到{fmt}存储库中。
通过这种方式,{fmt}可以得到bazelized,并且可以在Bazel构建中使用。
你可以用这个方法:
示例
创建一个具有以下内容的WORKSPACE.bazel文件:
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
# Fetch bazelized fmt
git_repository(
name = "fmt",
branch = "bazel-support", # A copy of master where BUILD.bazel, WORKSPACE.bazel, .bazelrc and .bazelversion are moved to root
remote = "https://github.com/<user_or_organisation>/fmt", # replace <user_or_organisation> by a valid account
)创建一个BUILD.bazel文件并将一个依赖项添加到{fmt} (使用fmt.BUILD的内容)。
为了保持{fmt}项目目录的清洁,这些文件没有添加到项目根目录中(有关详细信息,请参阅这里 )。
第三种方法:使用Bazel的{fmt}存储库
即使{fmt}存储库在其根目录中不包含WORKSPACE文件,也有一种简单的方法可以使用带Bazel的{fmt}存储库。下面的示例演示了这一点。
添加到您的WORKSPACE文件:
load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository")
# Fetch all files from fmt including the BUILD file `support/bazel/BUILD.bazel`
new_git_repository(
name = "fmt_workaround",
branch = "master",
remote = "https://github.com/fmtlib/fmt/",
build_file_content = "# Empty build file on purpose"
)
# Now the BUILD file `support/bazel/BUILD.bazel` can be used:
new_git_repository(
name = "fmt",
branch = "master",
remote = "https://github.com/fmtlib/fmt/",
build_file = "@fmt_workaround//:support/bazel/BUILD.bazel"
)创建一个BUILD.bazel文件并向{fmt}添加依赖项:
cc_binary( # Build a binary
name = "Demo", # Name of the binary
srcs = ["main.cpp"], # List of files - we only have main.cpp
deps = ["@fmt//:fmt"], # Depend on fmt
)利用main.cpp中的{fmt}
#include "fmt/core.h"C
int main() {
fmt::print("The answer is {}.\n", 42);
}本例的预期输出是The answer is 42。
第四种方法:利用patch_cmd
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
git_repository(
name = "fmt",
branch = "master",
patch_cmds = [
"mv support/bazel/.bazelrc .bazelrc",
"mv support/bazel/.bazelversion .bazelversion",
"mv support/bazel/BUILD.bazel BUILD.bazel",
"mv support/bazel/WORKSPACE.bazel WORKSPACE.bazel",
],
# Windows related patch commands are only needed in the case MSYS2 is not installed
patch_cmds_win = [
"Move-Item -Path support/bazel/.bazelrc -Destination .bazelrc",
"Move-Item -Path support/bazel/.bazelversion -Destination .bazelversion",
"Move-Item -Path support/bazel/BUILD.bazel -Destination BUILD.bazel",
"Move-Item -Path support/bazel/WORKSPACE.bazel -Destination WORKSPACE.bazel",
],
remote = "https://github.com/fmtlib/fmt",
)更多细节这里。
其他图书馆
我写了几篇关于Bazel化不同语言库的博文:
https://stackoverflow.com/questions/73591451
复制相似问题