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