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

使用JNI的Bazel C++程序:Jar相对路径问题求助

解决Bazel构建JNI程序时C++找不到Jar包的问题

问题根源

Bazel构建后,C++二进制文件会被放到bazel-bin的子目录中(比如//src:app对应bazel-bin/src/app),如果JavaNativeInterface.jar没有被同步到该目录,代码里的相对路径.:JavaNativeInterface.jar自然无法定位到文件。你之前用genrule没生效,大概率是没把生成的Jar关联到cc_binary的依赖链里。

可行解决方案

方案1:让Bazel自动复制Jar到二进制目录

直接通过cc_binary的data字段声明对Jar的依赖,Bazel会自动把Jar同步到二进制所在的bazel-bin子目录,此时相对路径就能正常工作。

示例BUILD配置:

# 先定义filegroup引用源码目录中的Jar
filegroup(
    name = "jni_jar",
    srcs = ["JavaNativeInterface.jar"],
)

cc_binary(
    name = "jni_app",
    srcs = ["main.cpp"],
    # 将Jar加入data依赖,Bazel会自动同步到二进制目录
    data = [":jni_jar"],
    # 添加JNI必要的链接配置(示例为Linux下JVM库)
    linkopts = ["-ljvm"],
    includes = ["/usr/lib/jvm/java-11-openjdk-amd64/include"],
)

构建完成后,JavaNativeInterface.jar会和jni_app二进制文件处于同一目录,C++代码里的-Djava.class.path=.:JavaNativeInterface.jar就能正确找到Jar。

方案2:通过Bazel Runfiles机制获取绝对路径(更可靠)

如果不想依赖相对路径,可以利用Bazel的Runfiles环境变量动态获取Jar的绝对路径,彻底避免路径依赖问题。

修改C++代码:

#include <cstdlib>
#include <string>

// ... 其他JNI初始化代码

const char* runfiles_dir = std::getenv("RUNFILES_DIR");
if (runfiles_dir != nullptr) {
    // 替换为你的Bazel工作区名称(WORKSPACE文件中的name字段,或项目根目录名)
    std::string jar_path = std::string(runfiles_dir) + "/your_workspace_name/JavaNativeInterface.jar";
    options[1].optionString = const_cast<char*>(jar_path.c_str());
} else {
    // 兼容非Bazel运行场景, fallback到相对路径
    options[1].optionString = (char*)"-Djava.class.path=.:JavaNativeInterface.jar";
}

这种方式无论二进制在哪个目录运行,只要是Bazel构建的产物,都能通过RUNFILES_DIR准确定位到Jar文件。

关于genrule失效的说明

如果之前用genrule复制Jar,必须确保genrule的输出被cc_binary的data字段引用,否则Bazel不会把生成的Jar同步到二进制目录。比如正确的genrule用法:

genrule(
    name = "copy_jar",
    srcs = ["JavaNativeInterface.jar"],
    outs = ["copied_jar.jar"],
    cmd = "cp $< $@",
)

cc_binary(
    name = "jni_app",
    srcs = ["main.cpp"],
    data = [":copy_jar"], # 引用genrule的输出产物
    # 其他配置...
)

但这种方式其实没必要,直接用方案1的data依赖原Jar更简洁高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:15:03