old python needs __main__ to call a module
[pylucene.git] / jcc / setup.py
1 #   Licensed under the Apache License, Version 2.0 (the "License");
2 #   you may not use this file except in compliance with the License.
3 #   You may obtain a copy of the License at
4 #
5 #       http://www.apache.org/licenses/LICENSE-2.0
6 #
7 #   Unless required by applicable law or agreed to in writing, software
8 #   distributed under the License is distributed on an "AS IS" BASIS,
9 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 #   See the License for the specific language governing permissions and
11 #   limitations under the License.
12
13 import os, sys, platform, subprocess
14
15 jcc_ver = '2.12'
16 machine = platform.machine()
17
18 if machine.startswith("iPod") or machine.startswith("iPhone"):
19     platform = 'ipod'
20 elif sys.platform == "win32" and "--compiler=mingw32" in sys.argv:
21     platform = 'mingw32'
22 else:
23     platform = sys.platform
24
25 # Add or edit the entry corresponding to your system in the JDK, INCLUDES,
26 # CFLAGS, DEBUG_CFLAGS, LFLAGS and JAVAC dictionaries below. 
27 # These entries are used to build JCC _and_ by JCC to drive compiling and
28 # linking via distutils or setuptools the extensions it generated code for.
29 #
30 # The key for your system is determined by the platform variable defined
31 # above.
32 #
33 # Instead of editing the entries below, you may also override these
34 # dictionaries with JCC_JDK, JCC_INCLUDES, JCC_CFLAGS, JCC_DEBUG_CFLAGS,
35 # JCC_LFLAGS and JCC_JAVAC environment variables using os.pathsep as value
36 # separator.
37
38 if platform in ("win32", "mingw32"):
39     try:
40         from helpers.windows import JAVAHOME
41     except ImportError:
42         JAVAHOME = None
43 elif platform in ("darwin",):
44     try:
45         from helpers.darwin import JAVAHOME
46     except ImportError:
47         JAVAHOME = None
48 else:
49     JAVAHOME = None
50
51 JDK = {
52     'darwin': JAVAHOME,
53     'ipod': '/usr/include/gcc',
54     'linux2': '/usr/lib/jvm/java-6-openjdk',
55     'sunos5': '/usr/jdk/instances/jdk1.6.0',
56     'win32': JAVAHOME,
57     'mingw32': JAVAHOME,
58     'freebsd7': '/usr/local/diablo-jdk1.6.0'
59 }
60 if 'JCC_JDK' in os.environ:
61     JDK[platform] = os.environ['JCC_JDK']
62
63
64 if not JDK[platform]:
65     raise RuntimeError('''
66                        
67 Can't determine where the Java JDK has been installed on this machine.
68
69 Please set the environment variable JCC_JDK to that location before
70 running setup.py.
71 ''')
72
73 elif not os.path.isdir(JDK[platform]):
74     raise RuntimeError('''
75                        
76 Java JDK directory '%s' does not exist.
77
78 Please set the environment variable JCC_JDK to the correct location before
79 running setup.py.
80 ''' %(JDK[platform]))
81
82
83 INCLUDES = {
84     'darwin': ['%(darwin)s/Headers' %(JDK)],
85     'ipod': ['%(ipod)s/darwin/default' %(JDK)],
86     'linux2': ['%(linux2)s/include' %(JDK),
87                '%(linux2)s/include/linux' %(JDK)],
88     'sunos5': ['%(sunos5)s/include' %(JDK),
89                '%(sunos5)s/include/solaris' %(JDK)],
90     'win32': ['%(win32)s/include' %(JDK),
91               '%(win32)s/include/win32' %(JDK)],
92     'mingw32': ['%(mingw32)s/include' %(JDK),
93                 '%(mingw32)s/include/win32' %(JDK)],
94     'freebsd7': ['%(freebsd7)s/include' %(JDK),
95                  '%(freebsd7)s/include/freebsd' %(JDK)],
96 }
97
98 CFLAGS = {
99     'darwin': ['-fno-strict-aliasing', '-Wno-write-strings'],
100     'ipod': ['-Wno-write-strings'],
101     'linux2': ['-fno-strict-aliasing', '-Wno-write-strings'],
102     'sunos5': ['-features=iddollar',
103                '-erroff=badargtypel2w,wbadinitl,wvarhidemem'],
104     'win32': ["/EHsc", "/D_CRT_SECURE_NO_WARNINGS"],  # MSVC 9 (2008)
105     'mingw32': ['-fno-strict-aliasing', '-Wno-write-strings'],
106     'freebsd7': ['-fno-strict-aliasing', '-Wno-write-strings'],
107 }
108
109 # added to CFLAGS when JCC is invoked with --debug
110 DEBUG_CFLAGS = {
111     'darwin': ['-O0', '-g', '-DDEBUG'],
112     'ipod': ['-O0', '-g', '-DDEBUG'],
113     'linux2': ['-O0', '-g', '-DDEBUG'],
114     'sunos5': ['-DDEBUG'],
115     'win32': ['/Od', '/DDEBUG'],
116     'mingw32': ['-O0', '-g', '-DDEBUG'],
117     'freebsd7': ['-O0', '-g', '-DDEBUG'],
118 }
119
120 LFLAGS = {
121     'darwin': ['-framework', 'JavaVM'],
122     'ipod': ['-ljvm', '-lpython%s.%s' %(sys.version_info[0:2]),
123              '-L/usr/lib/gcc/arm-apple-darwin9/4.0.1'],
124     'linux2/i386': ['-L%(linux2)s/jre/lib/i386' %(JDK), '-ljava',
125                     '-L%(linux2)s/jre/lib/i386/client' %(JDK), '-ljvm',
126                     '-Wl,-rpath=%(linux2)s/jre/lib/i386:%(linux2)s/jre/lib/i386/client' %(JDK)],
127     'linux2/i686': ['-L%(linux2)s/jre/lib/i386' %(JDK), '-ljava',
128                     '-L%(linux2)s/jre/lib/i386/client' %(JDK), '-ljvm',
129                     '-Wl,-rpath=%(linux2)s/jre/lib/i386:%(linux2)s/jre/lib/i386/client' %(JDK)],
130     'linux2/x86_64': ['-L%(linux2)s/jre/lib/amd64' %(JDK), '-ljava',
131                       '-L%(linux2)s/jre/lib/amd64/server' %(JDK), '-ljvm',
132                       '-Wl,-rpath=%(linux2)s/jre/lib/amd64:%(linux2)s/jre/lib/amd64/server' %(JDK)],
133     'sunos5': ['-L%(sunos5)s/jre/lib/i386' %(JDK), '-ljava',
134                '-L%(sunos5)s/jre/lib/i386/client' %(JDK), '-ljvm',
135                '-R%(sunos5)s/jre/lib/i386:%(sunos5)s/jre/lib/i386/client' %(JDK)],
136     'win32': ['/LIBPATH:%(win32)s/lib' %(JDK), 'jvm.lib'],
137     'mingw32': ['-L%(mingw32)s/lib' %(JDK), '-ljvm'],
138     'freebsd7': ['-L%(freebsd7)s/jre/lib/i386' %(JDK), '-ljava', '-lverify',
139                  '-L%(freebsd7)s/jre/lib/i386/client' %(JDK), '-ljvm',
140                  '-Wl,-rpath=%(freebsd7)s/jre/lib/i386:%(freebsd7)s/jre/lib/i386/client' %(JDK)],
141 }
142
143 IMPLIB_LFLAGS = {
144     'win32': ["/IMPLIB:%s"],
145     'mingw32': ["-Wl,--out-implib,%s"]
146 }
147
148 if platform == 'linux2':
149     LFLAGS['linux2'] = LFLAGS['linux2/%s' %(machine)]
150
151 JAVAC = {
152     'darwin': ['javac', '-target', '1.5'],
153     'ipod': ['jikes', '-cp', '/usr/share/classpath/glibj.zip'],
154     'linux2': ['javac'],
155     'sunos5': ['javac'],
156     'win32': ['%(win32)s/bin/javac.exe' %(JDK)],
157     'mingw32': ['%(mingw32)s/bin/javac.exe' %(JDK)],
158     'freebsd7': ['javac'],
159 }
160
161 JAVADOC = {
162     'darwin': ['javadoc'],
163     'ipod': [],
164     'linux2': ['javadoc'],
165     'sunos5': ['javadoc'],
166     'win32': ['%(win32)s/bin/javadoc.exe' %(JDK)],
167     'mingw32': ['%(mingw32)s/bin/javadoc.exe' %(JDK)],
168     'freebsd7': ['javadoc'],
169 }
170
171 try:
172     if 'USE_DISTUTILS' in os.environ:
173         raise ImportError
174     from setuptools import setup, Extension
175     from pkg_resources import require
176     with_setuptools = require('setuptools')[0].parsed_version
177
178     enable_shared = False
179     with_setuptools_c7 = ('00000000', '00000006', '*c', '00000007', '*final')
180
181     if with_setuptools >= with_setuptools_c7 and 'NO_SHARED' not in os.environ:
182         if platform in ('darwin', 'ipod', 'win32'):
183             enable_shared = True
184         elif platform == 'linux2':
185             from helpers.linux import patch_setuptools
186             enable_shared = patch_setuptools(with_setuptools)
187         elif platform == 'mingw32':
188             enable_shared = True
189             # need to monkeypatch the CygwinCCompiler class to generate
190             # jcc.lib in the correct place
191             from helpers.mingw32 import JCCMinGW32CCompiler
192             import distutils.cygwinccompiler
193             distutils.cygwinccompiler.Mingw32CCompiler = JCCMinGW32CCompiler
194
195 except ImportError:
196     if sys.version_info < (2, 4):
197         raise ImportError, 'setuptools is required when using Python 2.3'
198     else:
199         from distutils.core import setup, Extension
200         with_setuptools = None
201         enable_shared = False
202
203
204 def main(debug):
205
206     _jcc_argsep = os.environ.get('JCC_ARGSEP', os.pathsep)
207
208     if 'JCC_INCLUDES' in os.environ:
209         _includes = os.environ['JCC_INCLUDES'].split(_jcc_argsep)
210     else:
211         _includes = INCLUDES[platform]
212
213     if 'JCC_CFLAGS' in os.environ:
214         _cflags = os.environ['JCC_CFLAGS'].split(_jcc_argsep)
215     else:
216         _cflags = CFLAGS[platform]
217
218     if 'JCC_DEBUG_CFLAGS' in os.environ:
219         _debug_cflags = os.environ['JCC_DEBUG_CFLAGS'].split(_jcc_argsep)
220     else:
221         _debug_cflags = DEBUG_CFLAGS[platform]
222
223     if 'JCC_LFLAGS' in os.environ:
224         _lflags = os.environ['JCC_LFLAGS'].split(_jcc_argsep)
225     else:
226         _lflags = LFLAGS[platform]
227
228     if 'JCC_IMPLIB_LFLAGS' in os.environ:
229         _implib_lflags = os.environ['JCC_IMPLIB_LFLAGS'].split(_jcc_argsep)
230     else:
231         _implib_lflags = IMPLIB_LFLAGS.get(platform, [])
232
233     if 'JCC_JAVAC' in os.environ:
234         _javac = os.environ['JCC_JAVAC'].split(_jcc_argsep)
235     else:
236         _javac = JAVAC[platform]
237
238     if 'JCC_JAVADOC' in os.environ:
239         _javadoc = os.environ['JCC_JAVADOC'].split(_jcc_argsep)
240     else:
241         _javadoc = JAVADOC[platform]
242
243     from helpers.build import jcc_build_py
244
245     jcc_build_py.config_file = \
246         os.path.join(os.path.dirname(os.path.abspath(__file__)),
247                      'jcc', 'config.py')
248     jcc_build_py.config_text = \
249         '\n'.join(['',
250                    'INCLUDES=%s' %(_includes),
251                    'CFLAGS=%s' %(_cflags),
252                    'DEBUG_CFLAGS=%s' %(_debug_cflags),
253                    'LFLAGS=%s' %(_lflags),
254                    'IMPLIB_LFLAGS=%s' %(_implib_lflags),
255                    'SHARED=%s' %(enable_shared),
256                    'VERSION="%s"' %(jcc_ver),
257                    ''])
258
259     extensions = []
260
261     boot = '_jcc'
262
263     cflags = ['-DPYTHON'] + _cflags
264     if debug:
265         cflags += _debug_cflags
266     includes = _includes + [boot, 'jcc/sources']
267     lflags = _lflags
268     if not debug:
269         if platform == 'win32':
270             pass
271         elif platform == 'sunos5':
272             lflags += ['-Wl,-s']
273         else:
274             lflags += ['-Wl,-S']
275
276     sources = ['jcc/sources/jcc.cpp',
277                'jcc/sources/JCCEnv.cpp',
278                'jcc/sources/JObject.cpp',
279                'jcc/sources/JArray.cpp',
280                'jcc/sources/functions.cpp',
281                'jcc/sources/types.cpp']
282     for path, dirs, names in os.walk(boot):
283         for name in names:
284             if name.endswith('.cpp'):
285                 sources.append(os.path.join(path, name))
286     package_data = ['sources/*.cpp', 'sources/*.h', 'patches/patch.*']
287
288     if with_setuptools and enable_shared:
289         from subprocess import Popen, PIPE
290         from setuptools import Library
291
292         kwds = { "extra_compile_args": cflags,
293                  "include_dirs": includes,
294                  "define_macros": [('_jcc_lib', None),
295                                    ('JCC_VER', '"%s"' %(jcc_ver))],
296                  "sources": sources[0:2] }
297
298         if platform in ('darwin', 'ipod'):
299             kwds["extra_link_args"] = \
300                 lflags + ['-install_name', '@rpath/libjcc.dylib',
301                           '-current_version', jcc_ver,
302                           '-compatibility_version', jcc_ver]
303         elif platform == 'linux2':
304             kwds["extra_link_args"] = \
305                 lflags + ['-lpython%s.%s' %(sys.version_info[0:2])]
306             kwds["force_shared"] = True    # requires jcc/patches/patch.43
307         elif platform in IMPLIB_LFLAGS:
308             jcclib = 'jcc%s.lib' %(debug and '_d' or '')
309             implib_flags = ' '.join(IMPLIB_LFLAGS[platform])
310             kwds["extra_link_args"] = \
311                 lflags + [implib_flags %(os.path.join('jcc', jcclib))]
312             package_data.append(jcclib)
313         else:
314             kwds["extra_link_args"] = lflags
315
316         extensions.append(Library('jcc', **kwds))
317
318         args = _javac[:]
319         args.extend(('-d', 'jcc/classes'))
320         args.append('java/org/apache/jcc/PythonVM.java')
321         args.append('java/org/apache/jcc/PythonException.java')
322         if not os.path.exists('jcc/classes'):
323             os.makedirs('jcc/classes')
324         try:
325             process = Popen(args, stderr=PIPE)
326         except Exception, e:
327             raise type(e), "%s: %s" %(e, args)
328         process.wait()
329         if process.returncode != 0:
330             raise OSError, process.stderr.read()
331         package_data.append('classes/org/apache/jcc/PythonVM.class')
332         package_data.append('classes/org/apache/jcc/PythonException.class')
333
334         args = _javadoc[:]
335         args.extend(('-d', 'javadoc', '-sourcepath', 'java', 'org.apache.jcc'))
336         try:
337             process = Popen(args, stderr=PIPE)
338         except Exception, e:
339             raise type(e), "%s: %s" %(e, args)
340         process.wait()
341         if process.returncode != 0:
342             raise OSError, process.stderr.read()
343
344     extensions.append(Extension('jcc._jcc',
345                                 extra_compile_args=cflags,
346                                 extra_link_args=lflags,
347                                 include_dirs=includes,
348                                 define_macros=[('_java_generics', None),
349                                                ('JCC_VER', '"%s"' %(jcc_ver))],
350                                 sources=sources))
351
352     args = {
353         'name': 'JCC',
354         'version': jcc_ver,
355         'description': 'a C++ code generator for calling Java from C++/Python',
356         'long_description': open('DESCRIPTION').read(),
357         'author': 'Andi Vajda',
358         'author_email': 'vajda@apache.org',
359         'classifiers': ['Development Status :: 5 - Production/Stable',
360                         'Environment :: Console',
361                         'Intended Audience :: Developers',
362                         'License :: OSI Approved :: Apache Software License',
363                         'Operating System :: OS Independent',
364                         'Programming Language :: C++',
365                         'Programming Language :: Java',
366                         'Programming Language :: Python',
367                         'Topic :: Software Development :: Code Generators',
368                         'Topic :: Software Development :: Libraries :: Java Libraries'],
369         'packages': ['jcc'],
370         'package_dir': {'jcc': 'jcc'},
371         'package_data': {'jcc': package_data},
372         'ext_modules': extensions,
373         "cmdclass": {"build_py": jcc_build_py},
374     }
375     if with_setuptools:
376         args['zip_safe'] = False
377         
378     setup(**args)
379
380
381 if __name__ == "__main__":
382     main('--debug' in sys.argv)