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