例如:
lib_a是一个内部库。它公开接口标头alpha.h。
lib_b是一个 API 库。它包括alpha.h在beta.c并暴露接口头beta.h不包括alpha.h。
exe_c是一个测试应用程序,利用lib_b. 由于它是 API 库的“外部” lib_b,它不应该访问内部库lib_a的头文件,即alpha.h.
现在,有没有办法防止将 的包含路径alpha.h添加到exe_c的编译命令行?
22 年 5 月 24 日更新:Bazel 添加了implementation_deps功能。
这可以通过自定义规则和宏来实现。
这是编写宏的方法,my_cc_library以便您可以执行类似的操作
my_cc_library(
name = "b",
hdrs = [
"b.h",
],
srcs = [
"b.cc",
]
impl_deps = [
"//a:a",
],
)
Run Code Online (Sandbox Code Playgroud)
并且依赖的目标b将无法包含依赖项中的标头a。
添加一个自定义规则,该规则采用基础库并形成一个新的CcInfo提供程序,其中仅包含您要公开的标头。
def _my_cc_slim_library(ctx):
cc_info = ctx.attr.base_library[CcInfo]
compilation_ctx = cc_info.compilation_context
compilation_ctx_p = cc_common.create_compilation_context(
headers = depset(direct=ctx.files.hdrs),
includes = compilation_ctx.includes,
quote_includes = compilation_ctx.quote_includes,
)
dep_cc_infos = [dep[CcInfo] for dep in ctx.attr.deps]
cc_info_p = cc_common.merge_cc_infos(
cc_infos = [
CcInfo(
compilation_context = compilation_ctx_p,
linking_context = cc_info.linking_context,
)
] + dep_cc_infos,
)
return [cc_info_p]
my_cc_slim_library = rule(
implementation = _my_cc_slim_library,
attrs = {
"base_library": attr.label(mandatory=True, providers = [CcInfo]),
"hdrs": attr.label_list(allow_files=True),
"deps": attr.label_list(providers = [CcInfo]),
},
)
Run Code Online (Sandbox Code Playgroud)
添加自定义宏my_cc_library。该宏将创建一个基础库,然后使用该规则my_cc_slim_library去除不需要的标头依赖项。
def my_cc_library(
name,
hdrs = [],
deps = [],
impl_deps = [],
**kwargs):
native.cc_library(
name = name + "-base",
hdrs = hdrs,
deps = deps + impl_deps,
**kwargs)
my_cc_slim_library(
name = name,
hdrs = hdrs,
base_library = name + "-base",
deps = deps,
)
Run Code Online (Sandbox Code Playgroud)
现在介绍如何在示例中使用它。
bazel/my_cc_library.bzl<- 包含自定义规则和宏
a/a.h
int do_a();
Run Code Online (Sandbox Code Playgroud)
a/a.cc
#include "a/a.h"
int do_a() {
return 1;
}
Run Code Online (Sandbox Code Playgroud)
a/BUILD
package(default_visibility = ["//visibility:public"])
cc_library(
name = "a",
hdrs = [
"a.h",
],
srcs = [
"a.cc",
],
)
Run Code Online (Sandbox Code Playgroud)
b/b.h
int do_b();
Run Code Online (Sandbox Code Playgroud)
b/b.cc
#include "a/a.h"
int do_b() {
return do_a() + 2;
}
Run Code Online (Sandbox Code Playgroud)
b/BUILD
load(
"//bazel:my_cc_library.bzl",
"my_cc_library",
)
package(default_visibility = ["//visibility:public"])
my_cc_library(
name = "b",
hdrs = [
"b.h",
],
srcs = [
"b.cc",
],
impl_deps = [
"//a:a",
],
)
Run Code Online (Sandbox Code Playgroud)
main.cc
#include <iostream>
// #include "a/a.h" <- this would cause an error
#include "b/b.h"
int main() {
std::cout << do_b() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
BUILD
cc_binary(
name = "exe",
srcs = [
"main.cc",
],
deps = [
"//b:b",
],
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
500 次 |
| 最近记录: |