From b4232c43a4b2a73f2710c53f910fdba68409b79f Mon Sep 17 00:00:00 2001
From: picomeg <megordon5@gmail.com>
Date: Tue, 19 Nov 2019 16:23:51 +0000
Subject: [PATCH] java and javah build, but c shared library build fail as
 unable to find includes like jni.h

---
 .gitignore                                    |  1 +
 Makefile                                      |  2 +-
 SConstruct                                    |  2 +-
 src/bindings/jni/ConfigureJNI.py              | 94 +++++++++++++++++++
 {jni => src/bindings/jni}/Example.java        |  0
 {jni => src/bindings/jni}/Makefile            | 11 ++-
 {jni => src/bindings/jni}/NOTES               |  0
 src/bindings/jni/SConscript                   | 39 ++++++++
 .../com/upstandinghackers/hammer/Action.java  |  0
 .../com/upstandinghackers/hammer/Hammer.java  |  0
 .../upstandinghackers/hammer/ParseResult.java |  0
 .../upstandinghackers/hammer/ParsedToken.java |  0
 .../com/upstandinghackers/hammer/Parser.java  |  0
 .../upstandinghackers/hammer/Predicate.java   |  0
 .../com_upstandinghackers_hammer_Hammer.c     |  0
 ...com_upstandinghackers_hammer_ParseResult.c |  0
 ...com_upstandinghackers_hammer_ParsedToken.c |  0
 .../com_upstandinghackers_hammer_Parser.c     |  0
 {jni => src/bindings/jni}/jhammer.h           |  0
 19 files changed, 142 insertions(+), 7 deletions(-)
 create mode 100644 src/bindings/jni/ConfigureJNI.py
 rename {jni => src/bindings/jni}/Example.java (100%)
 rename {jni => src/bindings/jni}/Makefile (87%)
 rename {jni => src/bindings/jni}/NOTES (100%)
 create mode 100644 src/bindings/jni/SConscript
 rename {jni => src/bindings/jni}/com/upstandinghackers/hammer/Action.java (100%)
 rename {jni => src/bindings/jni}/com/upstandinghackers/hammer/Hammer.java (100%)
 rename {jni => src/bindings/jni}/com/upstandinghackers/hammer/ParseResult.java (100%)
 rename {jni => src/bindings/jni}/com/upstandinghackers/hammer/ParsedToken.java (100%)
 rename {jni => src/bindings/jni}/com/upstandinghackers/hammer/Parser.java (100%)
 rename {jni => src/bindings/jni}/com/upstandinghackers/hammer/Predicate.java (100%)
 rename {jni => src/bindings/jni}/com_upstandinghackers_hammer_Hammer.c (100%)
 rename {jni => src/bindings/jni}/com_upstandinghackers_hammer_ParseResult.c (100%)
 rename {jni => src/bindings/jni}/com_upstandinghackers_hammer_ParsedToken.c (100%)
 rename {jni => src/bindings/jni}/com_upstandinghackers_hammer_Parser.c (100%)
 rename {jni => src/bindings/jni}/jhammer.h (100%)

diff --git a/.gitignore b/.gitignore
index 8101f080..1a1ad509 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,4 @@ libhammer.pc
 *.os
 *.pyc
 *.gem
+/bin/
diff --git a/Makefile b/Makefile
index 09aa037b..37d80857 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 # and kick off a recursive make
 # Also, "make src/all" turns into "make -C src all"
 
-SUBDIRS = src examples jni
+SUBDIRS = src examples src/bindings/jni
 
 include config.mk
 TOPLEVEL=.
diff --git a/SConstruct b/SConstruct
index 8aa8c816..ecc86df3 100644
--- a/SConstruct
+++ b/SConstruct
@@ -14,7 +14,7 @@ if platform.system() == 'Windows':
 vars = Variables(None, ARGUMENTS)
 vars.Add(PathVariable('DESTDIR', "Root directory to install in (useful for packaging scripts)", None, PathVariable.PathIsDirCreate))
 vars.Add(PathVariable('prefix', "Where to install in the FHS", "/usr/local", PathVariable.PathAccept))
-vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['cpp', 'dotnet', 'perl', 'php', 'python', 'ruby']))
+vars.Add(ListVariable('bindings', 'Language bindings to build', 'none', ['cpp', 'dotnet', 'jni', 'perl', 'php', 'python', 'ruby']))
 vars.Add('python', 'Python interpreter', 'python')
 
 tools = ['default', 'scanreplace']
diff --git a/src/bindings/jni/ConfigureJNI.py b/src/bindings/jni/ConfigureJNI.py
new file mode 100644
index 00000000..9a94a870
--- /dev/null
+++ b/src/bindings/jni/ConfigureJNI.py
@@ -0,0 +1,94 @@
+#!python 
+
+from __future__ import absolute_import, division, print_function
+
+import os
+import sys
+
+def walkDirs(path):
+    """helper function to get a list of all subdirectories"""
+    def addDirs(pathlist, dirname, names):
+        """internal function to pass to os.walk"""
+        print("in addDirs")
+        for n in names:
+            f = os.path.join(dirname, n)
+            if os.path.isdir(f):
+                pathlist.append(f)
+    pathlist = [path]
+    os.walk(path, addDirs, pathlist)
+    print(pathlist)
+    return pathlist
+
+def ConfigureJNI(env):
+    """Configure the given environment for compiling Java Native Interface
+       c or c++ language files."""
+    
+    print( "Configuring JNI includes")
+
+    if not env.get('JAVAC'):
+        print( "The Java compiler must be installed and in the current path.")
+        return 0
+
+    # first look for a shell variable called JAVA_HOME
+    java_base = os.environ.get('JAVA_HOME')
+    if not java_base:
+        if sys.platform == 'darwin':
+            # Apple's OS X has its own special java base directory
+            java_base = '/System/Library/Frameworks/JavaVM.framework'
+        else:
+            # Search for the java compiler
+            print ("JAVA_HOME environment variable is not set. Searching for java... ")
+            jcdir = os.path.dirname(env.WhereIs('javac'))
+            if not jcdir:
+                print( "not found.")
+                return 0
+            # assuming the compiler found is in some directory like
+            # /usr/jdkX.X/bin/javac, java's home directory is /usr/jdkX.X
+            java_base = os.path.join(jcdir, "..")
+            print( "found.")
+
+    if sys.platform == 'cygwin':
+        # Cygwin and Sun Java have different ideas of how path names
+        # are defined. Use cygpath to convert the windows path to
+        # a cygwin path. i.e. C:\jdkX.X to /cygdrive/c/jdkX.X
+        java_base = os.popen("cygpath -up '"+java_base+"'").read().replace( \
+                 '\n', '')
+
+    if sys.platform == 'darwin':
+        # Apple does not use Sun's naming convention
+        java_headers = [os.path.join(java_base, 'Headers')]
+        java_libs = [os.path.join(java_base, 'Libraries')]
+    else:
+        # windows and linux
+        java_headers = [os.path.join(java_base, 'include')]
+        java_libs = [os.path.join(java_base, 'lib')]
+        # Sun's windows and linux JDKs keep system-specific header
+        # files in a sub-directory of include
+        if java_base == '/usr' or java_base == '/usr/local':
+            # too many possible subdirectories. Just use defaults
+            java_headers.append(os.path.join(java_headers[0], 'win32'))
+            java_headers.append(os.path.join(java_headers[0], 'linux'))
+            java_headers.append(os.path.join(java_headers[0], 'solaris'))
+        else:
+            # add all subdirs of 'include'. The system specific headers
+            # should be in there somewhere
+            java_headers = walkDirs(java_headers[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)
+    env.Append(LIBPATH = java_libs)
+
+    # add any special platform-specific compilation or linking flags
+    if sys.platform == 'darwin':
+        env.Append(SHLINKFLAGS = '-dynamiclib -framework JavaVM')
+        env['SHLIBSUFFIX'] = '.jnilib'
+    elif sys.platform == 'cygwin':
+        env.Append(CCFLAGS = '-mno-cygwin')
+        env.Append(SHLINKFLAGS = '-mno-cygwin -Wl,--kill-at')
+
+    # Add extra potentially useful environment variables
+    env['JAVA_HOME'] = java_base
+    env['JNI_CPPPATH'] = java_headers
+    env['JNI_LIBPATH'] = java_libs
+    return 1
\ No newline at end of file
diff --git a/jni/Example.java b/src/bindings/jni/Example.java
similarity index 100%
rename from jni/Example.java
rename to src/bindings/jni/Example.java
diff --git a/jni/Makefile b/src/bindings/jni/Makefile
similarity index 87%
rename from jni/Makefile
rename to src/bindings/jni/Makefile
index 85be9733..ea257872 100644
--- a/jni/Makefile
+++ b/src/bindings/jni/Makefile
@@ -5,17 +5,18 @@ CSOURCES := com_upstandinghackers_hammer_Hammer.c com_upstandinghackers_hammer_P
 # ls *.h *.o *.so com/upstandinghackers/hammer/*.class | grep -v jhammer.h | tr '\n' ' '; replace single $ with $$
 OUTPUTS := com/upstandinghackers/hammer/Action.class com/upstandinghackers/hammer/Hammer.class com_upstandinghackers_hammer_Hammer.h com_upstandinghackers_hammer_Hammer.o com/upstandinghackers/hammer/Hammer\$TokenType.class com_upstandinghackers_hammer_Hammer_TokenType.h com/upstandinghackers/hammer/ParsedToken.class com_upstandinghackers_hammer_ParsedToken.h com_upstandinghackers_hammer_ParsedToken.o com/upstandinghackers/hammer/Parser.class com/upstandinghackers/hammer/ParseResult.class com_upstandinghackers_hammer_ParseResult.h com_upstandinghackers_hammer_ParseResult.o com_upstandinghackers_hammer_Parser.h com_upstandinghackers_hammer_Parser.o com/upstandinghackers/hammer/Predicate.class libjhammer.so
 
-TOPLEVEL := ../
+TOPLEVEL := ../../../
 
 JC=javac
 JH=javah
 CP=com/upstandinghackers/hammer
 PACKAGE=com.upstandinghackers.hammer
 
-include ../common.mk
+include ../../../common.mk
 
-JNI_INCLUDE := /usr/lib/jvm/java-6-openjdk/include/
-CFLAGS += -fPIC -I. -I $(TOPLEVEL)/src/ -I jni -I $(JNI_INCLUDE) 
+JNI_INCLUDE := /usr/lib/jvm/java-8-oracle/include/
+JNI_INCLUDE_LINUX := /usr/lib/jvm/java-8-oracle/include/linux
+CFLAGS += -fPIC -I. -I $(TOPLEVEL)/src/ -I jni -I $(JNI_INCLUDE) -I $(JNI_INCLUDE_LINUX)
 
 %.java: $(call ifsilent,| $(HUSH))
 	$(call hush, "Compiling Java source $@") $(JC) $(CP)/$@
@@ -23,7 +24,7 @@ CFLAGS += -fPIC -I. -I $(TOPLEVEL)/src/ -I jni -I $(JNI_INCLUDE)
 all: javacc prepare compile link
 
 link: compile
-	$(call hush, "Generating libjhammer.so") $(CC) -shared $(CFLAGS) -o libjhammer.so *.o ../src/*.o ../src/backends/*.o ../src/parsers/*.o
+	$(call hush, "Generating libjhammer.so") $(CC) -shared $(CFLAGS) -o libjhammer.so *.o ../../../src/*.o ../../../src/backends/*.o ../../../src/parsers/*.o
 
 $(CSOURCES): prepare
 	$(call hush, "Compiling $@") $(CC) -c $(CFLAGS) $@
diff --git a/jni/NOTES b/src/bindings/jni/NOTES
similarity index 100%
rename from jni/NOTES
rename to src/bindings/jni/NOTES
diff --git a/src/bindings/jni/SConscript b/src/bindings/jni/SConscript
new file mode 100644
index 00000000..7e506832
--- /dev/null
+++ b/src/bindings/jni/SConscript
@@ -0,0 +1,39 @@
+# -*- python -*-
+
+from __future__ import absolute_import, division, print_function
+
+import os, os.path
+import sys
+Import('env libhammer_shared testruns targets')
+from src.bindings.jni.ConfigureJNI import ConfigureJNI
+
+javaenv = env.Clone()
+
+if not ConfigureJNI(javaenv):
+    print("Java Native Interface is required... Exiting")
+    Exit(0)
+
+
+javaenv.Append(CPPPATH=[".", "/usr/lib/jvm/java-8-oracle/include", "/usr/lib/jvm/java-8-oracle/include/linux", "../.."],
+              LIBS=['hammer'],
+              LIBPATH=["../.."])
+
+# compile java classes
+jni_classes = javaenv.Java(".", "#src/bindings/jni/com")
+
+print(jni_classes)
+jni_headers = javaenv.JavaH(".", jni_classes)
+print(jni_headers)
+Default(jni_classes)
+Default(jni_headers)
+
+#print(javaenv.Dump())
+
+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)
+Default(libjhammer_shared)
+
diff --git a/jni/com/upstandinghackers/hammer/Action.java b/src/bindings/jni/com/upstandinghackers/hammer/Action.java
similarity index 100%
rename from jni/com/upstandinghackers/hammer/Action.java
rename to src/bindings/jni/com/upstandinghackers/hammer/Action.java
diff --git a/jni/com/upstandinghackers/hammer/Hammer.java b/src/bindings/jni/com/upstandinghackers/hammer/Hammer.java
similarity index 100%
rename from jni/com/upstandinghackers/hammer/Hammer.java
rename to src/bindings/jni/com/upstandinghackers/hammer/Hammer.java
diff --git a/jni/com/upstandinghackers/hammer/ParseResult.java b/src/bindings/jni/com/upstandinghackers/hammer/ParseResult.java
similarity index 100%
rename from jni/com/upstandinghackers/hammer/ParseResult.java
rename to src/bindings/jni/com/upstandinghackers/hammer/ParseResult.java
diff --git a/jni/com/upstandinghackers/hammer/ParsedToken.java b/src/bindings/jni/com/upstandinghackers/hammer/ParsedToken.java
similarity index 100%
rename from jni/com/upstandinghackers/hammer/ParsedToken.java
rename to src/bindings/jni/com/upstandinghackers/hammer/ParsedToken.java
diff --git a/jni/com/upstandinghackers/hammer/Parser.java b/src/bindings/jni/com/upstandinghackers/hammer/Parser.java
similarity index 100%
rename from jni/com/upstandinghackers/hammer/Parser.java
rename to src/bindings/jni/com/upstandinghackers/hammer/Parser.java
diff --git a/jni/com/upstandinghackers/hammer/Predicate.java b/src/bindings/jni/com/upstandinghackers/hammer/Predicate.java
similarity index 100%
rename from jni/com/upstandinghackers/hammer/Predicate.java
rename to src/bindings/jni/com/upstandinghackers/hammer/Predicate.java
diff --git a/jni/com_upstandinghackers_hammer_Hammer.c b/src/bindings/jni/com_upstandinghackers_hammer_Hammer.c
similarity index 100%
rename from jni/com_upstandinghackers_hammer_Hammer.c
rename to src/bindings/jni/com_upstandinghackers_hammer_Hammer.c
diff --git a/jni/com_upstandinghackers_hammer_ParseResult.c b/src/bindings/jni/com_upstandinghackers_hammer_ParseResult.c
similarity index 100%
rename from jni/com_upstandinghackers_hammer_ParseResult.c
rename to src/bindings/jni/com_upstandinghackers_hammer_ParseResult.c
diff --git a/jni/com_upstandinghackers_hammer_ParsedToken.c b/src/bindings/jni/com_upstandinghackers_hammer_ParsedToken.c
similarity index 100%
rename from jni/com_upstandinghackers_hammer_ParsedToken.c
rename to src/bindings/jni/com_upstandinghackers_hammer_ParsedToken.c
diff --git a/jni/com_upstandinghackers_hammer_Parser.c b/src/bindings/jni/com_upstandinghackers_hammer_Parser.c
similarity index 100%
rename from jni/com_upstandinghackers_hammer_Parser.c
rename to src/bindings/jni/com_upstandinghackers_hammer_Parser.c
diff --git a/jni/jhammer.h b/src/bindings/jni/jhammer.h
similarity index 100%
rename from jni/jhammer.h
rename to src/bindings/jni/jhammer.h
-- 
GitLab