##// END OF EJS Templates
setup: warn about missing standard Python components
Matt Mackall -
r7558:dc211ad8 default
parent child Browse files
Show More
@@ -1,144 +1,161 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # This is the mercurial setup script.
3 # This is the mercurial setup script.
4 #
4 #
5 # 'python setup.py install', or
5 # 'python setup.py install', or
6 # 'python setup.py --help' for more options
6 # 'python setup.py --help' for more options
7
7
8 import sys
8 import sys
9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'):
9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'):
10 raise SystemExit("Mercurial requires python 2.3 or later.")
10 raise SystemExit("Mercurial requires python 2.3 or later.")
11
11
12 # Solaris Python packaging brain damage
13 try:
14 import hashlib
15 sha = hashlib.sha1()
16 except:
17 try:
18 import sha
19 except:
20 raise SystemExit(
21 "Couldn't import standard hashlib (incomplete Python install).")
22
23 try:
24 import zlib
25 except:
26 raise SystemExit(
27 "Couldn't import standard zlib (incomplete Python install).")
28
12 import os
29 import os
13 import shutil
30 import shutil
14 import tempfile
31 import tempfile
15 from distutils.core import setup, Extension
32 from distutils.core import setup, Extension
16 from distutils.command.install_data import install_data
33 from distutils.command.install_data import install_data
17 from distutils.ccompiler import new_compiler
34 from distutils.ccompiler import new_compiler
18
35
19 import mercurial.version
36 import mercurial.version
20
37
21 extra = {}
38 extra = {}
22 scripts = ['hg']
39 scripts = ['hg']
23 if os.name == 'nt':
40 if os.name == 'nt':
24 scripts.append('contrib/win32/hg.bat')
41 scripts.append('contrib/win32/hg.bat')
25
42
26 # simplified version of distutils.ccompiler.CCompiler.has_function
43 # simplified version of distutils.ccompiler.CCompiler.has_function
27 # that actually removes its temporary files.
44 # that actually removes its temporary files.
28 def has_function(cc, funcname):
45 def has_function(cc, funcname):
29 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
46 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
30 devnull = oldstderr = None
47 devnull = oldstderr = None
31 try:
48 try:
32 try:
49 try:
33 fname = os.path.join(tmpdir, 'funcname.c')
50 fname = os.path.join(tmpdir, 'funcname.c')
34 f = open(fname, 'w')
51 f = open(fname, 'w')
35 f.write('int main(void) {\n')
52 f.write('int main(void) {\n')
36 f.write(' %s();\n' % funcname)
53 f.write(' %s();\n' % funcname)
37 f.write('}\n')
54 f.write('}\n')
38 f.close()
55 f.close()
39 # Redirect stderr to /dev/null to hide any error messages
56 # Redirect stderr to /dev/null to hide any error messages
40 # from the compiler.
57 # from the compiler.
41 # This will have to be changed if we ever have to check
58 # This will have to be changed if we ever have to check
42 # for a function on Windows.
59 # for a function on Windows.
43 devnull = open('/dev/null', 'w')
60 devnull = open('/dev/null', 'w')
44 oldstderr = os.dup(sys.stderr.fileno())
61 oldstderr = os.dup(sys.stderr.fileno())
45 os.dup2(devnull.fileno(), sys.stderr.fileno())
62 os.dup2(devnull.fileno(), sys.stderr.fileno())
46 objects = cc.compile([fname])
63 objects = cc.compile([fname])
47 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
64 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
48 except:
65 except:
49 return False
66 return False
50 return True
67 return True
51 finally:
68 finally:
52 if oldstderr is not None:
69 if oldstderr is not None:
53 os.dup2(oldstderr, sys.stderr.fileno())
70 os.dup2(oldstderr, sys.stderr.fileno())
54 if devnull is not None:
71 if devnull is not None:
55 devnull.close()
72 devnull.close()
56 shutil.rmtree(tmpdir)
73 shutil.rmtree(tmpdir)
57
74
58 # py2exe needs to be installed to work
75 # py2exe needs to be installed to work
59 try:
76 try:
60 import py2exe
77 import py2exe
61
78
62 # Help py2exe to find win32com.shell
79 # Help py2exe to find win32com.shell
63 try:
80 try:
64 import modulefinder
81 import modulefinder
65 import win32com
82 import win32com
66 for p in win32com.__path__[1:]: # Take the path to win32comext
83 for p in win32com.__path__[1:]: # Take the path to win32comext
67 modulefinder.AddPackagePath("win32com", p)
84 modulefinder.AddPackagePath("win32com", p)
68 pn = "win32com.shell"
85 pn = "win32com.shell"
69 __import__(pn)
86 __import__(pn)
70 m = sys.modules[pn]
87 m = sys.modules[pn]
71 for p in m.__path__[1:]:
88 for p in m.__path__[1:]:
72 modulefinder.AddPackagePath(pn, p)
89 modulefinder.AddPackagePath(pn, p)
73 except ImportError:
90 except ImportError:
74 pass
91 pass
75
92
76 extra['console'] = ['hg']
93 extra['console'] = ['hg']
77
94
78 except ImportError:
95 except ImportError:
79 pass
96 pass
80
97
81 # specify version string, otherwise 'hg identify' will be used:
98 # specify version string, otherwise 'hg identify' will be used:
82 version = ''
99 version = ''
83
100
84 class install_package_data(install_data):
101 class install_package_data(install_data):
85 def finalize_options(self):
102 def finalize_options(self):
86 self.set_undefined_options('install',
103 self.set_undefined_options('install',
87 ('install_lib', 'install_dir'))
104 ('install_lib', 'install_dir'))
88 install_data.finalize_options(self)
105 install_data.finalize_options(self)
89
106
90 mercurial.version.remember_version(version)
107 mercurial.version.remember_version(version)
91 cmdclass = {'install_data': install_package_data}
108 cmdclass = {'install_data': install_package_data}
92
109
93 ext_modules=[
110 ext_modules=[
94 Extension('mercurial.base85', ['mercurial/base85.c']),
111 Extension('mercurial.base85', ['mercurial/base85.c']),
95 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
112 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
96 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
113 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
97 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
114 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
98 Extension('mercurial.parsers', ['mercurial/parsers.c']),
115 Extension('mercurial.parsers', ['mercurial/parsers.c']),
99 ]
116 ]
100
117
101 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
118 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
102 'hgext.highlight', 'hgext.zeroconf', ]
119 'hgext.highlight', 'hgext.zeroconf', ]
103
120
104 try:
121 try:
105 import msvcrt
122 import msvcrt
106 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
123 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
107 except ImportError:
124 except ImportError:
108 pass
125 pass
109
126
110 try:
127 try:
111 import posix
128 import posix
112 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
129 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
113
130
114 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
131 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
115 # The inotify extension is only usable with Linux 2.6 kernels.
132 # The inotify extension is only usable with Linux 2.6 kernels.
116 # You also need a reasonably recent C library.
133 # You also need a reasonably recent C library.
117 cc = new_compiler()
134 cc = new_compiler()
118 if has_function(cc, 'inotify_add_watch'):
135 if has_function(cc, 'inotify_add_watch'):
119 ext_modules.append(Extension('hgext.inotify.linux._inotify',
136 ext_modules.append(Extension('hgext.inotify.linux._inotify',
120 ['hgext/inotify/linux/_inotify.c']))
137 ['hgext/inotify/linux/_inotify.c']))
121 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
138 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
122 except ImportError:
139 except ImportError:
123 pass
140 pass
124
141
125 setup(name='mercurial',
142 setup(name='mercurial',
126 version=mercurial.version.get_version(),
143 version=mercurial.version.get_version(),
127 author='Matt Mackall',
144 author='Matt Mackall',
128 author_email='mpm@selenic.com',
145 author_email='mpm@selenic.com',
129 url='http://selenic.com/mercurial',
146 url='http://selenic.com/mercurial',
130 description='Scalable distributed SCM',
147 description='Scalable distributed SCM',
131 license='GNU GPL',
148 license='GNU GPL',
132 scripts=scripts,
149 scripts=scripts,
133 packages=packages,
150 packages=packages,
134 ext_modules=ext_modules,
151 ext_modules=ext_modules,
135 data_files=[(os.path.join('mercurial', root),
152 data_files=[(os.path.join('mercurial', root),
136 [os.path.join(root, file_) for file_ in files])
153 [os.path.join(root, file_) for file_ in files])
137 for root, dirs, files in os.walk('templates')],
154 for root, dirs, files in os.walk('templates')],
138 cmdclass=cmdclass,
155 cmdclass=cmdclass,
139 options=dict(py2exe=dict(packages=['hgext', 'email']),
156 options=dict(py2exe=dict(packages=['hgext', 'email']),
140 bdist_mpkg=dict(zipdist=True,
157 bdist_mpkg=dict(zipdist=True,
141 license='COPYING',
158 license='COPYING',
142 readme='contrib/macosx/Readme.html',
159 readme='contrib/macosx/Readme.html',
143 welcome='contrib/macosx/Welcome.html')),
160 welcome='contrib/macosx/Welcome.html')),
144 **extra)
161 **extra)
General Comments 0
You need to be logged in to leave comments. Login now