Ejemplo n.º 1
0
def main(args):
    args = build_utils.ExpandFileArgs(args)
    options = _ParseOptions(args)

    libraries = []
    for p in options.classpath:
        # If a jar is part of input no need to include it as library jar.
        if p not in libraries and p not in options.input_paths:
            libraries.append(p)

    # TODO(agrieve): Remove proguard usages.
    if options.r8_path:
        with build_utils.TempDir() as tmp_dir:
            tmp_mapping_path = os.path.join(tmp_dir, 'mapping.txt')
            tmp_proguard_config_path = os.path.join(tmp_dir,
                                                    'proguard_config.txt')
            # If there is no output (no classes are kept), this prevents this script
            # from failing.
            build_utils.Touch(tmp_mapping_path)

            f = cStringIO.StringIO()
            proguard_util.WriteFlagsFile(options.proguard_configs,
                                         f,
                                         exclude_generated=True)
            merged_configs = f.getvalue()
            f.close()
            print_stdout = '-whyareyoukeeping' in merged_configs

            if options.output_path.endswith('.dex'):
                with build_utils.TempDir() as tmp_dex_dir:
                    cmd = _CreateR8Command(options, tmp_mapping_path,
                                           tmp_dex_dir,
                                           tmp_proguard_config_path, libraries)
                    build_utils.CheckOutput(cmd, print_stdout=print_stdout)
                    _MoveTempDexFile(tmp_dex_dir, options.output_path)
            else:
                cmd = _CreateR8Command(options, tmp_mapping_path,
                                       options.output_path,
                                       tmp_proguard_config_path, libraries)
                build_utils.CheckOutput(cmd, print_stdout=print_stdout)

            # Copy output files to correct locations.
            with build_utils.AtomicOutput(options.mapping_output) as mapping:
                # Mapping files generated by R8 include comments that may break
                # some of our tooling so remove those.
                with open(tmp_mapping_path) as tmp:
                    mapping.writelines(l for l in tmp if not l.startswith("#"))

        with build_utils.AtomicOutput(options.output_config) as f:
            f.write(merged_configs)

        if options.expected_configs_file:
            _VerifyExpectedConfigs(options.expected_configs_file,
                                   options.output_config,
                                   options.verify_expected_configs)

        other_inputs = []
        if options.apply_mapping:
            other_inputs += options.apply_mapping

        build_utils.WriteDepfile(options.depfile,
                                 options.output_path,
                                 inputs=options.proguard_configs +
                                 options.input_paths + libraries +
                                 other_inputs,
                                 add_pydeps=False)
    else:
        proguard = proguard_util.ProguardCmdBuilder(options.proguard_path)
        proguard.injars(options.input_paths)
        proguard.configs(options.proguard_configs)
        proguard.config_exclusions(options.proguard_config_exclusions)
        proguard.outjar(options.output_path)
        proguard.mapping_output(options.mapping_output)
        proguard.libraryjars(libraries)
        proguard.verbose(options.verbose)
        # Do not consider the temp file as an input since its name is random.
        input_paths = proguard.GetInputs()

        with tempfile.NamedTemporaryFile() as f:
            if options.apply_mapping:
                input_paths.append(options.apply_mapping)
                # Maintain only class name mappings in the .mapping file in order to
                # work around what appears to be a ProGuard bug in -applymapping:
                #     method 'int close()' is not being kept as 'a', but remapped to 'c'
                _RemoveMethodMappings(options.apply_mapping, f)
                proguard.mapping(f.name)

            input_strings = proguard.build()
            if f.name in input_strings:
                input_strings[input_strings.index(f.name)] = '$M'

            build_utils.CallAndWriteDepfileIfStale(
                proguard.CheckOutput,
                options,
                input_paths=input_paths,
                input_strings=input_strings,
                output_paths=proguard.GetOutputs(),
                depfile_deps=proguard.GetDepfileDeps(),
                add_pydeps=False)
Ejemplo n.º 2
0
def main(args):
  args = build_utils.ExpandFileArgs(args)
  options = _ParseOptions(args)

  libraries = []
  for p in options.classpath:
    # If a jar is part of input no need to include it as library jar.
    if p not in libraries and p not in options.input_paths:
      libraries.append(p)

  # TODO(agrieve): Remove proguard usages.
  if options.r8_path:
    temp_config_string = ''
    with build_utils.TempDir() as tmp_dir:
      tmp_mapping_path = os.path.join(tmp_dir, 'mapping.txt')
      tmp_proguard_config_path = os.path.join(tmp_dir, 'proguard_config.txt')
      # If there is no output (no classes are kept), this prevents this script
      # from failing.
      build_utils.Touch(tmp_mapping_path)

      f = cStringIO.StringIO()
      proguard_util.WriteFlagsFile(
          options.proguard_configs, f, exclude_generated=True)
      merged_configs = f.getvalue()
      # Fix up line endings (third_party configs can have windows endings)
      merged_configs = merged_configs.replace('\r', '')
      f.close()
      print_stdout = '-whyareyoukeeping' in merged_configs

      def run_r8(cmd):
        stderr_filter = None
        env = os.environ.copy()
        if options.disable_outlining:
          stderr_filter = lambda l: re.sub(r'.*_JAVA_OPTIONS.*\n?', '', l)
          env['_JAVA_OPTIONS'] = '-Dcom.android.tools.r8.disableOutlining=1'
        build_utils.CheckOutput(
            cmd,
            env=env,
            print_stdout=print_stdout,
            stderr_filter=stderr_filter)

      if options.output_path.endswith('.dex'):
        with build_utils.TempDir() as tmp_dex_dir:
          cmd, temp_config_string = _CreateR8Command(
              options, tmp_mapping_path, tmp_dex_dir, tmp_proguard_config_path,
              libraries)
          run_r8(cmd)
          _MoveTempDexFile(tmp_dex_dir, options.output_path)
      else:
        cmd, temp_config_string = _CreateR8Command(
            options, tmp_mapping_path, options.output_path,
            tmp_proguard_config_path, libraries)
        run_r8(cmd)

      # Copy output files to correct locations.
      with build_utils.AtomicOutput(options.mapping_output) as mapping:
        # Mapping files generated by R8 include comments that may break
        # some of our tooling so remove those.
        with open(tmp_mapping_path) as tmp:
          mapping.writelines(l for l in tmp if not l.startswith('#'))

      for output in build_utils.ParseGnList(options.extra_mapping_output_paths):
        shutil.copy(tmp_mapping_path, output)


    with build_utils.AtomicOutput(options.output_config) as f:
      f.write(merged_configs)
      if temp_config_string:
        f.write(_GENERATED_PROGUARD_HEADER)
        f.write(temp_config_string)

    if options.expected_configs_file:
      _VerifyExpectedConfigs(options.expected_configs_file,
                             options.output_config,
                             options.verify_expected_configs)

    other_inputs = []
    if options.apply_mapping:
      other_inputs += options.apply_mapping

    build_utils.WriteDepfile(
        options.depfile,
        options.output_path,
        inputs=options.proguard_configs + options.input_paths + libraries +
        other_inputs,
        add_pydeps=False)
  else:
    proguard = proguard_util.ProguardCmdBuilder(options.proguard_path)
    proguard.injars(options.input_paths)
    proguard.configs(options.proguard_configs)
    proguard.config_exclusions(options.proguard_config_exclusions)
    proguard.outjar(options.output_path)
    proguard.mapping_output(options.mapping_output)
    proguard.libraryjars(libraries)
    proguard.verbose(options.verbose)
    proguard.min_api(options.min_api)
    # Do not consider the temp file as an input since its name is random.
    input_paths = proguard.GetInputs()

    with tempfile.NamedTemporaryFile() as f:
      if options.apply_mapping:
        input_paths.append(options.apply_mapping)
        # Maintain only class name mappings in the .mapping file in order to
        # work around what appears to be a ProGuard bug in -applymapping:
        #     method 'int close()' is not being kept as 'a', but remapped to 'c'
        _RemoveMethodMappings(options.apply_mapping, f)
        proguard.mapping(f.name)
      with build_utils.TempDir() as d:
        proguard.tmp_dir(d)
        input_strings = proguard.build()
        if f.name in input_strings:
          input_strings[input_strings.index(f.name)] = '$M'

        build_utils.CallAndWriteDepfileIfStale(
            proguard.CheckOutput,
            options,
            input_paths=input_paths,
            input_strings=input_strings,
            output_paths=proguard.GetOutputs(),
            depfile_deps=proguard.GetDepfileDeps(),
            add_pydeps=False)