2012-02-23 141 views
2

我有一个C生成文件,它从Java代码生成头文件并编译非常简单的C可执行文件。有一个我找不到的错误。当我尝试运行代码时,我得到UnsatisfiedLinkError。如何调试这个Makefile

这是生成文件的内容:

#!/usr/bin/make -f 
# 
# Makefile for native stuff 
# 

# c files to compile 
C_SOURCES := sqrt.c 

# the name of the library to build 
LIBNAME  := sqrt 

C_SOURCE_DIR := src 
C_GENSOURCE_DIR := src 

TARGET_DIR := ../../../target 
C_BUILD_DIR = $(TARGET_DIR)/native 
JAVA_BUILD_DIR = $(TARGET_DIR)/classes 

# the name of the file we build 
TARGET  = $(JAVA_BUILD_DIR)/META-INF/lib/$(LIB_PREFIX)$(LIBNAME)$(LIB_EXTN) 

# find the jdk. if this doesn't work for you, define JAVA_HOME in your 
# environment or on the make command line 
JAVA_HOME ?= /opt/jdk1.7.0_02 

# classpath for javah 
JAVAH_CLASSPATH = `cat $(TARGET_DIR)/compile-classpath` 

# tools and options 
CFLAGS = -Wall -fpic 
CPPFLAGS = -I$(C_SOURCE_DIR) -I$(C_GENSOURCE_DIR) -Iinclude \ 
    -I$(JAVA_HOME)/include 
JAVAH = /opt/jdk1.7.0_02/bin/javah 
JAVAH_FLAGS += -classpath $(JAVAH_CLASSPATH) 
JAVAH_CMD = $(JAVAH) $(JAVAH_FLAGS) $(OUTPUT_OPTION) 
LDFLAGS = -shared 
LINK.so = $(CC) $(LDFLAGS) $(LD_LIBS) 

ifdef DEBUG 
CFLAGS += -g 
LDFLAGS += -g 
endif 

# os-dependent bits 
UNAME := $(shell uname) 

ifeq ($(UNAME),Linux) 
LIB_PREFIX = lib 
LIB_EXTN = .so 
CPPFLAGS += -I$(JAVA_HOME)/include/linux 
else 
ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) 
LIB_PREFIX = 
LIB_EXTN = .dll 
CPPFLAGS += -I$(JAVA_HOME)/include/win32 
else 
f := $(error Platform $(UNAME) not supported) 
endif 
endif 

# we look in $(C_SOURCE_DIR) for c files... 
vpath %.c $(C_SOURCE_DIR) 

# convenience variables 
C_OBJFILES = $(addprefix $(C_BUILD_DIR)/,$(subst .c,.o,$(C_SOURCES))) 

# default target 
all: $(TARGET) 

# rule to compile the .c files 
$(C_BUILD_DIR)/%.o: %.c 
    @mkdir -p `dirname [email protected]` 
    $(COMPILE.c) $(OUTPUT_OPTION) $< 

# link the C objects into a shared library 
$(TARGET): $(C_OBJFILES) $(LDLIBS) 
    @mkdir -p `dirname [email protected]` 
    $(LINK.so) $(OUTPUT_OPTION) $^ 

# a rule to build the .h file with javah      
$(C_GENSOURCE_DIR)/org_DX_57_osgi_NB_27_impl_Sqrt.h: $(JAVA_BUILD_DIR)/org/DX_57/osgi/NB_27/impl/Sqrt.class 
    rm -f [email protected]     
    $(JAVAH) $(JAVAH_FLAGS) $(OUTPUT_OPTION) org.DX_57.osgi.NB_27.impl.Sqrt 

# the .o file depends on the .h file 
$(C_BUILD_DIR)/sqrt.o: $(C_GENSOURCE_DIR)/org_DX_57_osgi_NB_27_impl_Sqrt.h 

clean:: 
    rm -f $(C_OBJFILES) 
    rm -f $(TARGET) 
    rm -f $(C_BUILD_DIR)/jnirules.mak 

这里是C文件的内容:

#include "org_DX_57_osgi_NB_27_impl_Sqrt.h" 

JNIEXPORT jdouble JNICALL Java_Sqrt_sqrt 
(JNIEnv *env, jclass cls, jdouble d, jdouble tol) 
{ 

    return tol; 
} 

最良好的祝愿 彼得

+0

在'../../../ target/native'中创建'.so'吗? – hmjd 2012-02-23 21:51:21

+0

在原生文件夹中,我找到了sqrt.o.也许这是问题? – 2012-02-23 22:11:05

+0

是的,这意味着'.so'没有被正确构建,或者至少不存在。在构建目录下的任何地方是否有'.so'? – hmjd 2012-02-23 22:12:23

回答

2

UnsatisfiedLinkError意味着JVM加载失败生成文件生成的本地共享对象,或本地共享对象所依赖的.so

../../../target/native的绝对路径添加到LD_LIBRARY_PATH将使JVM能够找到.so。如果.so依赖于其他.so库,则这些.so所在的目录也将需要添加到LD_LIBRARY_PATH

编辑:的NB_27-impl/target/classes/lib

代替../../../target/native使用绝对路径。