You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bazel构建阶段复制重命名目录及依赖报错解决问询

错误原因

Bazel的执行分为配置阶段和构建阶段:

  • 配置阶段会扫描所有真实存在的目录,解析BUILD文件和依赖关系
  • 你用copy_directory生成的directory_real是在构建阶段才会创建的临时目录,配置阶段Bazel根本找不到这个目录的BUILD文件,所以报错no such package 'directory_real'。
正确实现方案

不需要复制目录,用Bazel的config_setting+alias机制就能实现根据标志切换依赖,更高效简洁。

步骤1:定义配置标志

在根目录的BUILD文件中添加配置规则,用来识别构建时的标志:

config_setting(
    name = "use_directory_b",
    define_values = {"use_dir": "b"},
)

config_setting(
    name = "use_directory_a",
    define_values = {"use_dir": "a"},
    # 默认用directory_a,当没有指定--define use_dir=b时生效
    visibility = ["//visibility:public"],
)

步骤2:定义别名库

在根目录BUILD中添加一个别名cc_library,根据标志自动切换到directory_a或directory_b的mylib:

alias(
    name = "real_mylib",
    actual = select({
        ":use_directory_b": "//directory_b:mylib",
        ":use_directory_a": "//directory_a:mylib",
        "//conditions:default": "//directory_a:mylib",
    }),
    visibility = ["//visibility:public"],
)

步骤3:调整main.cpp的include和构建配置

修改main.cpp的include路径(不需要虚拟的directory_real):

#include "interface.h"
// do something
int main(){ // 注意:C++标准中main返回int,不是void
    // say hello world
    return 0;
}

然后修改directoryC/BUILD中的cc_binary配置,添加include路径并依赖别名库:

cc_binary(
    name = "test",
    srcs = ["main.cpp"],
    visibility = ["//visibility:public"],
    copts = select({
        "//:use_directory_b": ["-I../directory_b"],
        "//:use_directory_a": ["-I../directory_a"],
        "//conditions:default": ["-I../directory_a"],
    }),
    deps = ["//:real_mylib"],
)

构建命令

  • 默认用directory_a构建:
bazel build //directoryC:test
  • 指定用directory_b构建:
bazel build //directoryC:test --define use_dir=b

(可选)坚持使用directory_real作为include路径的方案

如果必须保留#include "directory_real/interface.h"的写法,可以用genrule生成包含头文件的directory_real目录,然后用cc_library依赖生成的文件:

  1. 根目录BUILD添加genrule:
genrule(
    name = "generate_directory_real",
    srcs = select({
        ":use_directory_b": ["//directory_b:interface.h", "//directory_b:mylib.cpp"],
        ":use_directory_a": ["//directory_a:interface.h", "//directory_a:mylib.cpp"],
    }),
    outs = [
        "directory_real/interface.h",
        "directory_real/mylib.cpp",
    ],
    cmd = """
        mkdir -p $(@D)/directory_real
        cp $(SRCS) $(@D)/directory_real/
    """,
)

cc_library(
    name = "directory_real_mylib",
    srcs = [":generate_directory_real"],
    hdrs = [":generate_directory_real"],
    visibility = ["//visibility:public"],
)
  1. 修改directoryC/BUILD:
cc_binary(
    name = "test",
    srcs = ["main.cpp"],
    visibility = ["//visibility:public"],
    copts = ["-I.."], # 让编译器能找到根目录下生成的directory_real
    deps = ["//:directory_real_mylib"],
)

这种方式需要生成文件副本,不如别名方案高效,优先推荐第一种方案。

内容的提问来源于stack exchange,提问作者Exia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:20:26