77 from distutils.core import Command, Extension |
77 from distutils.core import Command, Extension |
78 from distutils.dist import Distribution |
78 from distutils.dist import Distribution |
79 from distutils.command.build import build |
79 from distutils.command.build import build |
80 from distutils.command.build_ext import build_ext |
80 from distutils.command.build_ext import build_ext |
81 from distutils.command.build_py import build_py |
81 from distutils.command.build_py import build_py |
|
82 from distutils.command.build_scripts import build_scripts |
82 from distutils.command.install_lib import install_lib |
83 from distutils.command.install_lib import install_lib |
83 from distutils.command.install_scripts import install_scripts |
84 from distutils.command.install_scripts import install_scripts |
84 from distutils.spawn import spawn, find_executable |
85 from distutils.spawn import spawn, find_executable |
85 from distutils import file_util |
86 from distutils import file_util |
86 from distutils.errors import CCompilerError, DistutilsExecError |
87 from distutils.errors import ( |
|
88 CCompilerError, |
|
89 DistutilsError, |
|
90 DistutilsExecError, |
|
91 ) |
87 from distutils.sysconfig import get_python_inc, get_config_var |
92 from distutils.sysconfig import get_python_inc, get_config_var |
88 from distutils.version import StrictVersion |
93 from distutils.version import StrictVersion |
89 |
94 |
90 convert2to3 = '--c2to3' in sys.argv |
95 convert2to3 = '--c2to3' in sys.argv |
91 if convert2to3: |
96 if convert2to3: |
100 elif sys.version_info[0] >= 3: |
105 elif sys.version_info[0] >= 3: |
101 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)") |
106 raise SystemExit("setup.py with python3 needs --c2to3 (experimental)") |
102 |
107 |
103 scripts = ['hg'] |
108 scripts = ['hg'] |
104 if os.name == 'nt': |
109 if os.name == 'nt': |
|
110 # We remove hg.bat if we are able to build hg.exe. |
105 scripts.append('contrib/win32/hg.bat') |
111 scripts.append('contrib/win32/hg.bat') |
106 |
112 |
107 # simplified version of distutils.ccompiler.CCompiler.has_function |
113 # simplified version of distutils.ccompiler.CCompiler.has_function |
108 # that actually removes its temporary files. |
114 # that actually removes its temporary files. |
109 def hasfunction(cc, funcname): |
115 def hasfunction(cc, funcname): |
302 if not getattr(ext, 'optional', False): |
308 if not getattr(ext, 'optional', False): |
303 raise |
309 raise |
304 log.warn("Failed to build optional extension '%s' (skipping)", |
310 log.warn("Failed to build optional extension '%s' (skipping)", |
305 ext.name) |
311 ext.name) |
306 |
312 |
|
313 class hgbuildscripts(build_scripts): |
|
314 def run(self): |
|
315 if os.name != 'nt': |
|
316 return build_scripts.run(self) |
|
317 |
|
318 exebuilt = False |
|
319 try: |
|
320 self.run_command('build_hgexe') |
|
321 exebuilt = True |
|
322 except (DistutilsError, CCompilerError): |
|
323 log.warn('failed to build optional hg.exe') |
|
324 |
|
325 if exebuilt: |
|
326 # Copying hg.exe to the scripts build directory ensures it is |
|
327 # installed by the install_scripts command. |
|
328 hgexecommand = self.get_finalized_command('build_hgexe') |
|
329 dest = os.path.join(self.build_dir, 'hg.exe') |
|
330 self.mkpath(self.build_dir) |
|
331 self.copy_file(hgexecommand.hgexepath, dest) |
|
332 |
|
333 # Remove hg.bat because it is redundant with hg.exe. |
|
334 self.scripts.remove('contrib/win32/hg.bat') |
|
335 |
|
336 return build_scripts.run(self) |
|
337 |
307 class hgbuildpy(build_py): |
338 class hgbuildpy(build_py): |
308 if convert2to3: |
339 if convert2to3: |
309 fixer_names = sorted(set(getfixers("lib2to3.fixes") + |
340 fixer_names = sorted(set(getfixers("lib2to3.fixes") + |
310 getfixers("hgfixes"))) |
341 getfixers("hgfixes"))) |
311 |
342 |
386 dir = os.path.dirname(self.get_ext_fullpath('dummy')) |
417 dir = os.path.dirname(self.get_ext_fullpath('dummy')) |
387 target = os.path.join(dir, 'hg') |
418 target = os.path.join(dir, 'hg') |
388 self.compiler.link_executable(objects, target, |
419 self.compiler.link_executable(objects, target, |
389 libraries=[], |
420 libraries=[], |
390 output_dir=self.build_temp) |
421 output_dir=self.build_temp) |
|
422 |
|
423 @property |
|
424 def hgexepath(self): |
|
425 dir = os.path.dirname(self.get_ext_fullpath('dummy')) |
|
426 return os.path.join(self.build_temp, dir, 'hg.exe') |
391 |
427 |
392 class hginstalllib(install_lib): |
428 class hginstalllib(install_lib): |
393 ''' |
429 ''' |
394 This is a specialization of install_lib that replaces the copy_file used |
430 This is a specialization of install_lib that replaces the copy_file used |
395 there so that it supports setting the mode of files after copying them, |
431 there so that it supports setting the mode of files after copying them, |
471 |
507 |
472 cmdclass = {'build': hgbuild, |
508 cmdclass = {'build': hgbuild, |
473 'build_mo': hgbuildmo, |
509 'build_mo': hgbuildmo, |
474 'build_ext': hgbuildext, |
510 'build_ext': hgbuildext, |
475 'build_py': hgbuildpy, |
511 'build_py': hgbuildpy, |
|
512 'build_scripts': hgbuildscripts, |
476 'build_hgextindex': buildhgextindex, |
513 'build_hgextindex': buildhgextindex, |
477 'install_lib': hginstalllib, |
514 'install_lib': hginstalllib, |
478 'install_scripts': hginstallscripts, |
515 'install_scripts': hginstallscripts, |
479 'build_hgexe': buildhgexe, |
516 'build_hgexe': buildhgexe, |
480 } |
517 } |