cmake jar包无法执行:没有主要清单属性

cmake jar package cannot execute: no main manifest attribute

我从网上得到了一个非常简单的cmake-java项目如下:

猫HelloWorld.java

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

然后CMakeLists.txt文件:

cmake_minimum_required (VERSION 2.8)
find_package(Java REQUIRED)
include(UseJava)
enable_testing()
project (HelloWorld)
set(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8")
add_jar(HelloWorld HelloWorld.java)
get_target_property(_jarFile HelloWorld JAR_FILE)
get_target_property(_classDir HelloWorld CLASSDIR)
message(STATUS "Jar file ${_jarFile}")
message(STATUS "Class compiled to ${_classDir}")
add_test(NAME TestHelloWorld COMMAND ${Java_JAVA_EXECUTABLE} -cp ${_jarFile} HelloWorld)

我在 centos7 上 jdk 1.8 和 cmake 3.8,然后

cmake . && make -j8

有 HelloWorld.jar 文件,当 运行:

时出错
java -jar HelloWorld.jar HelloWorld

no main manifest attribute, in HelloWorld.jar

是的,里面没有主要的class定义:

$ cat META-INF/MANIFEST.MF 
Manifest-Version: 1.0
Created-By: 1.8.0_191 (Oracle Corporation)

我只是想知道如何使用cmake向MANIFEST.MF添加内容,你能帮忙解释一下吗? 非常感谢。

使用 add_jar 命令的 MANIFEST 选项添加自定义清单文件。

例如,要从当前 cmake 源目录添加清单文件,请使用:

add_jar(HelloWorld HelloWorld.java MANIFEST "${CMAKE_CURRENT_SOURCE_DIR}/MANIFEST.MF")

我遇到了完全相同的问题。

我的印象是 CMake 将根据 add_jar() 的其他输入生成清单。完全不是这样。

您负责创建清单文件,然后使用 MANIFEST 选项将 CMake 指向 add_jar()

因此,对于这个简单的 HelloWorld 示例,它可能看起来像这样:

Manifest-Version: 1.0
Created-By: YOUR NAME HERE
Main-Class: HelloWorld

为什么 Java 需要一个清单文件(当所有的 jar 在 javac 编译时已知)留给 reader 去思考。

也很重要 清单文件似乎不会自动成为 jar 目标的依赖项。您可以修改清单,然后 运行 再次“制作”,您的 jar 将不会更新为新的清单。至少这是我系统上确认的行为:

cmake 版本 3.19.7 GNU 制作 4.3 javajavac 11.0.10