Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: platform_tools/android/gyp_gen/gypd_parser.py

Issue 235883015: Generate tests/Android.mk from gyp (Closed) Base URL: https://skia.googlesource.com/skia.git@generate
Patch Set: Remove Android.mk/SkUserConfig.h Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright 2014 Google Inc. 3 # Copyright 2014 Google Inc.
4 # 4 #
5 # Use of this source code is governed by a BSD-style license that can be 5 # Use of this source code is governed by a BSD-style license that can be
6 # found in the LICENSE file. 6 # found in the LICENSE file.
7 7
8 """ 8 """Functions for parsing the gypd output from gyp.
9 Functions for parsing the gypd output from gyp.
10 """ 9 """
11 10
12 def parse_dictionary(var_dict, d, current_target_name): 11
13 """ 12 import os
14 Helper function to get the meaningful entries in a dictionary. 13
15 @param var_dict VarsDict object for storing the results of the parsing. 14
16 @param d Dictionary object to parse. 15 def parse_dictionary(var_dict, d, current_target_name, dest_dir):
17 @param current_target_name The current target being parsed. If this 16 """Helper function to get the meaningful entries in a dictionary.
18 dictionary is a target, this will be its entry 17
19 'target_name'. Otherwise, this will be the name of 18 Parse dictionary d, and store unique relevant entries in var_dict.
20 the target which contains this dictionary. 19 Recursively parses internal dictionaries and files that are referenced.
20 When parsing the 'libraries' list from gyp, entries in the form
21 '-l<name>' get assigned to var_dict.LOCAL_SHARED_LIBRARIES as 'lib<name>',
22 and entries in the form '[lib]<name>.a' get assigned to
23 var_dict.LOCAL_STATIC_LIBRARIES as 'lib<name>'.
24
25 Args:
26 var_dict: VarsDict object for storing the results of the parsing.
27 d: Dictionary object to parse.
28 current_target_name: The current target being parsed. If this dictionary
29 is a target, this will be its entry 'target_name'. Otherwise, this will
30 be the name of the target which contains this dictionary.
31 dest_dir: Destination for the eventual Android.mk that will be created from
32 this parse, relative to Skia trunk. Used to determine path for source
33 files.
21 """ 34 """
22 for source in d.get('sources', []): 35 for source in d.get('sources', []):
23 # Compare against a lowercase version, in case files are named .H or .GYPI 36 # Compare against a lowercase version, in case files are named .H or .GYPI
24 lowercase_source = source.lower() 37 lowercase_source = source.lower()
25 if lowercase_source.endswith('.h'): 38 if lowercase_source.endswith('.h'):
26 # Android.mk does not need the header files. 39 # Android.mk does not need the header files.
27 continue 40 continue
28 if lowercase_source.endswith('gypi'): 41 if lowercase_source.endswith('gypi'):
29 # The gypi files are included in sources, but the sources they included 42 # The gypi files are included in sources, but the sources they included
30 # are also included. No need to parse them again. 43 # are also included. No need to parse them again.
31 continue 44 continue
32 # The path is relative to the gyp folder, but Android wants the path 45 # The path is relative to the gyp folder, but Android wants the path
33 # relative to the root. 46 # relative to dest_dir.
34 source = source.replace('../src', 'src', 1) 47 rel_source = os.path.relpath(source, os.pardir)
35 var_dict.LOCAL_SRC_FILES.add(source) 48 rel_source = os.path.relpath(rel_source, dest_dir)
49 var_dict.LOCAL_SRC_FILES.add(rel_source)
36 50
37 for lib in d.get('libraries', []): 51 for lib in d.get('libraries', []):
38 if lib.endswith('.a'): 52 if lib.endswith('.a'):
39 # Remove the '.a' 53 # Remove the '.a'
40 lib = lib[:-2] 54 lib = lib[:-2]
41 # Add 'lib', if necessary 55 # Add 'lib', if necessary
42 if not lib.startswith('lib'): 56 if not lib.startswith('lib'):
43 lib = 'lib' + lib 57 lib = 'lib' + lib
44 var_dict.LOCAL_STATIC_LIBRARIES.add(lib) 58 var_dict.LOCAL_STATIC_LIBRARIES.add(lib)
45 else: 59 else:
46 # lib will be in the form of '-l<name>'. Change it to 'lib<name>' 60 # lib will be in the form of '-l<name>'. Change it to 'lib<name>'
47 lib = lib.replace('-l', 'lib', 1) 61 lib = lib.replace('-l', 'lib', 1)
48 var_dict.LOCAL_SHARED_LIBRARIES.add(lib) 62 var_dict.LOCAL_SHARED_LIBRARIES.add(lib)
49 63
50 for dependency in d.get('dependencies', []): 64 for dependency in d.get('dependencies', []):
51 # Each dependency is listed as 65 # Each dependency is listed as
52 # <path_to_file>:<target>#target 66 # <path_to_file>:<target>#target
53 li = dependency.split(':') 67 li = dependency.split(':')
54 assert(len(li) <= 2 and len(li) >= 1) 68 assert(len(li) <= 2 and len(li) >= 1)
55 sub_targets = [] 69 sub_targets = []
56 if len(li) == 2 and li[1] != '*': 70 if len(li) == 2 and li[1] != '*':
57 sub_targets.append(li[1].split('#')[0]) 71 sub_targets.append(li[1].split('#')[0])
58 sub_path = li[0] 72 sub_path = li[0]
59 assert(sub_path.endswith('.gyp')) 73 assert(sub_path.endswith('.gyp'))
60 # Although the original reference is to a .gyp, parse the corresponding 74 # Although the original reference is to a .gyp, parse the corresponding
61 # gypd file, which was constructed by gyp. 75 # gypd file, which was constructed by gyp.
62 sub_path = sub_path + 'd' 76 sub_path = sub_path + 'd'
63 parse_gypd(var_dict, sub_path, sub_targets) 77 parse_gypd(var_dict, sub_path, dest_dir, sub_targets)
64 78
65 if 'default_configuration' in d: 79 if 'default_configuration' in d:
66 config_name = d['default_configuration'] 80 config_name = d['default_configuration']
67 # default_configuration is meaningless without configurations 81 # default_configuration is meaningless without configurations
68 assert('configurations' in d) 82 assert('configurations' in d)
69 config = d['configurations'][config_name] 83 config = d['configurations'][config_name]
70 parse_dictionary(var_dict, config, current_target_name) 84 parse_dictionary(var_dict, config, current_target_name, dest_dir)
71 85
72 for flag in d.get('cflags', []): 86 for flag in d.get('cflags', []):
73 var_dict.LOCAL_CFLAGS.add(flag) 87 var_dict.LOCAL_CFLAGS.add(flag)
74 for flag in d.get('cflags_cc', []): 88 for flag in d.get('cflags_cc', []):
75 var_dict.LOCAL_CPPFLAGS.add(flag) 89 var_dict.LOCAL_CPPFLAGS.add(flag)
76 90
77 for include in d.get('include_dirs', []): 91 for include in d.get('include_dirs', []):
78 # The input path will be relative to gyp/, but Android wants relative to 92 if include.startswith('external'):
79 # LOCAL_PATH 93 # This path is relative to the Android root. Leave it alone.
80 include = include.replace('..', '$(LOCAL_PATH)', 1) 94 rel_include = include
95 else:
96 # As with source, the input path will be relative to gyp/, but Android
97 # wants relative to dest_dir.
98 rel_include = os.path.relpath(include, os.pardir)
99 rel_include = os.path.relpath(rel_include, dest_dir)
100 rel_include = os.path.join('$(LOCAL_PATH)', rel_include)
101
81 # Remove a trailing slash, if present. 102 # Remove a trailing slash, if present.
82 if include.endswith('/'): 103 if rel_include.endswith('/'):
83 include = include[:-1] 104 rel_include = rel_include[:-1]
84 var_dict.LOCAL_C_INCLUDES.add(include) 105 var_dict.LOCAL_C_INCLUDES.add(rel_include)
85 # For the top level, libskia, include directories should be exported. 106 # For the top level, libskia, include directories should be exported.
107 # FIXME (scroggo): Do not hard code this.
86 if current_target_name == 'libskia': 108 if current_target_name == 'libskia':
87 var_dict.LOCAL_EXPORT_C_INCLUDE_DIRS.add(include) 109 var_dict.LOCAL_EXPORT_C_INCLUDE_DIRS.add(rel_include)
88 110
89 for define in d.get('defines', []): 111 for define in d.get('defines', []):
90 var_dict.DEFINES.add(define) 112 var_dict.DEFINES.add(define)
91 113
92 114
93 def parse_gypd(var_dict, path, desired_targets=None): 115 def parse_gypd(var_dict, path, dest_dir, desired_targets=None):
94 """ 116 """Parse a gypd file.
95 Parse a gypd file. 117
96 @param var_dict VarsDict object for storing the result of the parse. 118 Open a file that consists of python dictionaries representing build targets.
97 @param path Path to gypd file. 119 Parse those dictionaries using parse_dictionary. Recursively parses
98 @param desired_targets List of targets to be parsed from this file. If empty, 120 referenced files.
99 parse all targets. 121
122 Args:
123 var_dict: VarsDict object for storing the result of the parse.
124 path: Path to gypd file.
125 dest_dir: Destination for the eventual Android.mk that will be created from
126 this parse, relative to Skia trunk. Used to determine path for source
127 files and include directories.
128 desired_targets: List of targets to be parsed from this file. If empty,
129 parse all targets.
100 """ 130 """
101 d = {} 131 d = {}
102 with open(path, 'r') as f: 132 with open(path, 'r') as f:
103 # Read the entire file as a dictionary 133 # Read the entire file as a dictionary
104 d = eval(f.read()) 134 d = eval(f.read())
105 135
106 # The gypd file is structured such that the top level dictionary has an entry 136 # The gypd file is structured such that the top level dictionary has an entry
107 # named 'targets' 137 # named 'targets'
108 for target in d['targets']: 138 for target in d['targets']:
109 target_name = target['target_name'] 139 target_name = target['target_name']
110 if target_name in var_dict.KNOWN_TARGETS: 140 if target_name in var_dict.KNOWN_TARGETS:
111 # Avoid circular dependencies 141 # Avoid circular dependencies
112 continue 142 continue
113 if desired_targets and target_name not in desired_targets: 143 if desired_targets and target_name not in desired_targets:
114 # Our caller does not depend on this one 144 # Our caller does not depend on this one
115 continue 145 continue
116 # Add it to our known targets so we don't parse it again 146 # Add it to our known targets so we don't parse it again
117 var_dict.KNOWN_TARGETS.add(target_name) 147 var_dict.KNOWN_TARGETS.add(target_name)
118 148
119 parse_dictionary(var_dict, target, target_name) 149 parse_dictionary(var_dict, target, target_name, dest_dir)
120 150
OLDNEW
« no previous file with comments | « platform_tools/android/gyp_gen/android_framework_gyp.py ('k') | platform_tools/android/gyp_gen/makefile_writer.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698