Beispiel #1
0
    def WriteRules(self, rules, extra_sources, extra_outputs):
        """Write Makefile code for any 'rules' from the gyp input.

    extra_sources: a list that will be filled in with newly generated source
                   files, if any
    extra_outputs: a list that will be filled in with any outputs of these
                   rules (used to make other pieces dependent on these rules)
    """
        if len(rules) == 0:
            return

        for rule in rules:
            if len(rule.get('rule_sources', [])) == 0:
                continue
            name = make.StringToMakefileVariable(
                '%s_%s' % (self.relative_target, rule['rule_name']))
            self.WriteLn('\n### Generated for rule "%s":' % name)
            self.WriteLn('# "%s":' % rule)

            inputs = rule.get('inputs')
            for rule_source in rule.get('rule_sources', []):
                (rule_source_dirname,
                 rule_source_basename) = os.path.split(rule_source)
                (rule_source_root, rule_source_ext) = \
                    os.path.splitext(rule_source_basename)

                outputs = [
                    self.ExpandInputRoot(out, rule_source_root,
                                         rule_source_dirname)
                    for out in rule['outputs']
                ]

                dirs = set()
                for out in outputs:
                    if not out.startswith('$'):
                        print(
                            'WARNING: Rule for target %s writes output to local path %s'
                            % (self.target, out))
                    dir = os.path.dirname(out)
                    if dir:
                        dirs.add(dir)
                extra_outputs += outputs
                if int(rule.get('process_outputs_as_sources', False)):
                    extra_sources.extend(outputs)

                components = []
                for component in rule['action']:
                    component = self.ExpandInputRoot(component,
                                                     rule_source_root,
                                                     rule_source_dirname)
                    if '$(RULE_SOURCES)' in component:
                        component = component.replace('$(RULE_SOURCES)',
                                                      rule_source)
                    components.append(component)

                command = gyp.common.EncodePOSIXShellList(components)
                cd_action = 'cd $(gyp_local_path)/%s; ' % self.path
                command = cd_action + command
                if dirs:
                    command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command

                # We set up a rule to build the first output, and then set up
                # a rule for each additional output to depend on the first.
                outputs = map(self.LocalPathify, outputs)
                main_output = outputs[0]
                self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' %
                             main_output)
                self.WriteLn('%s: gyp_var_prefix := $(GYP_VAR_PREFIX)' %
                             main_output)
                self.WriteLn('%s: gyp_intermediate_dir := '
                             '$(abspath $(gyp_intermediate_dir))' %
                             main_output)
                self.WriteLn('%s: gyp_shared_intermediate_dir := '
                             '$(abspath $(gyp_shared_intermediate_dir))' %
                             main_output)

                # See explanation in WriteActions.
                self.WriteLn('%s: export PATH := '
                             '$(subst $(ANDROID_BUILD_PATHS),,$(PATH))' %
                             main_output)

                main_output_deps = self.LocalPathify(rule_source)
                if inputs:
                    main_output_deps += ' '
                    main_output_deps += ' '.join(
                        [self.LocalPathify(f) for f in inputs])

                self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' %
                             (main_output, main_output_deps))
                self.WriteLn('\t%s\n' % command)
                for output in outputs[1:]:
                    # Make each output depend on the main output, with an empty command
                    # to force make to notice that the mtime has changed.
                    self.WriteLn('%s: %s ;' % (output, main_output))
                self.WriteLn()

        self.WriteLn()
  def WriteActions(self, actions, extra_sources, extra_outputs):
    """Write Makefile code for any 'actions' from the gyp input.

    extra_sources: a list that will be filled in with newly generated source
                   files, if any
    extra_outputs: a list that will be filled in with any outputs of these
                   actions (used to make other pieces dependent on these
                   actions)
    """
    for action in actions:
      name = make.StringToMakefileVariable('%s_%s' % (self.qualified_target,
                                                      action['action_name']))
      self.WriteLn('### Rules for action "%s":' % action['action_name'])
      inputs = action['inputs']
      outputs = action['outputs']

      # Build up a list of outputs.
      # Collect the output dirs we'll need.
      dirs = set()
      for out in outputs:
        if not out.startswith('$'):
          print ('WARNING: Action for target "%s" writes output to local path '
                 '"%s".' % (self.target, out))
        dir = os.path.split(out)[0]
        if dir:
          dirs.add(dir)
      if int(action.get('process_outputs_as_sources', False)):
        extra_sources += outputs

      # Prepare the actual command.
      command = gyp.common.EncodePOSIXShellList(action['action'])
      if 'message' in action:
        quiet_cmd = 'Gyp action: %s ($@)' % action['message']
      else:
        quiet_cmd = 'Gyp action: %s ($@)' % name
      if len(dirs) > 0:
        command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command

      cd_action = 'cd $(gyp_local_path)/%s; ' % self.path
      command = cd_action + command

      # The makefile rules are all relative to the top dir, but the gyp actions
      # are defined relative to their containing dir.  This replaces the gyp_*
      # variables for the action rule with an absolute version so that the
      # output goes in the right place.
      # Only write the gyp_* rules for the "primary" output (:1);
      # it's superfluous for the "extra outputs", and this avoids accidentally
      # writing duplicate dummy rules for those outputs.
      main_output = make.QuoteSpaces(self.LocalPathify(outputs[0]))
      self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output)
      self.WriteLn('%s: gyp_intermediate_dir := '
                   '$(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_intermediate_dir)' %
                   main_output)
      self.WriteLn('%s: gyp_shared_intermediate_dir := '
                   '$(GYP_ABS_ANDROID_TOP_DIR)/$(gyp_shared_intermediate_dir)' %
                   main_output)

      for input in inputs:
        assert ' ' not in input, (
            "Spaces in action input filenames not supported (%s)"  % input)
      for output in outputs:
        assert ' ' not in output, (
            "Spaces in action output filenames not supported (%s)"  % output)

      self.WriteLn('%s: %s $(GYP_TARGET_DEPENDENCIES)' %
                   (main_output, ' '.join(map(self.LocalPathify, inputs))))
      self.WriteLn('\t@echo "%s"' % quiet_cmd)
      self.WriteLn('\t$(hide)%s\n' % command)
      for output in outputs[1:]:
        # Make each output depend on the main output, with an empty command
        # to force make to notice that the mtime has changed.
        self.WriteLn('%s: %s ;' % (self.LocalPathify(output), main_output))

      extra_outputs += outputs
      self.WriteLn()

    self.WriteLn()
Beispiel #3
0
    def WriteActions(self, actions, extra_sources, extra_outputs):
        """Write Makefile code for any 'actions' from the gyp input.

    extra_sources: a list that will be filled in with newly generated source
                   files, if any
    extra_outputs: a list that will be filled in with any outputs of these
                   actions (used to make other pieces dependent on these
                   actions)
    """
        for action in actions:
            name = make.StringToMakefileVariable(
                '%s_%s' % (self.relative_target, action['action_name']))
            self.WriteLn('### Rules for action "%s":' % action['action_name'])
            inputs = action['inputs']
            outputs = action['outputs']

            # Build up a list of outputs.
            # Collect the output dirs we'll need.
            dirs = set()
            for out in outputs:
                if not out.startswith('$'):
                    print(
                        'WARNING: Action for target "%s" writes output to local path '
                        '"%s".' % (self.target, out))
                dir = os.path.split(out)[0]
                if dir:
                    dirs.add(dir)
            if int(action.get('process_outputs_as_sources', False)):
                extra_sources += outputs

            # Prepare the actual command.
            command = gyp.common.EncodePOSIXShellList(action['action'])
            if 'message' in action:
                quiet_cmd = 'Gyp action: %s ($@)' % action['message']
            else:
                quiet_cmd = 'Gyp action: %s ($@)' % name
            if len(dirs) > 0:
                command = 'mkdir -p %s' % ' '.join(dirs) + '; ' + command

            cd_action = 'cd $(gyp_local_path)/%s; ' % self.path
            command = cd_action + command

            # The makefile rules are all relative to the top dir, but the gyp actions
            # are defined relative to their containing dir.  This replaces the gyp_*
            # variables for the action rule with an absolute version so that the
            # output goes in the right place.
            # Only write the gyp_* rules for the "primary" output (:1);
            # it's superfluous for the "extra outputs", and this avoids accidentally
            # writing duplicate dummy rules for those outputs.
            main_output = make.QuoteSpaces(self.LocalPathify(outputs[0]))
            self.WriteLn('%s: gyp_local_path := $(LOCAL_PATH)' % main_output)
            self.WriteLn('%s: gyp_var_prefix := $(GYP_VAR_PREFIX)' %
                         main_output)
            self.WriteLn('%s: gyp_intermediate_dir := '
                         '$(abspath $(gyp_intermediate_dir))' % main_output)
            self.WriteLn('%s: gyp_shared_intermediate_dir := '
                         '$(abspath $(gyp_shared_intermediate_dir))' %
                         main_output)

            # Android's envsetup.sh adds a number of directories to the path including
            # the built host binary directory. This causes actions/rules invoked by
            # gyp to sometimes use these instead of system versions, e.g. bison.
            # The built host binaries may not be suitable, and can cause errors.
            # So, we remove them from the PATH using the ANDROID_BUILD_PATHS variable
            # set by envsetup.
            self.WriteLn(
                '%s: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))' %
                main_output)

            # Don't allow spaces in input/output filenames, but make an exception for
            # filenames which start with '$(' since it's okay for there to be spaces
            # inside of make function/macro invocations.
            for input in inputs:
                if not input.startswith('$(') and ' ' in input:
                    raise gyp.common.GypError(
                        'Action input filename "%s" in target %s contains a space'
                        % (input, self.target))
            for output in outputs:
                if not output.startswith('$(') and ' ' in output:
                    raise gyp.common.GypError(
                        'Action output filename "%s" in target %s contains a space'
                        % (output, self.target))

            self.WriteLn(
                '%s: %s $(GYP_TARGET_DEPENDENCIES)' %
                (main_output, ' '.join(map(self.LocalPathify, inputs))))
            self.WriteLn('\t@echo "%s"' % quiet_cmd)
            self.WriteLn('\t$(hide)%s\n' % command)
            for output in outputs[1:]:
                # Make each output depend on the main output, with an empty command
                # to force make to notice that the mtime has changed.
                self.WriteLn('%s: %s ;' %
                             (self.LocalPathify(output), main_output))

            extra_outputs += outputs
            self.WriteLn()

        self.WriteLn()