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 |