Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2012 Google Inc. All rights reserved. | 1 # Copyright (c) 2012 Google Inc. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from compiler.ast import Const | 5 from compiler.ast import Const |
| 6 from compiler.ast import Dict | 6 from compiler.ast import Dict |
| 7 from compiler.ast import Discard | 7 from compiler.ast import Discard |
| 8 from compiler.ast import List | 8 from compiler.ast import List |
| 9 from compiler.ast import Module | 9 from compiler.ast import Module |
| 10 from compiler.ast import Node | 10 from compiler.ast import Node |
| (...skipping 2087 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2098 VALID_TARGET_TYPES = ('executable', 'loadable_module', | 2098 VALID_TARGET_TYPES = ('executable', 'loadable_module', |
| 2099 'static_library', 'shared_library', | 2099 'static_library', 'shared_library', |
| 2100 'none') | 2100 'none') |
| 2101 target_type = target_dict.get('type', None) | 2101 target_type = target_dict.get('type', None) |
| 2102 if target_type not in VALID_TARGET_TYPES: | 2102 if target_type not in VALID_TARGET_TYPES: |
| 2103 raise Exception("Target %s has an invalid target type '%s'. " | 2103 raise Exception("Target %s has an invalid target type '%s'. " |
| 2104 "Must be one of %s." % | 2104 "Must be one of %s." % |
| 2105 (target, target_type, '/'.join(VALID_TARGET_TYPES))) | 2105 (target, target_type, '/'.join(VALID_TARGET_TYPES))) |
| 2106 | 2106 |
| 2107 | 2107 |
| 2108 def ValidateSourcesInTarget(target, target_dict, build_file): | |
| 2109 # TODO: Check if MSVC allows this for non-static_library targets. | |
| 2110 if target_dict.get('type', None) != 'static_library': | |
| 2111 return | |
| 2112 sources = target_dict.get('sources', []) | |
| 2113 basenames = {} | |
| 2114 for source in sources: | |
| 2115 name, ext = os.path.splitext(source) | |
| 2116 is_compiled_file = ext in ['.c', '.cc', '.m', '.mm', '.s', '.S'] | |
|
scottmg
2012/04/05 23:12:49
+= .cpp? (or is there a canonical list like this s
| |
| 2117 if not is_compiled_file: | |
| 2118 continue | |
| 2119 basename = os.path.basename(name) # Don't include extension. | |
| 2120 basenames.setdefault(basename, []).append(source) | |
| 2121 | |
| 2122 error = '' | |
| 2123 for basename, files in basenames.iteritems(): | |
| 2124 if len(files) > 1: | |
| 2125 error += ' %s: %s\n' % (basename, ' '.join(files)) | |
| 2126 | |
| 2127 if error: | |
| 2128 print ('static library %s has several files with the same basename:\n' % | |
| 2129 target + error + 'Some build systems, e.g. MSVC08, ' | |
| 2130 'cannot handle that.') | |
| 2131 raise KeyError, 'Duplicate basenames in sources section, see list above' | |
| 2132 | |
| 2133 | |
| 2108 def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): | 2134 def ValidateRulesInTarget(target, target_dict, extra_sources_for_rules): |
| 2109 """Ensures that the rules sections in target_dict are valid and consistent, | 2135 """Ensures that the rules sections in target_dict are valid and consistent, |
| 2110 and determines which sources they apply to. | 2136 and determines which sources they apply to. |
| 2111 | 2137 |
| 2112 Arguments: | 2138 Arguments: |
| 2113 target: string, name of target. | 2139 target: string, name of target. |
| 2114 target_dict: dict, target spec containing "rules" and "sources" lists. | 2140 target_dict: dict, target spec containing "rules" and "sources" lists. |
| 2115 extra_sources_for_rules: a list of keys to scan for rule matches in | 2141 extra_sources_for_rules: a list of keys to scan for rule matches in |
| 2116 addition to 'sources'. | 2142 addition to 'sources'. |
| 2117 """ | 2143 """ |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2155 (source_root, source_extension) = os.path.splitext(source) | 2181 (source_root, source_extension) = os.path.splitext(source) |
| 2156 if source_extension.startswith('.'): | 2182 if source_extension.startswith('.'): |
| 2157 source_extension = source_extension[1:] | 2183 source_extension = source_extension[1:] |
| 2158 if source_extension == extension: | 2184 if source_extension == extension: |
| 2159 rule_sources.append(source) | 2185 rule_sources.append(source) |
| 2160 | 2186 |
| 2161 if len(rule_sources) > 0: | 2187 if len(rule_sources) > 0: |
| 2162 rule['rule_sources'] = rule_sources | 2188 rule['rule_sources'] = rule_sources |
| 2163 | 2189 |
| 2164 | 2190 |
| 2165 def ValidateActionsInTarget(target, target_dict, build_file): | |
| 2166 '''Validates the inputs to the actions in a target.''' | |
| 2167 target_name = target_dict.get('target_name') | |
| 2168 actions = target_dict.get('actions', []) | |
| 2169 for action in actions: | |
| 2170 action_name = action.get('action_name') | |
| 2171 if not action_name: | |
| 2172 raise Exception("Anonymous action in target %s. " | |
| 2173 "An action must have an 'action_name' field." % | |
| 2174 target_name) | |
| 2175 inputs = action.get('inputs', []) | |
| 2176 action_command = action.get('action') | |
| 2177 if action_command and not action_command[0]: | |
| 2178 raise Exception("Empty action as command in target %s." % target_name) | |
| 2179 | |
| 2180 | |
| 2181 def ValidateRunAsInTarget(target, target_dict, build_file): | 2191 def ValidateRunAsInTarget(target, target_dict, build_file): |
| 2182 target_name = target_dict.get('target_name') | 2192 target_name = target_dict.get('target_name') |
| 2183 run_as = target_dict.get('run_as') | 2193 run_as = target_dict.get('run_as') |
| 2184 if not run_as: | 2194 if not run_as: |
| 2185 return | 2195 return |
| 2186 if not isinstance(run_as, dict): | 2196 if not isinstance(run_as, dict): |
| 2187 raise Exception("The 'run_as' in target %s from file %s should be a " | 2197 raise Exception("The 'run_as' in target %s from file %s should be a " |
| 2188 "dictionary." % | 2198 "dictionary." % |
| 2189 (target_name, build_file)) | 2199 (target_name, build_file)) |
| 2190 action = run_as.get('action') | 2200 action = run_as.get('action') |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 2201 raise Exception("The 'working_directory' for 'run_as' in target %s " | 2211 raise Exception("The 'working_directory' for 'run_as' in target %s " |
| 2202 "in file %s should be a string." % | 2212 "in file %s should be a string." % |
| 2203 (target_name, build_file)) | 2213 (target_name, build_file)) |
| 2204 environment = run_as.get('environment') | 2214 environment = run_as.get('environment') |
| 2205 if environment and not isinstance(environment, dict): | 2215 if environment and not isinstance(environment, dict): |
| 2206 raise Exception("The 'environment' for 'run_as' in target %s " | 2216 raise Exception("The 'environment' for 'run_as' in target %s " |
| 2207 "in file %s should be a dictionary." % | 2217 "in file %s should be a dictionary." % |
| 2208 (target_name, build_file)) | 2218 (target_name, build_file)) |
| 2209 | 2219 |
| 2210 | 2220 |
| 2221 def ValidateActionsInTarget(target, target_dict, build_file): | |
| 2222 '''Validates the inputs to the actions in a target.''' | |
| 2223 target_name = target_dict.get('target_name') | |
| 2224 actions = target_dict.get('actions', []) | |
| 2225 for action in actions: | |
| 2226 action_name = action.get('action_name') | |
| 2227 if not action_name: | |
| 2228 raise Exception("Anonymous action in target %s. " | |
| 2229 "An action must have an 'action_name' field." % | |
| 2230 target_name) | |
| 2231 inputs = action.get('inputs', []) | |
| 2232 action_command = action.get('action') | |
| 2233 if action_command and not action_command[0]: | |
| 2234 raise Exception("Empty action as command in target %s." % target_name) | |
| 2235 | |
| 2236 | |
| 2211 def TurnIntIntoStrInDict(the_dict): | 2237 def TurnIntIntoStrInDict(the_dict): |
| 2212 """Given dict the_dict, recursively converts all integers into strings. | 2238 """Given dict the_dict, recursively converts all integers into strings. |
| 2213 """ | 2239 """ |
| 2214 # Use items instead of iteritems because there's no need to try to look at | 2240 # Use items instead of iteritems because there's no need to try to look at |
| 2215 # reinserted keys and their associated values. | 2241 # reinserted keys and their associated values. |
| 2216 for k, v in the_dict.items(): | 2242 for k, v in the_dict.items(): |
| 2217 if isinstance(v, int): | 2243 if isinstance(v, int): |
| 2218 v = str(v) | 2244 v = str(v) |
| 2219 the_dict[k] = v | 2245 the_dict[k] = v |
| 2220 elif isinstance(v, dict): | 2246 elif isinstance(v, dict): |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2386 ProcessListFiltersInDict(target, target_dict) | 2412 ProcessListFiltersInDict(target, target_dict) |
| 2387 | 2413 |
| 2388 # Make sure that the rules make sense, and build up rule_sources lists as | 2414 # Make sure that the rules make sense, and build up rule_sources lists as |
| 2389 # needed. Not all generators will need to use the rule_sources lists, but | 2415 # needed. Not all generators will need to use the rule_sources lists, but |
| 2390 # some may, and it seems best to build the list in a common spot. | 2416 # some may, and it seems best to build the list in a common spot. |
| 2391 # Also validate actions and run_as elements in targets. | 2417 # Also validate actions and run_as elements in targets. |
| 2392 for target in flat_list: | 2418 for target in flat_list: |
| 2393 target_dict = targets[target] | 2419 target_dict = targets[target] |
| 2394 build_file = gyp.common.BuildFile(target) | 2420 build_file = gyp.common.BuildFile(target) |
| 2395 ValidateTargetType(target, target_dict) | 2421 ValidateTargetType(target, target_dict) |
| 2422 ValidateSourcesInTarget(target, target_dict, build_file) | |
| 2396 ValidateRulesInTarget(target, target_dict, extra_sources_for_rules) | 2423 ValidateRulesInTarget(target, target_dict, extra_sources_for_rules) |
| 2397 ValidateRunAsInTarget(target, target_dict, build_file) | 2424 ValidateRunAsInTarget(target, target_dict, build_file) |
| 2398 ValidateActionsInTarget(target, target_dict, build_file) | 2425 ValidateActionsInTarget(target, target_dict, build_file) |
| 2399 | 2426 |
| 2400 # Generators might not expect ints. Turn them into strs. | 2427 # Generators might not expect ints. Turn them into strs. |
| 2401 TurnIntIntoStrInDict(data) | 2428 TurnIntIntoStrInDict(data) |
| 2402 | 2429 |
| 2403 # TODO(mark): Return |data| for now because the generator needs a list of | 2430 # TODO(mark): Return |data| for now because the generator needs a list of |
| 2404 # build files that came in. In the future, maybe it should just accept | 2431 # build files that came in. In the future, maybe it should just accept |
| 2405 # a list, and not the whole data dict. | 2432 # a list, and not the whole data dict. |
| 2406 return [flat_list, targets, data] | 2433 return [flat_list, targets, data] |
| OLD | NEW |