From 2fd2a1d8c987de63b99e0b2ca83b5f496f174c2d Mon Sep 17 00:00:00 2001 From: Kragen Javier Sitaker <kragen@canonical.org> Date: Thu, 21 Nov 2019 03:26:28 -0300 Subject: [PATCH] Get JNI shared library to build with SCons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was a real adventure since I didn’t know anything about SCons, and I can’t say that I’m fond of scons after it, but it does seem to work. There were two obstacles. First, the ConfigureJNI module doesn’t successfully configure the JNI on my system because it was expecting to find `JAVA_HOME` in .., so I added a little code to notice if it’s failing to find a place where `jni.h` exists. (And on my system I did `export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64` before running it, but your pathnames will vary.) There was a hardcoded pathname in SConscript, presumably as an interim debugging measure, which I removed. A reasonable default to try on Debian-derived systems such as Ubuntu and LinuxMint might be `/usr/lib/jvm/default-java`, but I didn’t implement that. Second, in SConscript, the JNI include directories were being stuck into a `javaenv` SCons environment object, which was used to build the Java classes providing the Java interfaces to Hammer, but not the C files containing the native methods themselves. Consequently the compiler couldn’t find the JDK JNI headers when it tried to compile the C code into a shared library. It might make sense to use `javaenv` to compile that shared library, but in case it doesn’t, I cloned the default environment with an extra include directory. I hope this is soon enough to be helpful! --- src/bindings/jni/ConfigureJNI.py | 5 +++++ src/bindings/jni/SConscript | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bindings/jni/ConfigureJNI.py b/src/bindings/jni/ConfigureJNI.py index 9a94a870..573bd682 100644 --- a/src/bindings/jni/ConfigureJNI.py +++ b/src/bindings/jni/ConfigureJNI.py @@ -74,6 +74,11 @@ def ConfigureJNI(env): # should be in there somewhere java_headers = walkDirs(java_headers[0]) + if not any(os.path.exists(os.path.join(path, 'jni.h')) + for path in java_headers): + print("Can't find jni.h in %s" % java_headers) + return 0 + # add Java's include and lib directory to the environment java_headers.append(os.path.join(java_headers[0], 'linux')) env.Append(CPPPATH = java_headers) diff --git a/src/bindings/jni/SConscript b/src/bindings/jni/SConscript index 7e506832..3b454b99 100644 --- a/src/bindings/jni/SConscript +++ b/src/bindings/jni/SConscript @@ -14,7 +14,7 @@ if not ConfigureJNI(javaenv): Exit(0) -javaenv.Append(CPPPATH=[".", "/usr/lib/jvm/java-8-oracle/include", "/usr/lib/jvm/java-8-oracle/include/linux", "../.."], +javaenv.Append(CPPPATH=[".", "../.."], LIBS=['hammer'], LIBPATH=["../.."]) @@ -29,11 +29,12 @@ Default(jni_headers) #print(javaenv.Dump()) +shlib_env = env.Clone(CPPPATH=javaenv['JNI_CPPPATH'] + ['../..']) csources = ['com_upstandinghackers_hammer_Hammer.c', 'com_upstandinghackers_hammer_ParsedToken.c', 'com_upstandinghackers_hammer_Parser.c', 'com_upstandinghackers_hammer_ParseResult.c'] -libjhammer_shared = env.SharedLibrary('libjhammer', csources) +libjhammer_shared = shlib_env.SharedLibrary('libjhammer', csources) Default(libjhammer_shared) -- GitLab