##// END OF EJS Templates
add --pure flag to setup.py...
Martin Geisler -
r7722:103127a8 default
parent child Browse files
Show More
@@ -1,218 +1,247
1 1 #!/usr/bin/env python
2 2 #
3 3 # This is the mercurial setup script.
4 4 #
5 5 # 'python setup.py install', or
6 6 # 'python setup.py --help' for more options
7 7
8 8 import sys
9 9 if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'):
10 10 raise SystemExit("Mercurial requires python 2.3 or later.")
11 11
12 12 # Solaris Python packaging brain damage
13 13 try:
14 14 import hashlib
15 15 sha = hashlib.sha1()
16 16 except:
17 17 try:
18 18 import sha
19 19 except:
20 20 raise SystemExit(
21 21 "Couldn't import standard hashlib (incomplete Python install).")
22 22
23 23 try:
24 24 import zlib
25 25 except:
26 26 raise SystemExit(
27 27 "Couldn't import standard zlib (incomplete Python install).")
28 28
29 29 import os, time
30 30 import shutil
31 31 import tempfile
32 32 from distutils.core import setup, Extension
33 from distutils.dist import Distribution
33 34 from distutils.command.install_data import install_data
34 35 from distutils.command.build import build
36 from distutils.command.build_py import build_py
35 37 from distutils.spawn import spawn, find_executable
36 38 from distutils.ccompiler import new_compiler
37 39
38 40 extra = {}
39 41 scripts = ['hg']
40 42 if os.name == 'nt':
41 43 scripts.append('contrib/win32/hg.bat')
42 44
43 45 # simplified version of distutils.ccompiler.CCompiler.has_function
44 46 # that actually removes its temporary files.
45 47 def has_function(cc, funcname):
46 48 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
47 49 devnull = oldstderr = None
48 50 try:
49 51 try:
50 52 fname = os.path.join(tmpdir, 'funcname.c')
51 53 f = open(fname, 'w')
52 54 f.write('int main(void) {\n')
53 55 f.write(' %s();\n' % funcname)
54 56 f.write('}\n')
55 57 f.close()
56 58 # Redirect stderr to /dev/null to hide any error messages
57 59 # from the compiler.
58 60 # This will have to be changed if we ever have to check
59 61 # for a function on Windows.
60 62 devnull = open('/dev/null', 'w')
61 63 oldstderr = os.dup(sys.stderr.fileno())
62 64 os.dup2(devnull.fileno(), sys.stderr.fileno())
63 65 objects = cc.compile([fname])
64 66 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
65 67 except:
66 68 return False
67 69 return True
68 70 finally:
69 71 if oldstderr is not None:
70 72 os.dup2(oldstderr, sys.stderr.fileno())
71 73 if devnull is not None:
72 74 devnull.close()
73 75 shutil.rmtree(tmpdir)
74 76
75 77 # py2exe needs to be installed to work
76 78 try:
77 79 import py2exe
78 80
79 81 # Help py2exe to find win32com.shell
80 82 try:
81 83 import modulefinder
82 84 import win32com
83 85 for p in win32com.__path__[1:]: # Take the path to win32comext
84 86 modulefinder.AddPackagePath("win32com", p)
85 87 pn = "win32com.shell"
86 88 __import__(pn)
87 89 m = sys.modules[pn]
88 90 for p in m.__path__[1:]:
89 91 modulefinder.AddPackagePath(pn, p)
90 92 except ImportError:
91 93 pass
92 94
93 95 extra['console'] = ['hg']
94 96
95 97 except ImportError:
96 98 pass
97 99
98 100 try:
99 101 # execute hg out of this directory with a custom environment which
100 102 # includes the pure Python modules in mercurial/pure
101 103 pypath = os.environ.get('PYTHONPATH', '')
102 104 purepath = os.path.join('mercurial', 'pure')
103 105 os.environ['PYTHONPATH'] = os.pathsep.join(['mercurial', purepath, pypath])
104 106 cmd = '%s id -it' % os.path.join('.', 'hg')
105 107 l = os.popen(cmd).read().split()
106 108 os.environ['PYTHONPATH'] = pypath
107 109 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
108 110 l.pop()
109 111 version = l and l[-1] or 'unknown' # latest tag or revision number
110 112 if version.endswith('+'):
111 113 version += time.strftime('%Y%m%d')
112 114
113 115 except OSError:
114 116 version = "unknown"
115 117
116 118 f = file("mercurial/__version__.py", "w")
117 119 f.write('# this file is autogenerated by setup.py\n')
118 120 f.write('version = "%s"\n' % version)
119 121 f.close()
120 122
121 123 class install_package_data(install_data):
122 124 def finalize_options(self):
123 125 self.set_undefined_options('install',
124 126 ('install_lib', 'install_dir'))
125 127 install_data.finalize_options(self)
126 128
127 129 class build_mo(build):
128 130
129 131 description = "build translations (.mo files)"
130 132
131 133 def run(self):
132 134 if not find_executable('msgfmt'):
133 135 self.warn("could not find msgfmt executable, no translations "
134 136 "will be built")
135 137 return
136 138
137 139 podir = 'i18n'
138 140 if not os.path.isdir(podir):
139 141 self.warn("could not find %s/ directory" % podir)
140 142 return
141 143
142 144 join = os.path.join
143 145 for po in os.listdir(podir):
144 146 if not po.endswith('.po'):
145 147 continue
146 148 pofile = join(podir, po)
147 149 modir = join('locale', po[:-3], 'LC_MESSAGES')
148 150 mofile = join(modir, 'hg.mo')
149 151 cmd = ['msgfmt', '-v', '-o', mofile, pofile]
150 152 if sys.platform != 'sunos5':
151 153 # msgfmt on Solaris does not know about -c
152 154 cmd.append('-c')
153 155 self.mkpath(modir)
154 156 self.make_file([pofile], mofile, spawn, (cmd,))
155 157 self.distribution.data_files.append((join('mercurial', modir),
156 158 [mofile]))
157 159
158 160 build.sub_commands.append(('build_mo', None))
159 161
162 Distribution.pure = 0
163 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
164 "code instead of C extensions"))
165
166 class hg_build_py(build_py):
167
168 def finalize_options(self):
169 build_py.finalize_options(self)
170
171 if self.distribution.pure:
172 if self.py_modules is None:
173 self.py_modules = []
174 for ext in self.distribution.ext_modules:
175 if ext.name.startswith("mercurial."):
176 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
177 self.distribution.ext_modules = []
178
179 def find_modules(self):
180 modules = build_py.find_modules(self)
181 for module in modules:
182 if module[0] == "mercurial.pure":
183 if module[1] != "__init__":
184 yield ("mercurial", module[1], module[2])
185 else:
186 yield module
187
160 188 cmdclass = {'install_data': install_package_data,
161 'build_mo': build_mo}
189 'build_mo': build_mo,
190 'build_py': hg_build_py}
162 191
163 192 ext_modules=[
164 193 Extension('mercurial.base85', ['mercurial/base85.c']),
165 194 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
166 195 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
167 196 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
168 197 Extension('mercurial.parsers', ['mercurial/parsers.c']),
169 198 ]
170 199
171 200 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
172 201 'hgext.highlight', 'hgext.zeroconf', ]
173 202
174 203 try:
175 204 import msvcrt
176 205 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
177 206 except ImportError:
178 207 pass
179 208
180 209 try:
181 210 import posix
182 211 ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
183 212
184 213 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
185 214 # The inotify extension is only usable with Linux 2.6 kernels.
186 215 # You also need a reasonably recent C library.
187 216 cc = new_compiler()
188 217 if has_function(cc, 'inotify_add_watch'):
189 218 ext_modules.append(Extension('hgext.inotify.linux._inotify',
190 219 ['hgext/inotify/linux/_inotify.c']))
191 220 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
192 221 except ImportError:
193 222 pass
194 223
195 224 datafiles = []
196 225 for root in ('templates', 'i18n'):
197 226 for dir, dirs, files in os.walk(root):
198 227 datafiles.append((os.path.join('mercurial', dir),
199 228 [os.path.join(dir, file_) for file_ in files]))
200 229
201 230 setup(name='mercurial',
202 231 version=version,
203 232 author='Matt Mackall',
204 233 author_email='mpm@selenic.com',
205 234 url='http://selenic.com/mercurial',
206 235 description='Scalable distributed SCM',
207 236 license='GNU GPL',
208 237 scripts=scripts,
209 238 packages=packages,
210 239 ext_modules=ext_modules,
211 240 data_files=datafiles,
212 241 cmdclass=cmdclass,
213 242 options=dict(py2exe=dict(packages=['hgext', 'email']),
214 243 bdist_mpkg=dict(zipdist=True,
215 244 license='COPYING',
216 245 readme='contrib/macosx/Readme.html',
217 246 welcome='contrib/macosx/Welcome.html')),
218 247 **extra)
General Comments 0
You need to be logged in to leave comments. Login now