##// END OF EJS Templates
setup: add missing hgext.fsmonitor...
Sean Farley -
r28625:776fd2e2 default
parent child Browse files
Show More
@@ -1,677 +1,678 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, platform
8 8 if getattr(sys, 'version_info', (0, 0, 0)) < (2, 6, 0, 'final'):
9 9 raise SystemExit("Mercurial requires Python 2.6 or later.")
10 10
11 11 if sys.version_info[0] >= 3:
12 12 printf = eval('print')
13 13 libdir_escape = 'unicode_escape'
14 14 else:
15 15 libdir_escape = 'string_escape'
16 16 def printf(*args, **kwargs):
17 17 f = kwargs.get('file', sys.stdout)
18 18 end = kwargs.get('end', '\n')
19 19 f.write(b' '.join(args) + end)
20 20
21 21 # Solaris Python packaging brain damage
22 22 try:
23 23 import hashlib
24 24 sha = hashlib.sha1()
25 25 except ImportError:
26 26 try:
27 27 import sha
28 28 sha.sha # silence unused import warning
29 29 except ImportError:
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 zlib.compressobj # silence unused import warning
36 36 except ImportError:
37 37 raise SystemExit(
38 38 "Couldn't import standard zlib (incomplete Python install).")
39 39
40 40 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
41 41 isironpython = False
42 42 try:
43 43 isironpython = (platform.python_implementation()
44 44 .lower().find("ironpython") != -1)
45 45 except AttributeError:
46 46 pass
47 47
48 48 if isironpython:
49 49 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
50 50 else:
51 51 try:
52 52 import bz2
53 53 bz2.BZ2Compressor # silence unused import warning
54 54 except ImportError:
55 55 raise SystemExit(
56 56 "Couldn't import standard bz2 (incomplete Python install).")
57 57
58 58 ispypy = "PyPy" in sys.version
59 59
60 60 import os, stat, subprocess, time
61 61 import re
62 62 import shutil
63 63 import tempfile
64 64 from distutils import log
65 65 if 'FORCE_SETUPTOOLS' in os.environ:
66 66 from setuptools import setup
67 67 else:
68 68 from distutils.core import setup
69 69 from distutils.core import Command, Extension
70 70 from distutils.dist import Distribution
71 71 from distutils.command.build import build
72 72 from distutils.command.build_ext import build_ext
73 73 from distutils.command.build_py import build_py
74 74 from distutils.command.build_scripts import build_scripts
75 75 from distutils.command.install_lib import install_lib
76 76 from distutils.command.install_scripts import install_scripts
77 77 from distutils.spawn import spawn, find_executable
78 78 from distutils import file_util
79 79 from distutils.errors import (
80 80 CCompilerError,
81 81 DistutilsError,
82 82 DistutilsExecError,
83 83 )
84 84 from distutils.sysconfig import get_python_inc, get_config_var
85 85 from distutils.version import StrictVersion
86 86
87 87 scripts = ['hg']
88 88 if os.name == 'nt':
89 89 # We remove hg.bat if we are able to build hg.exe.
90 90 scripts.append('contrib/win32/hg.bat')
91 91
92 92 # simplified version of distutils.ccompiler.CCompiler.has_function
93 93 # that actually removes its temporary files.
94 94 def hasfunction(cc, funcname):
95 95 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
96 96 devnull = oldstderr = None
97 97 try:
98 98 fname = os.path.join(tmpdir, 'funcname.c')
99 99 f = open(fname, 'w')
100 100 f.write('int main(void) {\n')
101 101 f.write(' %s();\n' % funcname)
102 102 f.write('}\n')
103 103 f.close()
104 104 # Redirect stderr to /dev/null to hide any error messages
105 105 # from the compiler.
106 106 # This will have to be changed if we ever have to check
107 107 # for a function on Windows.
108 108 devnull = open('/dev/null', 'w')
109 109 oldstderr = os.dup(sys.stderr.fileno())
110 110 os.dup2(devnull.fileno(), sys.stderr.fileno())
111 111 objects = cc.compile([fname], output_dir=tmpdir)
112 112 cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
113 113 return True
114 114 except Exception:
115 115 return False
116 116 finally:
117 117 if oldstderr is not None:
118 118 os.dup2(oldstderr, sys.stderr.fileno())
119 119 if devnull is not None:
120 120 devnull.close()
121 121 shutil.rmtree(tmpdir)
122 122
123 123 # py2exe needs to be installed to work
124 124 try:
125 125 import py2exe
126 126 py2exe.Distribution # silence unused import warning
127 127 py2exeloaded = True
128 128 # import py2exe's patched Distribution class
129 129 from distutils.core import Distribution
130 130 except ImportError:
131 131 py2exeloaded = False
132 132
133 133 def runcmd(cmd, env):
134 134 if (sys.platform == 'plan9'
135 135 and (sys.version_info[0] == 2 and sys.version_info[1] < 7)):
136 136 # subprocess kludge to work around issues in half-baked Python
137 137 # ports, notably bichued/python:
138 138 _, out, err = os.popen3(cmd)
139 139 return str(out), str(err)
140 140 else:
141 141 p = subprocess.Popen(cmd, stdout=subprocess.PIPE,
142 142 stderr=subprocess.PIPE, env=env)
143 143 out, err = p.communicate()
144 144 return out, err
145 145
146 146 def runhg(cmd, env):
147 147 out, err = runcmd(cmd, env)
148 148 # If root is executing setup.py, but the repository is owned by
149 149 # another user (as in "sudo python setup.py install") we will get
150 150 # trust warnings since the .hg/hgrc file is untrusted. That is
151 151 # fine, we don't want to load it anyway. Python may warn about
152 152 # a missing __init__.py in mercurial/locale, we also ignore that.
153 153 err = [e for e in err.splitlines()
154 154 if not e.startswith(b'not trusting file') \
155 155 and not e.startswith(b'warning: Not importing') \
156 156 and not e.startswith(b'obsolete feature not enabled')]
157 157 if err:
158 158 printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
159 159 printf(b'\n'.join([b' ' + e for e in err]), file=sys.stderr)
160 160 return ''
161 161 return out
162 162
163 163 version = ''
164 164
165 165 # Execute hg out of this directory with a custom environment which takes care
166 166 # to not use any hgrc files and do no localization.
167 167 env = {'HGMODULEPOLICY': 'py',
168 168 'HGRCPATH': '',
169 169 'LANGUAGE': 'C'}
170 170 if 'LD_LIBRARY_PATH' in os.environ:
171 171 env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
172 172 if 'SystemRoot' in os.environ:
173 173 # Copy SystemRoot into the custom environment for Python 2.6
174 174 # under Windows. Otherwise, the subprocess will fail with
175 175 # error 0xc0150004. See: http://bugs.python.org/issue3440
176 176 env['SystemRoot'] = os.environ['SystemRoot']
177 177
178 178 if os.path.isdir('.hg'):
179 179 cmd = [sys.executable, 'hg', 'log', '-r', '.', '--template', '{tags}\n']
180 180 numerictags = [t for t in runhg(cmd, env).split() if t[0].isdigit()]
181 181 hgid = runhg([sys.executable, 'hg', 'id', '-i'], env).strip()
182 182 if numerictags: # tag(s) found
183 183 version = numerictags[-1]
184 184 if hgid.endswith('+'): # propagate the dirty status to the tag
185 185 version += '+'
186 186 else: # no tag found
187 187 ltagcmd = [sys.executable, 'hg', 'parents', '--template',
188 188 '{latesttag}']
189 189 ltag = runhg(ltagcmd, env)
190 190 changessincecmd = [sys.executable, 'hg', 'log', '-T', 'x\n', '-r',
191 191 "only(.,'%s')" % ltag]
192 192 changessince = len(runhg(changessincecmd, env).splitlines())
193 193 version = '%s+%s-%s' % (ltag, changessince, hgid)
194 194 if version.endswith('+'):
195 195 version += time.strftime('%Y%m%d')
196 196 elif os.path.exists('.hg_archival.txt'):
197 197 kw = dict([[t.strip() for t in l.split(':', 1)]
198 198 for l in open('.hg_archival.txt')])
199 199 if 'tag' in kw:
200 200 version = kw['tag']
201 201 elif 'latesttag' in kw:
202 202 if 'changessincelatesttag' in kw:
203 203 version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
204 204 else:
205 205 version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
206 206 else:
207 207 version = kw.get('node', '')[:12]
208 208
209 209 if version:
210 210 with open("mercurial/__version__.py", "w") as f:
211 211 f.write('# this file is autogenerated by setup.py\n')
212 212 f.write('version = "%s"\n' % version)
213 213
214 214 try:
215 215 oldpolicy = os.environ.get('HGMODULEPOLICY', None)
216 216 os.environ['HGMODULEPOLICY'] = 'py'
217 217 from mercurial import __version__
218 218 version = __version__.version
219 219 except ImportError:
220 220 version = 'unknown'
221 221 finally:
222 222 if oldpolicy is None:
223 223 del os.environ['HGMODULEPOLICY']
224 224 else:
225 225 os.environ['HGMODULEPOLICY'] = oldpolicy
226 226
227 227 class hgbuild(build):
228 228 # Insert hgbuildmo first so that files in mercurial/locale/ are found
229 229 # when build_py is run next.
230 230 sub_commands = [('build_mo', None)] + build.sub_commands
231 231
232 232 class hgbuildmo(build):
233 233
234 234 description = "build translations (.mo files)"
235 235
236 236 def run(self):
237 237 if not find_executable('msgfmt'):
238 238 self.warn("could not find msgfmt executable, no translations "
239 239 "will be built")
240 240 return
241 241
242 242 podir = 'i18n'
243 243 if not os.path.isdir(podir):
244 244 self.warn("could not find %s/ directory" % podir)
245 245 return
246 246
247 247 join = os.path.join
248 248 for po in os.listdir(podir):
249 249 if not po.endswith('.po'):
250 250 continue
251 251 pofile = join(podir, po)
252 252 modir = join('locale', po[:-3], 'LC_MESSAGES')
253 253 mofile = join(modir, 'hg.mo')
254 254 mobuildfile = join('mercurial', mofile)
255 255 cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
256 256 if sys.platform != 'sunos5':
257 257 # msgfmt on Solaris does not know about -c
258 258 cmd.append('-c')
259 259 self.mkpath(join('mercurial', modir))
260 260 self.make_file([pofile], mobuildfile, spawn, (cmd,))
261 261
262 262
263 263 class hgdist(Distribution):
264 264 pure = ispypy
265 265
266 266 global_options = Distribution.global_options + \
267 267 [('pure', None, "use pure (slow) Python "
268 268 "code instead of C extensions"),
269 269 ]
270 270
271 271 def has_ext_modules(self):
272 272 # self.ext_modules is emptied in hgbuildpy.finalize_options which is
273 273 # too late for some cases
274 274 return not self.pure and Distribution.has_ext_modules(self)
275 275
276 276 class hgbuildext(build_ext):
277 277
278 278 def build_extension(self, ext):
279 279 try:
280 280 build_ext.build_extension(self, ext)
281 281 except CCompilerError:
282 282 if not getattr(ext, 'optional', False):
283 283 raise
284 284 log.warn("Failed to build optional extension '%s' (skipping)",
285 285 ext.name)
286 286
287 287 class hgbuildscripts(build_scripts):
288 288 def run(self):
289 289 if os.name != 'nt' or self.distribution.pure:
290 290 return build_scripts.run(self)
291 291
292 292 exebuilt = False
293 293 try:
294 294 self.run_command('build_hgexe')
295 295 exebuilt = True
296 296 except (DistutilsError, CCompilerError):
297 297 log.warn('failed to build optional hg.exe')
298 298
299 299 if exebuilt:
300 300 # Copying hg.exe to the scripts build directory ensures it is
301 301 # installed by the install_scripts command.
302 302 hgexecommand = self.get_finalized_command('build_hgexe')
303 303 dest = os.path.join(self.build_dir, 'hg.exe')
304 304 self.mkpath(self.build_dir)
305 305 self.copy_file(hgexecommand.hgexepath, dest)
306 306
307 307 # Remove hg.bat because it is redundant with hg.exe.
308 308 self.scripts.remove('contrib/win32/hg.bat')
309 309
310 310 return build_scripts.run(self)
311 311
312 312 class hgbuildpy(build_py):
313 313 def finalize_options(self):
314 314 build_py.finalize_options(self)
315 315
316 316 if self.distribution.pure:
317 317 self.distribution.ext_modules = []
318 318 else:
319 319 h = os.path.join(get_python_inc(), 'Python.h')
320 320 if not os.path.exists(h):
321 321 raise SystemExit('Python headers are required to build '
322 322 'Mercurial but weren\'t found in %s' % h)
323 323
324 324 def run(self):
325 325 if self.distribution.pure:
326 326 modulepolicy = 'py'
327 327 else:
328 328 modulepolicy = 'c'
329 329 with open("mercurial/__modulepolicy__.py", "w") as f:
330 330 f.write('# this file is autogenerated by setup.py\n')
331 331 f.write('modulepolicy = "%s"\n' % modulepolicy)
332 332
333 333 build_py.run(self)
334 334
335 335 class buildhgextindex(Command):
336 336 description = 'generate prebuilt index of hgext (for frozen package)'
337 337 user_options = []
338 338 _indexfilename = 'hgext/__index__.py'
339 339
340 340 def initialize_options(self):
341 341 pass
342 342
343 343 def finalize_options(self):
344 344 pass
345 345
346 346 def run(self):
347 347 if os.path.exists(self._indexfilename):
348 348 with open(self._indexfilename, 'w') as f:
349 349 f.write('# empty\n')
350 350
351 351 # here no extension enabled, disabled() lists up everything
352 352 code = ('import pprint; from mercurial import extensions; '
353 353 'pprint.pprint(extensions.disabled())')
354 354 out, err = runcmd([sys.executable, '-c', code], env)
355 355 if err:
356 356 raise DistutilsExecError(err)
357 357
358 358 with open(self._indexfilename, 'w') as f:
359 359 f.write('# this file is autogenerated by setup.py\n')
360 360 f.write('docs = ')
361 361 f.write(out)
362 362
363 363 class buildhgexe(build_ext):
364 364 description = 'compile hg.exe from mercurial/exewrapper.c'
365 365
366 366 def build_extensions(self):
367 367 if os.name != 'nt':
368 368 return
369 369 if isinstance(self.compiler, HackedMingw32CCompiler):
370 370 self.compiler.compiler_so = self.compiler.compiler # no -mdll
371 371 self.compiler.dll_libraries = [] # no -lmsrvc90
372 372 hv = sys.hexversion
373 373 pythonlib = 'python%d%d' % (hv >> 24, (hv >> 16) & 0xff)
374 374 with open('mercurial/hgpythonlib.h', 'wb') as f:
375 375 f.write('/* this file is autogenerated by setup.py */\n')
376 376 f.write('#define HGPYTHONLIB "%s"\n' % pythonlib)
377 377 objects = self.compiler.compile(['mercurial/exewrapper.c'],
378 378 output_dir=self.build_temp)
379 379 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
380 380 target = os.path.join(dir, 'hg')
381 381 self.compiler.link_executable(objects, target,
382 382 libraries=[],
383 383 output_dir=self.build_temp)
384 384
385 385 @property
386 386 def hgexepath(self):
387 387 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
388 388 return os.path.join(self.build_temp, dir, 'hg.exe')
389 389
390 390 class hginstalllib(install_lib):
391 391 '''
392 392 This is a specialization of install_lib that replaces the copy_file used
393 393 there so that it supports setting the mode of files after copying them,
394 394 instead of just preserving the mode that the files originally had. If your
395 395 system has a umask of something like 027, preserving the permissions when
396 396 copying will lead to a broken install.
397 397
398 398 Note that just passing keep_permissions=False to copy_file would be
399 399 insufficient, as it might still be applying a umask.
400 400 '''
401 401
402 402 def run(self):
403 403 realcopyfile = file_util.copy_file
404 404 def copyfileandsetmode(*args, **kwargs):
405 405 src, dst = args[0], args[1]
406 406 dst, copied = realcopyfile(*args, **kwargs)
407 407 if copied:
408 408 st = os.stat(src)
409 409 # Persist executable bit (apply it to group and other if user
410 410 # has it)
411 411 if st[stat.ST_MODE] & stat.S_IXUSR:
412 412 setmode = int('0755', 8)
413 413 else:
414 414 setmode = int('0644', 8)
415 415 m = stat.S_IMODE(st[stat.ST_MODE])
416 416 m = (m & ~int('0777', 8)) | setmode
417 417 os.chmod(dst, m)
418 418 file_util.copy_file = copyfileandsetmode
419 419 try:
420 420 install_lib.run(self)
421 421 finally:
422 422 file_util.copy_file = realcopyfile
423 423
424 424 class hginstallscripts(install_scripts):
425 425 '''
426 426 This is a specialization of install_scripts that replaces the @LIBDIR@ with
427 427 the configured directory for modules. If possible, the path is made relative
428 428 to the directory for scripts.
429 429 '''
430 430
431 431 def initialize_options(self):
432 432 install_scripts.initialize_options(self)
433 433
434 434 self.install_lib = None
435 435
436 436 def finalize_options(self):
437 437 install_scripts.finalize_options(self)
438 438 self.set_undefined_options('install',
439 439 ('install_lib', 'install_lib'))
440 440
441 441 def run(self):
442 442 install_scripts.run(self)
443 443
444 444 # It only makes sense to replace @LIBDIR@ with the install path if
445 445 # the install path is known. For wheels, the logic below calculates
446 446 # the libdir to be "../..". This is because the internal layout of a
447 447 # wheel archive looks like:
448 448 #
449 449 # mercurial-3.6.1.data/scripts/hg
450 450 # mercurial/__init__.py
451 451 #
452 452 # When installing wheels, the subdirectories of the "<pkg>.data"
453 453 # directory are translated to system local paths and files therein
454 454 # are copied in place. The mercurial/* files are installed into the
455 455 # site-packages directory. However, the site-packages directory
456 456 # isn't known until wheel install time. This means we have no clue
457 457 # at wheel generation time what the installed site-packages directory
458 458 # will be. And, wheels don't appear to provide the ability to register
459 459 # custom code to run during wheel installation. This all means that
460 460 # we can't reliably set the libdir in wheels: the default behavior
461 461 # of looking in sys.path must do.
462 462
463 463 if (os.path.splitdrive(self.install_dir)[0] !=
464 464 os.path.splitdrive(self.install_lib)[0]):
465 465 # can't make relative paths from one drive to another, so use an
466 466 # absolute path instead
467 467 libdir = self.install_lib
468 468 else:
469 469 common = os.path.commonprefix((self.install_dir, self.install_lib))
470 470 rest = self.install_dir[len(common):]
471 471 uplevel = len([n for n in os.path.split(rest) if n])
472 472
473 473 libdir = uplevel * ('..' + os.sep) + self.install_lib[len(common):]
474 474
475 475 for outfile in self.outfiles:
476 476 with open(outfile, 'rb') as fp:
477 477 data = fp.read()
478 478
479 479 # skip binary files
480 480 if b'\0' in data:
481 481 continue
482 482
483 483 # During local installs, the shebang will be rewritten to the final
484 484 # install path. During wheel packaging, the shebang has a special
485 485 # value.
486 486 if data.startswith(b'#!python'):
487 487 log.info('not rewriting @LIBDIR@ in %s because install path '
488 488 'not known' % outfile)
489 489 continue
490 490
491 491 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
492 492 with open(outfile, 'wb') as fp:
493 493 fp.write(data)
494 494
495 495 cmdclass = {'build': hgbuild,
496 496 'build_mo': hgbuildmo,
497 497 'build_ext': hgbuildext,
498 498 'build_py': hgbuildpy,
499 499 'build_scripts': hgbuildscripts,
500 500 'build_hgextindex': buildhgextindex,
501 501 'install_lib': hginstalllib,
502 502 'install_scripts': hginstallscripts,
503 503 'build_hgexe': buildhgexe,
504 504 }
505 505
506 506 packages = ['mercurial', 'mercurial.hgweb', 'mercurial.httpclient',
507 507 'mercurial.pure',
508 'hgext', 'hgext.convert', 'hgext.highlight', 'hgext.largefiles',
509 'hgext.zeroconf', 'hgext3rd']
508 'hgext', 'hgext.convert', 'hgext.fsmonitor',
509 'hgext.fsmonitor.pywatchman', 'hgext.highlight',
510 'hgext.largefiles', 'hgext.zeroconf', 'hgext3rd']
510 511
511 512 common_depends = ['mercurial/util.h']
512 513
513 514 osutil_ldflags = []
514 515
515 516 if sys.platform == 'darwin':
516 517 osutil_ldflags += ['-framework', 'ApplicationServices']
517 518
518 519 extmodules = [
519 520 Extension('mercurial.base85', ['mercurial/base85.c'],
520 521 depends=common_depends),
521 522 Extension('mercurial.bdiff', ['mercurial/bdiff.c'],
522 523 depends=common_depends),
523 524 Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c'],
524 525 depends=common_depends),
525 526 Extension('mercurial.mpatch', ['mercurial/mpatch.c'],
526 527 depends=common_depends),
527 528 Extension('mercurial.parsers', ['mercurial/dirs.c',
528 529 'mercurial/manifest.c',
529 530 'mercurial/parsers.c',
530 531 'mercurial/pathencode.c'],
531 532 depends=common_depends),
532 533 Extension('mercurial.osutil', ['mercurial/osutil.c'],
533 534 extra_link_args=osutil_ldflags,
534 535 depends=common_depends),
535 536 Extension('hgext.fsmonitor.pywatchman.bser',
536 537 ['hgext/fsmonitor/pywatchman/bser.c']),
537 538 ]
538 539
539 540 try:
540 541 from distutils import cygwinccompiler
541 542
542 543 # the -mno-cygwin option has been deprecated for years
543 544 compiler = cygwinccompiler.Mingw32CCompiler
544 545
545 546 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
546 547 def __init__(self, *args, **kwargs):
547 548 compiler.__init__(self, *args, **kwargs)
548 549 for i in 'compiler compiler_so linker_exe linker_so'.split():
549 550 try:
550 551 getattr(self, i).remove('-mno-cygwin')
551 552 except ValueError:
552 553 pass
553 554
554 555 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
555 556 except ImportError:
556 557 # the cygwinccompiler package is not available on some Python
557 558 # distributions like the ones from the optware project for Synology
558 559 # DiskStation boxes
559 560 class HackedMingw32CCompiler(object):
560 561 pass
561 562
562 563 packagedata = {'mercurial': ['locale/*/LC_MESSAGES/hg.mo',
563 564 'help/*.txt',
564 565 'help/internals/*.txt',
565 566 'default.d/*.rc',
566 567 'dummycert.pem']}
567 568
568 569 def ordinarypath(p):
569 570 return p and p[0] != '.' and p[-1] != '~'
570 571
571 572 for root in ('templates',):
572 573 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
573 574 curdir = curdir.split(os.sep, 1)[1]
574 575 dirs[:] = filter(ordinarypath, dirs)
575 576 for f in filter(ordinarypath, files):
576 577 f = os.path.join(curdir, f)
577 578 packagedata['mercurial'].append(f)
578 579
579 580 datafiles = []
580 581 setupversion = version
581 582 extra = {}
582 583
583 584 if py2exeloaded:
584 585 extra['console'] = [
585 586 {'script':'hg',
586 587 'copyright':'Copyright (C) 2005-2016 Matt Mackall and others',
587 588 'product_version':version}]
588 589 # sub command of 'build' because 'py2exe' does not handle sub_commands
589 590 build.sub_commands.insert(0, ('build_hgextindex', None))
590 591 # put dlls in sub directory so that they won't pollute PATH
591 592 extra['zipfile'] = 'lib/library.zip'
592 593
593 594 if os.name == 'nt':
594 595 # Windows binary file versions for exe/dll files must have the
595 596 # form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
596 597 setupversion = version.split('+', 1)[0]
597 598
598 599 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
599 600 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[0].splitlines()
600 601 if version:
601 602 version = version[0]
602 603 if sys.version_info[0] == 3:
603 604 version = version.decode('utf-8')
604 605 xcode4 = (version.startswith('Xcode') and
605 606 StrictVersion(version.split()[1]) >= StrictVersion('4.0'))
606 607 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
607 608 else:
608 609 # xcodebuild returns empty on OS X Lion with XCode 4.3 not
609 610 # installed, but instead with only command-line tools. Assume
610 611 # that only happens on >= Lion, thus no PPC support.
611 612 xcode4 = True
612 613 xcode51 = False
613 614
614 615 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
615 616 # distutils.sysconfig
616 617 if xcode4:
617 618 os.environ['ARCHFLAGS'] = ''
618 619
619 620 # XCode 5.1 changes clang such that it now fails to compile if the
620 621 # -mno-fused-madd flag is passed, but the version of Python shipped with
621 622 # OS X 10.9 Mavericks includes this flag. This causes problems in all
622 623 # C extension modules, and a bug has been filed upstream at
623 624 # http://bugs.python.org/issue21244. We also need to patch this here
624 625 # so Mercurial can continue to compile in the meantime.
625 626 if xcode51:
626 627 cflags = get_config_var('CFLAGS')
627 628 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
628 629 os.environ['CFLAGS'] = (
629 630 os.environ.get('CFLAGS', '') + ' -Qunused-arguments')
630 631
631 632 setup(name='mercurial',
632 633 version=setupversion,
633 634 author='Matt Mackall and many others',
634 635 author_email='mercurial@selenic.com',
635 636 url='https://mercurial-scm.org/',
636 637 download_url='https://mercurial-scm.org/release/',
637 638 description=('Fast scalable distributed SCM (revision control, version '
638 639 'control) system'),
639 640 long_description=('Mercurial is a distributed SCM tool written in Python.'
640 641 ' It is used by a number of large projects that require'
641 642 ' fast, reliable distributed revision control, such as '
642 643 'Mozilla.'),
643 644 license='GNU GPLv2 or any later version',
644 645 classifiers=[
645 646 'Development Status :: 6 - Mature',
646 647 'Environment :: Console',
647 648 'Intended Audience :: Developers',
648 649 'Intended Audience :: System Administrators',
649 650 'License :: OSI Approved :: GNU General Public License (GPL)',
650 651 'Natural Language :: Danish',
651 652 'Natural Language :: English',
652 653 'Natural Language :: German',
653 654 'Natural Language :: Italian',
654 655 'Natural Language :: Japanese',
655 656 'Natural Language :: Portuguese (Brazilian)',
656 657 'Operating System :: Microsoft :: Windows',
657 658 'Operating System :: OS Independent',
658 659 'Operating System :: POSIX',
659 660 'Programming Language :: C',
660 661 'Programming Language :: Python',
661 662 'Topic :: Software Development :: Version Control',
662 663 ],
663 664 scripts=scripts,
664 665 packages=packages,
665 666 ext_modules=extmodules,
666 667 data_files=datafiles,
667 668 package_data=packagedata,
668 669 cmdclass=cmdclass,
669 670 distclass=hgdist,
670 671 options={'py2exe': {'packages': ['hgext', 'email']},
671 672 'bdist_mpkg': {'zipdist': False,
672 673 'license': 'COPYING',
673 674 'readme': 'contrib/macosx/Readme.html',
674 675 'welcome': 'contrib/macosx/Welcome.html',
675 676 },
676 677 },
677 678 **extra)
General Comments 0
You need to be logged in to leave comments. Login now