Beispiel #1
0
 def _build_source_pex(self, interpreter, path, targets):
   pex_builder = PexBuilderWrapper.Factory.create(
     builder=PEXBuilder(path=path, interpreter=interpreter, copy=True),
     log=self.context.log)
   for target in targets:
     if has_python_sources(target):
       pex_builder.add_sources_from(target)
   pex_builder.freeze()
Beispiel #2
0
 def _build_source_pex(self, interpreter, path, targets):
   pex_builder = PexBuilderWrapper.Factory.create(
     builder=PEXBuilder(path=path, interpreter=interpreter, copy=True),
     log=self.context.log)
   for target in targets:
     if has_python_sources(target):
       pex_builder.add_sources_from(target)
   pex_builder.freeze()
  def _create_binary(self, binary_tgt, results_dir):
    """Create a .pex file for the specified binary target."""
    # Note that we rebuild a chroot from scratch, instead of using the REQUIREMENTS_PEX
    # and PYTHON_SOURCES products, because those products are already-built pexes, and there's
    # no easy way to merge them into a single pex file (for example, they each have a __main__.py,
    # metadata, and so on, which the merging code would have to handle specially).
    interpreter = self.context.products.get_data(PythonInterpreter)
    with temporary_dir() as tmpdir:
      # Create the pex_info for the binary.
      run_info_dict = self.context.run_tracker.run_info.get_as_dict()
      build_properties = PexInfo.make_build_properties()
      build_properties.update(run_info_dict)
      pex_info = binary_tgt.pexinfo.copy()
      pex_info.build_properties = build_properties

      pex_builder = PexBuilderWrapper.Factory.create(
        builder=PEXBuilder(path=tmpdir, interpreter=interpreter, pex_info=pex_info, copy=True),
        log=self.context.log)

      if binary_tgt.shebang:
        self.context.log.info('Found Python binary target {} with customized shebang, using it: {}'
          .format(binary_tgt.name, binary_tgt.shebang))
        pex_builder.set_shebang(binary_tgt.shebang)
      else:
        self.context.log.debug('No customized shebang found for {}'.format(binary_tgt.name))

      # Find which targets provide sources and which specify requirements.
      source_tgts = []
      req_tgts = []
      constraint_tgts = []
      for tgt in binary_tgt.closure(exclude_scopes=Scopes.COMPILE):
        if has_python_sources(tgt) or has_resources(tgt):
          source_tgts.append(tgt)
        elif has_python_requirements(tgt):
          req_tgts.append(tgt)
        if is_python_target(tgt):
          constraint_tgts.append(tgt)

      # Add interpreter compatibility constraints to pex info. This will first check the targets for any
      # constraints, and if they do not have any will resort to the global constraints.
      pex_builder.add_interpreter_constraints_from(constraint_tgts)

      # Dump everything into the builder's chroot.
      for tgt in source_tgts:
        pex_builder.add_sources_from(tgt)

      # We need to ensure that we are resolving for only the current platform if we are
      # including local python dist targets that have native extensions.
      self._python_native_code_settings.check_build_for_current_platform_only(self.context.targets())
      pex_builder.add_requirement_libs_from(req_tgts, platforms=binary_tgt.platforms)

      # Build the .pex file.
      pex_path = os.path.join(results_dir, '{}.pex'.format(binary_tgt.name))
      pex_builder.build(pex_path)
      return pex_path
Beispiel #4
0
    def _create_binary(self, binary_tgt, results_dir):
        """Create a .pex file for the specified binary target."""
        # Note that we rebuild a chroot from scratch, instead of using the REQUIREMENTS_PEX
        # and PYTHON_SOURCES products, because those products are already-built pexes, and there's
        # no easy way to merge them into a single pex file (for example, they each have a __main__.py,
        # metadata, and so on, which the merging code would have to handle specially).
        interpreter = self.context.products.get_data(PythonInterpreter)
        with temporary_dir() as tmpdir:
            # Create the pex_info for the binary.
            build_properties = PexInfo.make_build_properties()
            if self.get_options().include_run_information:
                run_info_dict = self.context.run_tracker.run_info.get_as_dict()
                build_properties.update(run_info_dict)
            pex_info = binary_tgt.pexinfo.copy()
            pex_info.build_properties = build_properties

            pex_builder = PexBuilderWrapper.Factory.create(
                builder=PEXBuilder(path=tmpdir,
                                   interpreter=interpreter,
                                   pex_info=pex_info,
                                   copy=True),
                log=self.context.log)

            if binary_tgt.shebang:
                self.context.log.info(
                    'Found Python binary target {} with customized shebang, using it: {}'
                    .format(binary_tgt.name, binary_tgt.shebang))
                pex_builder.set_shebang(binary_tgt.shebang)
            else:
                self.context.log.debug(
                    f'No customized shebang found for {binary_tgt.name}')

            # Find which targets provide sources and which specify requirements.
            source_tgts = []
            req_tgts = []
            constraint_tgts = []
            for tgt in binary_tgt.closure(exclude_scopes=Scopes.COMPILE):
                if has_python_sources(tgt) or has_resources(tgt):
                    source_tgts.append(tgt)
                elif has_python_requirements(tgt):
                    req_tgts.append(tgt)
                if is_python_target(tgt):
                    constraint_tgts.append(tgt)

            # Add interpreter compatibility constraints to pex info. Note that we only add the constraints for the final
            # binary target itself, not its dependencies. The upstream interpreter selection tasks will already validate that
            # there are no compatibility conflicts among the dependencies and target. If the binary target does not have
            # `compatibility` in its BUILD entry, the global --python-setup-interpreter-constraints will be used.
            pex_builder.add_interpreter_constraints_from([binary_tgt])

            # Dump everything into the builder's chroot.
            for tgt in source_tgts:
                pex_builder.add_sources_from(tgt)

            # We need to ensure that we are resolving for only the current platform if we are
            # including local python dist targets that have native extensions.
            self._python_native_code_settings.check_build_for_current_platform_only(
                self.context.targets())
            pex_builder.add_requirement_libs_from(
                req_tgts, platforms=binary_tgt.platforms)

            # Build the .pex file.
            pex_path = os.path.join(results_dir, f'{binary_tgt.name}.pex')
            pex_builder.build(pex_path)
            return pex_path
Beispiel #5
0
 def collect_source_targets(target):
   if has_python_sources(target) or has_resources(target):
     targets.add(target)