1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#!/usr/bin/env python
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved.
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)# found in the LICENSE file.
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)"""Simple tool to generate NMF file by just reformatting given arguments.
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)This tool is similar to native_client_sdk/src/tools/create_nmf.py.
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)create_nmf.py handles most cases, with the exception of Non-SFI nexes.
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)create_nmf.py tries to auto-detect nexe and pexe types based on their contents,
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)but it does not work for Non-SFI nexes (which don't have a marker to
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)distinguish them from SFI nexes).
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)This script simply reformats the command line arguments into NMF JSON format.
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)"""
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import argparse
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import collections
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import json
20cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import logging
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)import os
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_FILES_KEY = 'files'
24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_PORTABLE_KEY = 'portable'
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_PROGRAM_KEY = 'program'
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_URL_KEY = 'url'
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)_X86_32_NONSFI_KEY = 'x86-32-nonsfi'
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def ParseArgs():
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser = argparse.ArgumentParser()
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_argument(
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      '--program', metavar='FILE', help='Main program nexe')
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  # To keep compatibility with create_nmf.py, we use -x and --extra-files
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  # as flags.
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_argument(
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      '-x', '--extra-files', action='append', metavar='KEY:FILE', default=[],
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      help=('Add extra key:file tuple to the "files" '
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            'section of the .nmf'))
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  parser.add_argument(
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      '--output', metavar='FILE', help='Path to the output nmf file.')
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return parser.parse_args()
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def BuildNmfMap(root_path, program, extra_files):
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  """Build simple map representing nmf json."""
48cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  result = {
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    _PROGRAM_KEY: {
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      _X86_32_NONSFI_KEY: {
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        # The program path is relative to the root_path.
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        _URL_KEY: os.path.relpath(program, root_path)
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if extra_files:
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    files = {}
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    for named_file in extra_files:
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      name, path = named_file.split(':', 1)
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      files[name] = {
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        _PORTABLE_KEY: {
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          # Note: use path as is, unlike program path.
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          _URL_KEY: path
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if files:
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      result[_FILES_KEY] = files
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  return result
71cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
72cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def OutputNmf(nmf_map, output_path):
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  """Writes the nmf to an output file at given path in JSON format."""
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  with open(output_path, 'w') as output:
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    json.dump(nmf_map, output, indent=2)
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)def main():
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  args = ParseArgs()
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if not args.program:
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    logging.error('--program is not specified.')
83cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    sys.exit(1)
84cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if not args.output:
85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    logging.error('--output is not specified.')
86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    sys.exit(1)
87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  nmf_map = BuildNmfMap(os.path.dirname(args.output),
89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                        args.program, args.extra_files)
90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  OutputNmf(nmf_map, args.output)
91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)if __name__ == '__main__':
94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  main()
95