##// END OF EJS Templates
setup: remove unnecessary code for win32com (pywin32)
Steve Borho -
r13619:fd09c3ae default
parent child Browse files
Show More
@@ -1,405 +1,389 b''
1 1 #
2 2 # This is the mercurial setup script.
3 3 #
4 4 # 'python setup.py install', or
5 5 # 'python setup.py --help' for more options
6 6
7 7 import sys
8 8 if not hasattr(sys, 'version_info') or sys.version_info < (2, 4, 0, 'final'):
9 9 raise SystemExit("Mercurial requires Python 2.4 or later.")
10 10
11 11 if sys.version_info[0] >= 3:
12 12 def b(s):
13 13 '''A helper function to emulate 2.6+ bytes literals using string
14 14 literals.'''
15 15 return s.encode('latin1')
16 16 else:
17 17 def b(s):
18 18 '''A helper function to emulate 2.6+ bytes literals using string
19 19 literals.'''
20 20 return s
21 21
22 22 # Solaris Python packaging brain damage
23 23 try:
24 24 import hashlib
25 25 sha = hashlib.sha1()
26 26 except:
27 27 try:
28 28 import sha
29 29 except:
30 30 raise SystemExit(
31 31 "Couldn't import standard hashlib (incomplete Python install).")
32 32
33 33 try:
34 34 import zlib
35 35 except:
36 36 raise SystemExit(
37 37 "Couldn't import standard zlib (incomplete Python install).")
38 38
39 39 try:
40 40 import bz2
41 41 except:
42 42 raise SystemExit(
43 43 "Couldn't import standard bz2 (incomplete Python install).")
44 44
45 45 import os, subprocess, time
46 46 import shutil
47 47 import tempfile
48 48 from distutils import log
49 49 from distutils.core import setup, Extension
50 50 from distutils.dist import Distribution
51 51 from distutils.command.build import build
52 52 from distutils.command.build_ext import build_ext
53 53 from distutils.command.build_py import build_py
54 54 from distutils.command.install_scripts import install_scripts
55 55 from distutils.spawn import spawn, find_executable
56 56 from distutils.ccompiler import new_compiler
57 57 from distutils.errors import CCompilerError
58 58 from distutils.sysconfig import get_python_inc
59 59 from distutils.version import StrictVersion
60 60
61 61 scripts = ['hg']
62 62 if os.name == 'nt':
63 63 scripts.append('contrib/win32/hg.bat')
64 64
65 65 # simplified version of distutils.ccompiler.CCompiler.has_function
66 66 # that actually removes its temporary files.
67 67 def hasfunction(cc, funcname):
68 68 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
69 69 devnull = oldstderr = None
70 70 try:
71 71 try:
72 72 fname = os.path.join(tmpdir, 'funcname.c')
73 73 f = open(fname, 'w')
74 74 f.write('int main(void) {\n')
75 75 f.write(' %s();\n' % funcname)
76 76 f.write('}\n')
77 77 f.close()
78 78 # Redirect stderr to /dev/null to hide any error messages
79 79 # from the compiler.
80 80 # This will have to be changed if we ever have to check
81 81 # for a function on Windows.
82 82 devnull = open('/dev/null', 'w')
83 83 oldstderr = os.dup(sys.stderr.fileno())
84 84 os.dup2(devnull.fileno(), sys.stderr.fileno())
85 85 objects = cc.compile([fname], output_dir=tmpdir)
86 86 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
87 87 except:
88 88 return False
89 89 return True
90 90 finally:
91 91 if oldstderr is not None:
92 92 os.dup2(oldstderr, sys.stderr.fileno())
93 93 if devnull is not None:
94 94 devnull.close()
95 95 shutil.rmtree(tmpdir)
96 96
97 97 # py2exe needs to be installed to work
98 98 try:
99 99 import py2exe
100 100 py2exeloaded = True
101
102 # Help py2exe to find win32com.shell
103 try:
104 import modulefinder
105 import win32com
106 for p in win32com.__path__[1:]: # Take the path to win32comext
107 modulefinder.AddPackagePath("win32com", p)
108 pn = "win32com.shell"
109 __import__(pn)
110 m = sys.modules[pn]
111 for p in m.__path__[1:]:
112 modulefinder.AddPackagePath(pn, p)
113 except ImportError:
114 pass
115
116 101 except ImportError:
117 102 py2exeloaded = False
118 pass
119 103
120 104 def runcmd(cmd, env):
121 105 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
122 106 stderr=subprocess.PIPE, env=env)
123 107 out, err = p.communicate()
124 108 # If root is executing setup.py, but the repository is owned by
125 109 # another user (as in "sudo python setup.py install") we will get
126 110 # trust warnings since the .hg/hgrc file is untrusted. That is
127 111 # fine, we don't want to load it anyway. Python may warn about
128 112 # a missing __init__.py in mercurial/locale, we also ignore that.
129 113 err = [e for e in err.splitlines()
130 114 if not e.startswith(b('Not trusting file')) \
131 115 and not e.startswith(b('warning: Not importing'))]
132 116 if err:
133 117 return ''
134 118 return out
135 119
136 120 version = ''
137 121
138 122 if os.path.isdir('.hg'):
139 123 # Execute hg out of this directory with a custom environment which
140 124 # includes the pure Python modules in mercurial/pure. We also take
141 125 # care to not use any hgrc files and do no localization.
142 126 pypath = ['mercurial', os.path.join('mercurial', 'pure')]
143 127 env = {'PYTHONPATH': os.pathsep.join(pypath),
144 128 'HGRCPATH': '',
145 129 'LANGUAGE': 'C'}
146 130 if 'LD_LIBRARY_PATH' in os.environ:
147 131 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
148 132 if 'SystemRoot' in os.environ:
149 133 # Copy SystemRoot into the custom environment for Python 2.6
150 134 # under Windows. Otherwise, the subprocess will fail with
151 135 # error 0xc0150004. See: http://bugs.python.org/issue3440
152 136 env['SystemRoot'] = os.environ['SystemRoot']
153 137 cmd = [sys.executable, 'hg', 'id', '-i', '-t']
154 138 l = runcmd(cmd, env).split()
155 139 while len(l) > 1 and l[-1][0].isalpha(): # remove non-numbered tags
156 140 l.pop()
157 141 if len(l) > 1: # tag found
158 142 version = l[-1]
159 143 if l[0].endswith('+'): # propagate the dirty status to the tag
160 144 version += '+'
161 145 elif len(l) == 1: # no tag found
162 146 cmd = [sys.executable, 'hg', 'parents', '--template',
163 147 '{latesttag}+{latesttagdistance}-']
164 148 version = runcmd(cmd, env) + l[0]
165 149 if version.endswith('+'):
166 150 version += time.strftime('%Y%m%d')
167 151 elif os.path.exists('.hg_archival.txt'):
168 152 kw = dict([[t.strip() for t in l.split(':', 1)]
169 153 for l in open('.hg_archival.txt')])
170 154 if 'tag' in kw:
171 155 version = kw['tag']
172 156 elif 'latesttag' in kw:
173 157 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
174 158 else:
175 159 version = kw.get('node', '')[:12]
176 160
177 161 if version:
178 162 f = open("mercurial/__version__.py", "w")
179 163 f.write('# this file is autogenerated by setup.py\n')
180 164 f.write('version = "%s"\n' % version)
181 165 f.close()
182 166
183 167
184 168 try:
185 169 from mercurial import __version__
186 170 version = __version__.version
187 171 except ImportError:
188 172 version = 'unknown'
189 173
190 174 class hgbuildmo(build):
191 175
192 176 description = "build translations (.mo files)"
193 177
194 178 def run(self):
195 179 if not find_executable('msgfmt'):
196 180 self.warn("could not find msgfmt executable, no translations "
197 181 "will be built")
198 182 return
199 183
200 184 podir = 'i18n'
201 185 if not os.path.isdir(podir):
202 186 self.warn("could not find %s/ directory" % podir)
203 187 return
204 188
205 189 join = os.path.join
206 190 for po in os.listdir(podir):
207 191 if not po.endswith('.po'):
208 192 continue
209 193 pofile = join(podir, po)
210 194 modir = join('locale', po[:-3], 'LC_MESSAGES')
211 195 mofile = join(modir, 'hg.mo')
212 196 mobuildfile = join('mercurial', mofile)
213 197 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
214 198 if sys.platform != 'sunos5':
215 199 # msgfmt on Solaris does not know about -c
216 200 cmd.append('-c')
217 201 self.mkpath(join('mercurial', modir))
218 202 self.make_file([pofile], mobuildfile, spawn, (cmd,))
219 203
220 204
221 205 # Insert hgbuildmo first so that files in mercurial/locale/ are found
222 206 # when build_py is run next.
223 207 build.sub_commands.insert(0, ('build_mo', None))
224 208
225 209 Distribution.pure = 0
226 210 Distribution.global_options.append(('pure', None, "use pure (slow) Python "
227 211 "code instead of C extensions"))
228 212
229 213 class hgbuildext(build_ext):
230 214
231 215 def build_extension(self, ext):
232 216 try:
233 217 build_ext.build_extension(self, ext)
234 218 except CCompilerError:
235 219 if not getattr(ext, 'optional', False):
236 220 raise
237 221 log.warn("Failed to build optional extension '%s' (skipping)",
238 222 ext.name)
239 223
240 224 class hgbuildpy(build_py):
241 225
242 226 def finalize_options(self):
243 227 build_py.finalize_options(self)
244 228
245 229 if self.distribution.pure:
246 230 if self.py_modules is None:
247 231 self.py_modules = []
248 232 for ext in self.distribution.ext_modules:
249 233 if ext.name.startswith("mercurial."):
250 234 self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
251 235 self.distribution.ext_modules = []
252 236 else:
253 237 if not os.path.exists(os.path.join(get_python_inc(), 'Python.h')):
254 238 raise SystemExit("Python headers are required to build Mercurial")
255 239
256 240 def find_modules(self):
257 241 modules = build_py.find_modules(self)
258 242 for module in modules:
259 243 if module[0] == "mercurial.pure":
260 244 if module[1] != "__init__":
261 245 yield ("mercurial", module[1], module[2])
262 246 else:
263 247 yield module
264 248
265 249 class hginstallscripts(install_scripts):
266 250 '''
267 251 This is a specialization of install_scripts that replaces the @LIBDIR@ with
268 252 the configured directory for modules. If possible, the path is made relative
269 253 to the directory for scripts.
270 254 '''
271 255
272 256 def initialize_options(self):
273 257 install_scripts.initialize_options(self)
274 258
275 259 self.install_lib = None
276 260
277 261 def finalize_options(self):
278 262 install_scripts.finalize_options(self)
279 263 self.set_undefined_options('install',
280 264 ('install_lib', 'install_lib'))
281 265
282 266 def run(self):
283 267 install_scripts.run(self)
284 268
285 269 if (os.path.splitdrive(self.install_dir)[0] !=
286 270 os.path.splitdrive(self.install_lib)[0]):
287 271 # can't make relative paths from one drive to another, so use an
288 272 # absolute path instead
289 273 libdir = self.install_lib
290 274 else:
291 275 common = os.path.commonprefix((self.install_dir, self.install_lib))
292 276 rest = self.install_dir[len(common):]
293 277 uplevel = len([n for n in os.path.split(rest) if n])
294 278
295 279 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
296 280
297 281 for outfile in self.outfiles:
298 282 fp = open(outfile, 'rb')
299 283 data = fp.read()
300 284 fp.close()
301 285
302 286 # skip binary files
303 287 if '\0' in data:
304 288 continue
305 289
306 290 data = data.replace('@LIBDIR@', libdir.encode('string_escape'))
307 291 fp = open(outfile, 'wb')
308 292 fp.write(data)
309 293 fp.close()
310 294
311 295 cmdclass = {'build_mo': hgbuildmo,
312 296 'build_ext': hgbuildext,
313 297 'build_py': hgbuildpy,
314 298 'install_scripts': hginstallscripts}
315 299
316 300 packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
317 301 'hgext.highlight', 'hgext.zeroconf']
318 302
319 303 pymodules = []
320 304
321 305 extmodules = [
322 306 Extension('mercurial.base85', ['mercurial/base85.c']),
323 307 Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
324 308 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
325 309 Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
326 310 Extension('mercurial.parsers', ['mercurial/parsers.c']),
327 311 ]
328 312
329 313 # disable osutil.c under windows + python 2.4 (issue1364)
330 314 if sys.platform == 'win32' and sys.version_info < (2, 5, 0, 'final'):
331 315 pymodules.append('mercurial.pure.osutil')
332 316 else:
333 317 extmodules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
334 318
335 319 if sys.platform == 'linux2' and os.uname()[2] > '2.6':
336 320 # The inotify extension is only usable with Linux 2.6 kernels.
337 321 # You also need a reasonably recent C library.
338 322 # In any case, if it fails to build the error will be skipped ('optional').
339 323 cc = new_compiler()
340 324 if hasfunction(cc, 'inotify_add_watch'):
341 325 inotify = Extension('hgext.inotify.linux._inotify',
342 326 ['hgext/inotify/linux/_inotify.c'],
343 327 ['mercurial'])
344 328 inotify.optional = True
345 329 extmodules.append(inotify)
346 330 packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
347 331
348 332 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
349 333 'help/*.txt']}
350 334
351 335 def ordinarypath(p):
352 336 return p and p[0] != '.' and p[-1] != '~'
353 337
354 338 for root in ('templates',):
355 339 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
356 340 curdir = curdir.split(os.sep, 1)[1]
357 341 dirs[:] = filter(ordinarypath, dirs)
358 342 for f in filter(ordinarypath, files):
359 343 f = os.path.join(curdir, f)
360 344 packagedata['mercurial'].append(f)
361 345
362 346 datafiles = []
363 347 setupversion = version
364 348 extra = {}
365 349
366 350 if py2exeloaded:
367 351 extra['console'] = [
368 352 {'script':'hg',
369 353 'copyright':'Copyright (C) 2005-2010 Matt Mackall and others',
370 354 'product_version':version}]
371 355
372 356 if os.name == 'nt':
373 357 # Windows binary file versions for exe/dll files must have the
374 358 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
375 359 setupversion = version.split('+', 1)[0]
376 360
377 361 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
378 362 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
379 363 # distutils.sysconfig
380 364 version = runcmd(['/usr/bin/xcodebuild', '-version'], {}).splitlines()[0]
381 365 # Also parse only first digit, because 3.2.1 can't be parsed nicely
382 366 if (version.startswith('Xcode') and
383 367 StrictVersion(version.split()[1]) >= StrictVersion('4.0')):
384 368 os.environ['ARCHFLAGS'] = '-arch i386 -arch x86_64'
385 369
386 370 setup(name='mercurial',
387 371 version=setupversion,
388 372 author='Matt Mackall',
389 373 author_email='mpm@selenic.com',
390 374 url='http://mercurial.selenic.com/',
391 375 description='Scalable distributed SCM',
392 376 license='GNU GPLv2+',
393 377 scripts=scripts,
394 378 packages=packages,
395 379 py_modules=pymodules,
396 380 ext_modules=extmodules,
397 381 data_files=datafiles,
398 382 package_data=packagedata,
399 383 cmdclass=cmdclass,
400 384 options=dict(py2exe=dict(packages=['hgext', 'email']),
401 385 bdist_mpkg=dict(zipdist=True,
402 386 license='COPYING',
403 387 readme='contrib/macosx/Readme.html',
404 388 welcome='contrib/macosx/Welcome.html')),
405 389 **extra)
General Comments 0
You need to be logged in to leave comments. Login now