You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wheel.py 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import
  3. import logging
  4. import os
  5. from pip._internal.cache import WheelCache
  6. from pip._internal.cli import cmdoptions
  7. from pip._internal.cli.base_command import RequirementCommand
  8. from pip._internal.exceptions import CommandError, PreviousBuildDirError
  9. from pip._internal.operations.prepare import RequirementPreparer
  10. from pip._internal.req import RequirementSet
  11. from pip._internal.req.req_tracker import RequirementTracker
  12. from pip._internal.resolve import Resolver
  13. from pip._internal.utils.temp_dir import TempDirectory
  14. from pip._internal.wheel import WheelBuilder
  15. logger = logging.getLogger(__name__)
  16. class WheelCommand(RequirementCommand):
  17. """
  18. Build Wheel archives for your requirements and dependencies.
  19. Wheel is a built-package format, and offers the advantage of not
  20. recompiling your software during every install. For more details, see the
  21. wheel docs: https://wheel.readthedocs.io/en/latest/
  22. Requirements: setuptools>=0.8, and wheel.
  23. 'pip wheel' uses the bdist_wheel setuptools extension from the wheel
  24. package to build individual wheels.
  25. """
  26. name = 'wheel'
  27. usage = """
  28. %prog [options] <requirement specifier> ...
  29. %prog [options] -r <requirements file> ...
  30. %prog [options] [-e] <vcs project url> ...
  31. %prog [options] [-e] <local project path> ...
  32. %prog [options] <archive url/path> ..."""
  33. summary = 'Build wheels from your requirements.'
  34. def __init__(self, *args, **kw):
  35. super(WheelCommand, self).__init__(*args, **kw)
  36. cmd_opts = self.cmd_opts
  37. cmd_opts.add_option(
  38. '-w', '--wheel-dir',
  39. dest='wheel_dir',
  40. metavar='dir',
  41. default=os.curdir,
  42. help=("Build wheels into <dir>, where the default is the "
  43. "current working directory."),
  44. )
  45. cmd_opts.add_option(cmdoptions.no_binary())
  46. cmd_opts.add_option(cmdoptions.only_binary())
  47. cmd_opts.add_option(cmdoptions.prefer_binary())
  48. cmd_opts.add_option(
  49. '--build-option',
  50. dest='build_options',
  51. metavar='options',
  52. action='append',
  53. help="Extra arguments to be supplied to 'setup.py bdist_wheel'.",
  54. )
  55. cmd_opts.add_option(cmdoptions.no_build_isolation())
  56. cmd_opts.add_option(cmdoptions.use_pep517())
  57. cmd_opts.add_option(cmdoptions.no_use_pep517())
  58. cmd_opts.add_option(cmdoptions.constraints())
  59. cmd_opts.add_option(cmdoptions.editable())
  60. cmd_opts.add_option(cmdoptions.requirements())
  61. cmd_opts.add_option(cmdoptions.src())
  62. cmd_opts.add_option(cmdoptions.ignore_requires_python())
  63. cmd_opts.add_option(cmdoptions.no_deps())
  64. cmd_opts.add_option(cmdoptions.build_dir())
  65. cmd_opts.add_option(cmdoptions.progress_bar())
  66. cmd_opts.add_option(
  67. '--global-option',
  68. dest='global_options',
  69. action='append',
  70. metavar='options',
  71. help="Extra global options to be supplied to the setup.py "
  72. "call before the 'bdist_wheel' command.")
  73. cmd_opts.add_option(
  74. '--pre',
  75. action='store_true',
  76. default=False,
  77. help=("Include pre-release and development versions. By default, "
  78. "pip only finds stable versions."),
  79. )
  80. cmd_opts.add_option(cmdoptions.no_clean())
  81. cmd_opts.add_option(cmdoptions.require_hashes())
  82. index_opts = cmdoptions.make_option_group(
  83. cmdoptions.index_group,
  84. self.parser,
  85. )
  86. self.parser.insert_option_group(0, index_opts)
  87. self.parser.insert_option_group(0, cmd_opts)
  88. def run(self, options, args):
  89. cmdoptions.check_install_build_global(options)
  90. index_urls = [options.index_url] + options.extra_index_urls
  91. if options.no_index:
  92. logger.debug('Ignoring indexes: %s', ','.join(index_urls))
  93. index_urls = []
  94. if options.build_dir:
  95. options.build_dir = os.path.abspath(options.build_dir)
  96. options.src_dir = os.path.abspath(options.src_dir)
  97. with self._build_session(options) as session:
  98. finder = self._build_package_finder(options, session)
  99. build_delete = (not (options.no_clean or options.build_dir))
  100. wheel_cache = WheelCache(options.cache_dir, options.format_control)
  101. with RequirementTracker() as req_tracker, TempDirectory(
  102. options.build_dir, delete=build_delete, kind="wheel"
  103. ) as directory:
  104. requirement_set = RequirementSet(
  105. require_hashes=options.require_hashes,
  106. )
  107. try:
  108. self.populate_requirement_set(
  109. requirement_set, args, options, finder, session,
  110. self.name, wheel_cache
  111. )
  112. preparer = RequirementPreparer(
  113. build_dir=directory.path,
  114. src_dir=options.src_dir,
  115. download_dir=None,
  116. wheel_download_dir=options.wheel_dir,
  117. progress_bar=options.progress_bar,
  118. build_isolation=options.build_isolation,
  119. req_tracker=req_tracker,
  120. )
  121. resolver = Resolver(
  122. preparer=preparer,
  123. finder=finder,
  124. session=session,
  125. wheel_cache=wheel_cache,
  126. use_user_site=False,
  127. upgrade_strategy="to-satisfy-only",
  128. force_reinstall=False,
  129. ignore_dependencies=options.ignore_dependencies,
  130. ignore_requires_python=options.ignore_requires_python,
  131. ignore_installed=True,
  132. isolated=options.isolated_mode,
  133. use_pep517=options.use_pep517
  134. )
  135. resolver.resolve(requirement_set)
  136. # build wheels
  137. wb = WheelBuilder(
  138. finder, preparer, wheel_cache,
  139. build_options=options.build_options or [],
  140. global_options=options.global_options or [],
  141. no_clean=options.no_clean,
  142. )
  143. build_failures = wb.build(
  144. requirement_set.requirements.values(), session=session,
  145. )
  146. if len(build_failures) != 0:
  147. raise CommandError(
  148. "Failed to build one or more wheels"
  149. )
  150. except PreviousBuildDirError:
  151. options.no_clean = True
  152. raise
  153. finally:
  154. if not options.no_clean:
  155. requirement_set.cleanup_files()
  156. wheel_cache.cleanup()