15

我正在使用Swig为 C 库生成 Java 绑定。构建系统是用CMake编写的,以实现平台中立。我希望生成一个包含 Java 绑定的 JAR 文件(即由 Swig 创建的 .java 文件编译产生的 .class 文件)。我正在尝试使用 Cmakeadd_jar()命令执行编译并生成 JAR 文件。

我的问题是 Swig 在构建时生成了一组 Java 文件,但在执行cmakeadd_jar()时需要一个源文件列表。我目前正在使用 UNIX 通配符(按字面意思传递给 javac 命令行)解决这个问题。

# How do I avoid the shell wildcard?
add_jar(ExampleJNI ${CMAKE_SWIG_OUTDIR}/*.java)

有没有更好的办法?

我在下面包含一个完整的示例(由三个文件组成)来说明我的方法。如果您想自己尝试,请将三个文件放在一个目录中,然后调用cmake . ; make VERBOSE=1.

CMakeLists.txt

cmake_minimum_required (VERSION 2.8)
find_package(Swig REQUIRED)
find_package(Java REQUIRED)
find_package(JNI REQUIRED)
include(UseJava)
include(UseSWIG)

project (Example)

add_library (Example example.c)

set(CMAKE_SWIG_FLAGS -package org.mycompany)
set(CMAKE_SWIG_OUTDIR ${CMAKE_CURRENT_BINARY_DIR}/src/main/java/org/mycompany)

swig_add_module(ExampleSWIG java example.i)
include_directories(${JNI_INCLUDE_DIRS})

swig_link_libraries(ExampleSWIG Example)

# How do I avoid the wildcard?
add_jar(ExampleJNI ${CMAKE_SWIG_OUTDIR}/*.java)

add_dependencies(ExampleJNI ExampleSWIG)

例子.c

int foo() {
  return 0;
}

例子.i

%module example

%inline %{
    extern int    foo();
%}

我在用:

  • cmake 版本 2.8.10.2
  • Java版本“1.6.0_37”
  • SWIG 版本 2.0.9
  • Mac OS X 达尔文内核版本 12.2.0
4

2 回答 2

10

这篇文章很旧,但我今天遇到了同样的问题并找到了一个很好的解决方案。

我目前的方法区分buildsystem generation timebuild-time。而不是使用通配符(在 Windows 上似乎不适用于 add_jar)。我使用add_custom_command()在build-time生成带有生成的 java 类的 JAR 。我在构建系统生成时知道这个 JAR 的名称。所以我可以使用名称作为 add_jar() 函数的 INCLUDE_JAR 参数。我将包含由 SWIG 生成的 java 文件的 JAR 称为Native.jar

这是一个如何实现 CMake + Java + SWIG 的示例

首先我们需要找到必要的包:

FIND_PACKAGE(SWIG REQUIRED)
FIND_PACKAGE(JNI REQUIRED)
FIND_PACKAGE(Java REQUIRED)
INCLUDE(UseSWIG)
INCLUDE(UseJava)

然后我们需要定义我们的 SWIG 模块:

SET(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/java")
SET_PROPERTY(SOURCE "native-interface.i" PROPERTY CPLUSPLUS ON)
SWIG_ADD_MODULE(Native java "native-interface.i" 
    "algorithm.hpp"
    "algorithm-listener.hpp"
    "simple-methods.hpp" "simple-methods.cpp"
    )
TARGET_INCLUDE_DIRECTORIES(Native
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
    PRIVATE ${JAVA_INCLUDE_PATH}
    PRIVATE ${JAVA_INCLUDE_PATH2})

如您所见,我使用java子目录来存储 java 文件。我还将为类文件添加一个子目录,然后注册 POST_BUILD 事件来构建Native.jar

FILE(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/classes")
ADD_CUSTOM_COMMAND(TARGET Native POST_BUILD
    COMMAND "${Java_JAVAC_EXECUTABLE}" -d classes java/*.java
    COMMAND "${Java_JAR_EXECUTABLE}" -cfM Native.jar -C classes .
    )
# Store Path to native JAR in variable:
SET(NATIVE_JAR "${CMAKE_CURRENT_BINARY_DIR}/Native.jar")

在下一步中,我们将使用 add_jar() 函数生成一个 java 项目:

ADD_JAR(ConsoleApp 
    SOURCES "NativeInvoker.java"
    INCLUDE_JARS ${NATIVE_JAR})
SET(CMAKE_JAVA_COMPILE_FLAGS "-source" "1.8" "-target" "1.8")

如果您为您的项目使用不同的文件夹(例如在一个子目录中有本地文件,而在另一个子目录中有 java 的东西)。您必须将 Native.dll 复制到与您的 java 应用程序相同的文件夹中,或者确保它可以被 Java 找到。要在 CMake 中执行此操作,您可以再次使用add_custom_command()

ADD_CUSTOM_COMMAND(TARGET ConsoleApp POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Native> ${CMAKE_CURRENT_BINARY_DIR})

希望这对你们很多人有帮助。

问候蒂姆

于 2015-07-31T15:45:51.623 回答
0

您可以尝试使用文件通配符:

FILE(GLOB SWIG_JAVA_FILES ${CMAKE_SWIG_OUTDIR}/*.java)
add_jar(ExampleJNI ${SWIG_JAVA_FILES})
于 2014-07-31T07:57:39.427 回答