仅为所需平台构建带有二进制文件的 jar (javacpp)

Build jar with binaries for required platform only (javacpp)

我想为 tesseract 构建一个 fat jar。使用以下构建设置,我得到一个大约 68 MB 的 jar,其中包含所有支持平台的依赖项:

dependencies {
    implementation group: 'org.bytedeco', name: 'tesseract-platform', version: '4.1.1-1.5.3'
}
jar {
    manifest { attributes 'Main-Class': 'BasicExample' }
    from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
}

为了减小这个大小,我尝试只包含我的平台的依赖项 this guideline - but without success, see also this and @Samuel Audet's answer to it (I want to stick with gradle). Therefore I decided to manually include only the required dependencies from the POM file:

dependencies {
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3'
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3', classifier: 'windows-x86_64'
    implementation group: 'org.bytedeco', name: 'leptonica', version: '1.79.0-1.5.3', classifier: 'windows-x86_64'
}

这将 jar 的大小减少到大约 7 MB,并且工作正常(至少对于 basic example)。尽管如此,我还是收到了警告:

Warning: Could not load ...: java.lang.UnsatisfiedLinkError: no jnijavacpp in java.library.path: ...

比较这两个罐子,我发现小罐子缺少 lib 路径以及所有 so 库以及 header、cmake 和 pkgconfig 文件,我认为这是警告的原因。

所以我的问题是:

  1. 如果这些文件显然不是 运行 jar 所必需的,为什么它们通常包含在内?
  2. 如何在保持小罐子大小的同时防止这些警告?

当然也欢迎使用任何其他方式构建仅包含一个平台所需依赖项的 jar。

我必须稍微更新一下该指南,感谢您的报告!我们现在还需要 javacpp-platform,在这种情况下,它会为 windows-x86_64 提供类似的东西:

dependencies {
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3'
    implementation group: 'org.bytedeco', name: 'tesseract', version: '4.1.1-1.5.3', classifier: 'windows-x86_64'
    implementation group: 'org.bytedeco', name: 'leptonica', version: '1.79.0-1.5.3', classifier: 'windows-x86_64'
    implementation group: 'org.bytedeco', name: 'javacpp', version: '1.5.3', classifier: 'windows-x86_64'
}

如本期所述,这需要解决加载时的一些问题:
https://github.com/bytedeco/javacv/issues/1305

更新:现在可以使用 Gradle JavaCPP 以这种方式更轻松地完成此操作:

plugins {
    id 'java-library'
    id 'org.bytedeco.gradle-javacpp-platform' version "$javacppVersion"
}

// We can set this on the command line too this way: -PjavacppPlatform=linux-x86_64,macosx-x86_64,windows-x86_64,etc
ext {
    javacppPlatform = 'linux-x86_64,macosx-x86_64,windows-x86_64,etc' // defaults to Loader.getPlatform()
}

dependencies {
    api "org.bytedeco:tesseract-platform:$tesseractVersion"
}