15

Swigを使用して、C ライブラリの Java バインディングを作成しています。ビルド システムは、プラットフォームの中立性を実現するためにCMakeで記述されています。Java バインディングを含む JAR ファイル (つまり、Swig によって作成された .java ファイルをコンパイルした結果の .class ファイル) を作成したいと考えています。Cmakeadd_jar()コマンドを使用してコンパイルを実行し、JAR ファイルを生成しようとしています。

私の問題は、Swig がビルド時に一連の Java ファイルを生成するが、cmakeの実行add_jar()時にソース ファイルのリストが必要なことです。現在、UNIX ワイルドカード (javac コマンドラインに文字どおり渡される) を使用して問題を回避しています。

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

より良い方法はありますか?

私のアプローチを示す完全な例 (3 つのファイルで構成される) を以下に示します。自分で試してみたい場合は、3 つのファイルをディレクトリに配置してから、 を呼び出し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)

example.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 Darwin カーネル バージョン 12.2.0
4

2 に答える 2

10

この投稿は古いですが、今日も同じ問題があり、良い解決策を見つけました。

私の現在のアプローチでは、 buildsystem 生成時間build-timeを区別しています。ワイルドカードを使用する代わりに (Windows の add_jar では機能しないようです)。add_custom_command()を使用して、ビルド時に生成された Java クラスで JAR を生成します。buildsystem の生成時にこの 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")

プロジェクトに別のフォルダーを使用する場合 (1 つのサブディレクトリにネイティブがあり、別のサブディレクトリに 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 に答える