Here's my latest patch against the SVN trunk. It allows you to say "--auto-find-jvm-dll" when building JCC:
python setup.py build --auto-find-jvm-dll install and puts that setting in the jcc/config.py file. Later, if it's set, when "jcc" is imported, it looks up the JVM location in the registry and puts it at the end of "Path". The default is off. It also correctly builds the jcc.lib file with mingw, and I added a section to the lucene Makefile for "make wininst", as well as configuration section in the Makefile for using mingw32. I've tried it with Java 6 on mingw32, and Java 5 on OS X Leopard. Bill
Index: trunk/jcc/jcc/windows.py =================================================================== --- trunk/jcc/jcc/windows.py (revision 925683) +++ trunk/jcc/jcc/windows.py (working copy) @@ -1,11 +1,8 @@ -import sys +import sys, os -global JAVAHOME -JAVAHOME = None - if sys.platform == "win32": - # figure out where the JDK lives + # figure out where the JDK and/or JRE lives try: import _winreg as wreg @@ -36,8 +33,32 @@ v, t = r.get(subname) return v - javaversion = get_registry_value(r"SOFTWARE\JavaSoft\Java Development Kit", "CurrentVersion") - JAVAHOME = get_registry_value(r"SOFTWARE\JavaSoft\Java Development Kit\%s" % javaversion, "JavaHome") + def get_jdk_root(): + try: + javaversion = get_registry_value(r"SOFTWARE\JavaSoft\Java Development Kit", "CurrentVersion") + javahome = get_registry_value(r"SOFTWARE\JavaSoft\Java Development Kit\%s" % javaversion, "JavaHome") + except: + return None + else: + return javahome + def get_jre_jvm_directory(client_or_server="client"): + try: + javaversion = get_registry_value(r"SOFTWARE\JavaSoft\Java Runtime Environment", "CurrentVersion") + jrehome = get_registry_value(r"SOFTWARE\JavaSoft\Java Runtime Environment\%s" % javaversion, "JavaHome") + except: + jrehome = None + if not jrehome: + # no JRE installed on this machine via standard installer, try JDK + path = get_jdk_root() + if os.path.exists(path): + jrehome = os.path.abspath(os.path.join(path, "jre")) + else: + jrehome = os.path.abspath(os.path.join(jrehome, "bin", client_or_server)) + if jrehome and os.path.exists(os.path.join(jrehome, "jvm.dll")): + return jrehome + return None + except: - JAVAHOME = 'c:/Program Files/Java/jdk1.6.0_18' + get_jdk_root = lambda: None + get_jre_root = lambda: None Index: trunk/jcc/jcc/__init__.py =================================================================== --- trunk/jcc/jcc/__init__.py (revision 925683) +++ trunk/jcc/jcc/__init__.py (working copy) @@ -15,14 +15,33 @@ import os, sys if sys.platform == 'win32': - from jcc.config import SHARED - if SHARED: - path = os.environ['Path'].split(os.pathsep) - eggpath = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) - if eggpath not in path: - path.insert(0, eggpath) - os.environ['Path'] = os.pathsep.join(path) + # we need to make sure the jcc DLL is found, so put it on your Path + try: + from jcc.config import SHARED, AUTO_FIND_JVM_DLL + except ImportError: + pass + else: + if SHARED: + path = os.environ['Path'].split(os.pathsep) + eggpath = os.path.abspath(os.path.dirname(os.path.dirname(__file__))) + if eggpath not in path: + path.insert(0, eggpath) + os.environ['Path'] = os.pathsep.join(path) + if AUTO_FIND_JVM_DLL: + # we'd like the JVM DLL to be found, so put it on the path at end if not + # already there + try: + from jcc.windows import get_jre_jvm_directory + jvmdir = get_jre_jvm_directory("client") + if jvmdir: + path = os.environ['Path'].split(os.pathsep) + if jvmdir not in path: + path.append(jvmdir) + os.environ['Path'] = os.pathsep.join(path) + except ImportError: + pass + if __name__ == '__main__': import jcc.__main__ else: Index: trunk/jcc/setup.py =================================================================== --- trunk/jcc/setup.py (revision 925683) +++ trunk/jcc/setup.py (working copy) @@ -10,7 +10,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import os, sys, platform, subprocess +import os, sys, platform, subprocess, imp jcc_ver = '2.5' machine = platform.machine() @@ -36,10 +36,9 @@ # separator. if sys.platform == "win32": - try: - from jcc.windows import JAVAHOME - except ImportError: - JAVAHOME = None + _jccwindows = imp.load_source("_jccwindows", os.path.join( + os.path.dirname(__file__), "jcc", "windows.py")) + JAVAHOME = _jccwindows.get_jdk_root() else: JAVAHOME = None @@ -55,6 +54,16 @@ if 'JCC_JDK' in os.environ: JDK[platform] = os.environ['JCC_JDK'] +if (not JDK[platform]) or (not os.path.isdir(JDK[platform])): + raise RuntimeError(""" + +Can't determine where the Java JDK has been installed on this machine. + +Please set the environment variable JCC_JDK to that location before +running setup.py. + +""") + INCLUDES = { 'darwin': ['%(darwin)s/Headers' %(JDK)], 'ipod': ['%(ipod)s/darwin/default' %(JDK)], @@ -64,8 +73,8 @@ '%(sunos5)s/include/solaris' %(JDK)], 'win32': ['%(win32)s/include' %(JDK), '%(win32)s/include/win32' %(JDK)], - 'mingw32': ['%(win32)s/include' %(JDK), - '%(win32)s/include/win32' %(JDK)], + 'mingw32': ['%(mingw32)s/include' %(JDK), + '%(mingw32)s/include/win32' %(JDK)], 'freebsd7': ['%(freebsd7)s/include' %(JDK), '%(freebsd7)s/include/freebsd' %(JDK)], } @@ -77,7 +86,7 @@ 'sunos5': ['-features=iddollar', '-erroff=badargtypel2w,wbadinitl,wvarhidemem'], 'win32': [], - 'mingw32': ['-Wno-write-strings'], + 'mingw32': ['-fno-strict-aliasing', '-Wno-write-strings'], 'freebsd7': ['-fno-strict-aliasing', '-Wno-write-strings'], } @@ -140,7 +149,7 @@ with_setuptools_c7 = ('00000000', '00000006', '*c', '00000007', '*final') with_setuptools_c11 = ('00000000', '00000006', '*c', '00000011', '*final') if with_setuptools >= with_setuptools_c7 and 'NO_SHARED' not in os.environ: - if platform in ('darwin', 'ipod', 'win32'): + if platform in ('darwin', 'ipod', 'win32', 'mingw32'): enable_shared = True elif platform == 'linux2': try: @@ -196,7 +205,55 @@ with_setuptools = None enable_shared = False +if enable_shared and (platform == "mingw32"): + # need to monkeypatch the CygwinCCompiler class to generate + # jcc.lib in the correct place + import distutils.cygwinccompiler, copy + _mgwc = distutils.cygwinccompiler.Mingw32CCompiler + class OurMinGW32CCompiler(_mgwc): + def link (self, + target_desc, + objects, + output_filename, + output_dir=None, + libraries=None, + library_dirs=None, + runtime_library_dirs=None, + export_symbols=None, + debug=0, + extra_preargs=None, + extra_postargs=None, + build_temp=None, + target_lang=None): + # use separate copies, so we can modify the lists + extra_preargs = copy.copy(extra_preargs or []) + + (dll_name, dll_extension) = os.path.splitext(output_filename) + if dll_extension == ".dll": + extra_preargs.extend(["-Wl,--out-implib,%s" % ( + os.path.join(os.path.dirname(dll_name), "jcc", "jcc.lib"))]) + + _mgwc.link( + self, + target_desc=target_desc, + objects=objects, + output_filename=output_filename, + output_dir=output_dir, + libraries=libraries, + library_dirs=library_dirs, + runtime_library_dirs=runtime_library_dirs, + export_symbols=export_symbols, + debug=debug, + extra_preargs=extra_preargs, + extra_postargs=extra_postargs, + build_temp=build_temp, + target_lang=target_lang) + + # class OurMinGW32CCompiler + + distutils.cygwinccompiler.Mingw32CCompiler = OurMinGW32CCompiler + def main(debug): _jcc_argsep = os.environ.get('JCC_ARGSEP', os.pathsep) @@ -226,6 +283,14 @@ else: _javac = JAVAC[platform] + if 'JCC_AUTO_FIND_JVM_DLL' in os.environ: + _autofindjvmdll = os.environ['JCC_AUTO_FIND_JVM_DLL'] + elif "--auto-find-jvm-dll" in sys.argv: + _autofindjvmdll = True + sys.argv.remove("--auto-find-jvm-dll") + else: + _autofindjvmdll = False + config = file(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'jcc', 'config.py'), 'w') print >>config @@ -234,6 +299,7 @@ print >>config, 'DEBUG_CFLAGS=%s' %(_debug_cflags) print >>config, 'LFLAGS=%s' %(_lflags) print >>config, 'SHARED=%s' %(enable_shared) + print >>config, 'AUTO_FIND_JVM_DLL=%s' %(_autofindjvmdll) print >>config config.close() Index: trunk/Makefile =================================================================== --- trunk/Makefile (revision 925683) +++ trunk/Makefile (working copy) @@ -118,6 +118,13 @@ #JCC=$(PYTHON) -m jcc --shared #NUM_FILES=3 +# Windows (Win32, msys/MinGW, Python 2.6.4, Java 1.6, ant 1.7.1 (WinAnt)) +PREFIX_PYTHON=/c/Python26 +ANT=JAVA_HOME="c:\\Program Files\\Java\\jdk1.6.0_18" "/c/Program Files/WinAnt/bin/ant" +PYTHON=$(PREFIX_PYTHON)/python.exe +JCC=$(PYTHON) -m jcc.__main__ --shared --compiler mingw32 +NUM_FILES=3 + # # No edits required below # @@ -228,6 +235,9 @@ bdist: jars $(GENERATE) --bdist +wininst: jars + $(GENERATE) --wininst + all: sources jars compile @echo build of $(PYLUCENE_LIB) complete