在 Cmake 中使用 Swig 不正确 link Java
Using Swig in Cmake doesn't link Java properly
我正在尝试 link 一个非常简单的测试 C 库 Java,使用 Swig 和 Cmake(项目需要)。当我 运行 手动操作时一切正常:
$ swig -java AMItest.i
$ gcc -fPIC -c AMItest.c AMItest_wrap.c -I/usr/lib/jvm/java-11-openjdk-amd64/include -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux
$ gcc -shared AMItest.o AMItest_wrap.o -W -o libAMItest_swig.so
$ javac main.java
$ LD_LIBRARY_PATH=. java main
我的cmake:
cmake_minimum_required(VERSION 3.11)
enable_language(C)
project(AMItest)
set(CMAKE_C_FLAGS "-ggdb -O0 -Wall -Wextra -pedantic -std=gnu11 -fdiagnostics-color=always -Wno-unused-function")
find_package(SWIG REQUIRED COMPONENTS java)
include(${SWIG_USE_FILE})
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS} .)
swig_add_library(AMItest_swig LANGUAGE java SOURCES AMItest.i)
# Optional below
find_package(Java REQUIRED)
add_custom_command(TARGET AMItest_swig COMMAND javac main.java MAIN_DEPENDENCY main.java DEPENDS libAMItest_swig.so BYPRODUCTS main.class)
当我尝试 运行:
$ cmake . &7 make && LD_LIBRARY_PATH=. java main
java: symbol lookup error: libAMItest_swig.so: undefined symbol: AMItest
$ nm libAMItest_swig.so | grep AMItest
U AMItest
0000000000003089 T Java_AMItestJNI_AMItest
我的main.java:
public class main {
public static void main(String argv[]) {
System.loadLibrary("AMItest_swig"); // File is libAMItest_swig.so
int size = 11;
double[] myArray = new double[size];
System.out.println(AMItest.AMItest(myArray, 10, 20));
...
}
}
最后是我的 AMItest.h(C 代码在这里并不相关):
extern int AMItest(double *Array, int Start, int End);
我很确定它来自编译 C 代码的一些差异,但是使用 make VERBOSE=1
将行与 cc
进行比较不起作用,因为差异太多。我可能需要一些选项或包含一些库。但是哪个以及如何?
像这样将 AMItest.c
添加到 swig_add_library 时:
swig_add_library(AMItest_swig LANGUAGE java SOURCES AMItest.i AMItest.c)
以及替换行:
add_custom_command(TARGET AMItest_swig COMMAND javac main.java MAIN_DEPENDENCY main.java DEPENDS libAMItest_swig.so BYPRODUCTS main.class)
与:
include(UseJava)
add_jar(
Main
SOURCES main.java
ENTRY_POINT main
)
add_dependencies(Main AMItest_swig)
那么可以这样调用:
java -jar Main.jar
并且数字输出正确,这意味着动态 Link 库构建正确。
总结一下:您稍加修改的 CMakeLists.txt 将如下所示:
cmake_minimum_required(VERSION 3.11)
enable_language(C)
project(AMItest)
set(CMAKE_C_FLAGS "-ggdb -O0 -Wall -Wextra -pedantic -std=gnu11 -fdiagnostics-color=always -Wno-unused-function")
find_package(SWIG REQUIRED COMPONENTS java)
include(${SWIG_USE_FILE})
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS} .)
swig_add_library(AMItest_swig LANGUAGE java SOURCES AMItest.i AMItest.c)
# Optional below
find_package(Java REQUIRED)
include(UseJava)
add_jar(
Main
SOURCES main.java
ENTRY_POINT main
)
add_dependencies(Main AMItest_swig)
我正在尝试 link 一个非常简单的测试 C 库 Java,使用 Swig 和 Cmake(项目需要)。当我 运行 手动操作时一切正常:
$ swig -java AMItest.i
$ gcc -fPIC -c AMItest.c AMItest_wrap.c -I/usr/lib/jvm/java-11-openjdk-amd64/include -I/usr/lib/jvm/java-11-openjdk-amd64/include/linux
$ gcc -shared AMItest.o AMItest_wrap.o -W -o libAMItest_swig.so
$ javac main.java
$ LD_LIBRARY_PATH=. java main
我的cmake:
cmake_minimum_required(VERSION 3.11)
enable_language(C)
project(AMItest)
set(CMAKE_C_FLAGS "-ggdb -O0 -Wall -Wextra -pedantic -std=gnu11 -fdiagnostics-color=always -Wno-unused-function")
find_package(SWIG REQUIRED COMPONENTS java)
include(${SWIG_USE_FILE})
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS} .)
swig_add_library(AMItest_swig LANGUAGE java SOURCES AMItest.i)
# Optional below
find_package(Java REQUIRED)
add_custom_command(TARGET AMItest_swig COMMAND javac main.java MAIN_DEPENDENCY main.java DEPENDS libAMItest_swig.so BYPRODUCTS main.class)
当我尝试 运行:
$ cmake . &7 make && LD_LIBRARY_PATH=. java main
java: symbol lookup error: libAMItest_swig.so: undefined symbol: AMItest
$ nm libAMItest_swig.so | grep AMItest
U AMItest
0000000000003089 T Java_AMItestJNI_AMItest
我的main.java:
public class main {
public static void main(String argv[]) {
System.loadLibrary("AMItest_swig"); // File is libAMItest_swig.so
int size = 11;
double[] myArray = new double[size];
System.out.println(AMItest.AMItest(myArray, 10, 20));
...
}
}
最后是我的 AMItest.h(C 代码在这里并不相关):
extern int AMItest(double *Array, int Start, int End);
我很确定它来自编译 C 代码的一些差异,但是使用 make VERBOSE=1
将行与 cc
进行比较不起作用,因为差异太多。我可能需要一些选项或包含一些库。但是哪个以及如何?
像这样将 AMItest.c
添加到 swig_add_library 时:
swig_add_library(AMItest_swig LANGUAGE java SOURCES AMItest.i AMItest.c)
以及替换行:
add_custom_command(TARGET AMItest_swig COMMAND javac main.java MAIN_DEPENDENCY main.java DEPENDS libAMItest_swig.so BYPRODUCTS main.class)
与:
include(UseJava)
add_jar(
Main
SOURCES main.java
ENTRY_POINT main
)
add_dependencies(Main AMItest_swig)
那么可以这样调用:
java -jar Main.jar
并且数字输出正确,这意味着动态 Link 库构建正确。
总结一下:您稍加修改的 CMakeLists.txt 将如下所示:
cmake_minimum_required(VERSION 3.11)
enable_language(C)
project(AMItest)
set(CMAKE_C_FLAGS "-ggdb -O0 -Wall -Wextra -pedantic -std=gnu11 -fdiagnostics-color=always -Wno-unused-function")
find_package(SWIG REQUIRED COMPONENTS java)
include(${SWIG_USE_FILE})
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS} .)
swig_add_library(AMItest_swig LANGUAGE java SOURCES AMItest.i AMItest.c)
# Optional below
find_package(Java REQUIRED)
include(UseJava)
add_jar(
Main
SOURCES main.java
ENTRY_POINT main
)
add_dependencies(Main AMItest_swig)