From c3f882f90540883782e6742c03707b96511805d3 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 22 Oct 2020 20:01:06 -0700 Subject: [PATCH] util: Embed the JNI library (.so) in the jar file for the gem5 ops. This makes it easier to manage the java wrapper since there's only one file. This change also splits up the command builder which builds the java jar since we need to run one step which produces the .h, then a second step to build the library, and then finally the step that produces the jar. The first step is left as a command builder since the scons Java builder still doesn't know about the -h option, but the second step now uses the Jar builder. Change-Id: I76e2e5e86bb3153f2ba69a75ad94cd4e065cd33d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/28183 Reviewed-by: Gabe Black Maintainer: Gabe Black Tested-by: kokoro --- util/m5/SConstruct | 1 + util/m5/src/SConscript | 34 ++++++++++++++++++++++------------ util/m5/src/java/gem5/Ops.java | 17 ++++++++++++++++- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/util/m5/SConstruct b/util/m5/SConstruct index 242bbe7c3..6552bfb9f 100644 --- a/util/m5/SConstruct +++ b/util/m5/SConstruct @@ -79,6 +79,7 @@ if not GetOption('verbose'): main['ASPPCOMSTR'] = ComStr('ASPP') main['ARCOMSTR'] = ComStr('AR') main['RANLIBCOMSTR'] = ComStr('RANLIB') + main['JARCOMSTR'] = ComStr('JAR') def MakeAction(action, string, *args, **kwargs): def func(target, source, env, executor): diff --git a/util/m5/src/SConscript b/util/m5/src/SConscript index b3e057c7f..1105b6037 100644 --- a/util/m5/src/SConscript +++ b/util/m5/src/SConscript @@ -105,16 +105,24 @@ if env['HAVE_JAVA']: # that the javah tool exists. Java has dropped that tool in favor of a -h # option on javac which the Java builder doesn't know how to use. To get # around this, we set up our own builder which does the "right thing" here. - java_env.Command([ Dir('java').File('gem5_Ops.h'), - Dir('out').Dir('java').File('gem5Ops.jar') ], - srcs, - MakeAction([ - '${JAVAC} ${JAVACFLAGS} -d ${OUT} ' - '${SOURCES} -h ${JAVA_DIR}', - '${JAR} cvf ${TARGETS[1]} ${CLS_DIR}/*.class' ], - 'JAVA'), - CLS_DIR=Dir('out').Dir('java').Dir('gem5'), - OUT=Dir('out').Dir('java'), JAVA_DIR=Dir('java')) + jni_header = Dir('java').File('gem5_Ops.h') + + java_files = [] + class_files = [] + def check_for_java(arg, dirname, fnames): + for filename in fnames: + base, extension = os.path.splitext(filename) + if extension == '.java': + java_files.append(dirname.File(filename)) + class_files.append(dirname.File(base + '.class')) + + Dir('java').walk(check_for_java, None) + + java_env.Command([ jni_header ] + class_files, java_files, + MakeAction('${JAVAC} ${JAVACFLAGS} -d ${JAVA_DIR} ' + '${SOURCES} -h ${JAVA_DIR}', + 'JAVA'), JAVA_DIR=Dir('java')) + # Set include paths to the C headers from the JDK which scons found for us. java_env.Append(CPPPATH='${JAVAINCLUDES}') for ct in all_call_types: @@ -122,9 +130,11 @@ if env['HAVE_JAVA']: java_env.Append(CXXFLAGS=[ '-DCALL_TYPE_DEFAULT=%s' % ct.name ]) java_env.Append(CXXFLAGS=[ '-DCALL_TYPE_%s_ENABLED=%s' % (ct.name, '1' if ct.enabled else '0') ]) - java_env.SharedLibrary('out/java/gem5Ops', - [ jni ] + m5op_shared + m5_mmap_shared) + jni_lib = java_env.SharedLibrary( + 'java/gem5Ops', [ jni ] + m5op_shared + m5_mmap_shared) + java_env.Jar(Dir('out').File('gem5Ops.jar'), + jni_lib + class_files, JARCHDIR=Dir('java')) if env['HAVE_LUA51']: # diff --git a/util/m5/src/java/gem5/Ops.java b/util/m5/src/java/gem5/Ops.java index 44afad976..f6ab178db 100644 --- a/util/m5/src/java/gem5/Ops.java +++ b/util/m5/src/java/gem5/Ops.java @@ -37,6 +37,7 @@ package gem5; +import java.io.*; import java.util.*; /** @@ -53,7 +54,21 @@ public class Ops { public static final Map callTypes; static { - System.loadLibrary("gem5Ops"); + try { + File temp_lib = File.createTempFile("gem5Ops", ".so"); + temp_lib.deleteOnExit(); + + InputStream in = Ops.class.getResourceAsStream("/libgem5Ops.so"); + byte[] buffer = new byte[in.available()]; + in.read(buffer); + OutputStream out = new FileOutputStream(temp_lib); + out.write(buffer); + + System.load(temp_lib.getAbsolutePath()); + } catch (Exception e) { + throw new RuntimeException(e.getMessage()); + } + setupCallTypes(); callTypes = Collections.unmodifiableMap(_callTypes); } -- 2.30.2