在Cmake中使用Swig不能正确链接Java。

问题描述 投票:0回答:1

我试图用Swig将一个非常简单的测试C库和Java连接起来。 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代码时的一些差异造成的,但是比较一下这行代码和 cc 使用 make VERBOSE=1 不工作,因为有太多的差异。我可能需要一些选项或包含一些lib。但是,什么是什么,怎么做?

java c cmake swig
1个回答
1
投票

当添加 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  

数字就会正确输出,这意味着动态链接库的建立是正确的。

总结一下。你稍加修改的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)
© www.soinside.com 2019 - 2024. All rights reserved.