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

Side by Side Diff: pylib/gyp/generator/xcode.py

Issue 437013: Xcode has some issues with generated sources/headers and compiling sources. ... (Closed) Base URL: http://gyp.googlecode.com/svn/trunk/
Patch Set: '' Created 11 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2009 Google Inc. All rights reserved. 3 # Copyright (c) 2009 Google Inc. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 import filecmp 7 import filecmp
8 import gyp.common 8 import gyp.common
9 import gyp.xcodeproj_file 9 import gyp.xcodeproj_file
10 import errno 10 import errno
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 'mac_bundle', 67 'mac_bundle',
68 'mac_bundle_resources', 68 'mac_bundle_resources',
69 'xcode_create_dependents_test_runner', 69 'xcode_create_dependents_test_runner',
70 ] 70 ]
71 71
72 # We want to let any rules apply to files that are resources also. 72 # We want to let any rules apply to files that are resources also.
73 generator_extra_sources_for_rules = [ 73 generator_extra_sources_for_rules = [
74 'mac_bundle_resources', 74 'mac_bundle_resources',
75 ] 75 ]
76 76
77
78 def CreateXCConfigurationList(configuration_names):
79 xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []})
80 for configuration_name in configuration_names:
81 xcbc = gyp.xcodeproj_file.XCBuildConfiguration({
82 'name': configuration_name})
83 xccl.AppendProperty('buildConfigurations', xcbc)
84 xccl.SetProperty('defaultConfigurationName', configuration_names[0])
85 return xccl
86
87
77 class XcodeProject(object): 88 class XcodeProject(object):
78 def __init__(self, gyp_path, path, build_file_dict): 89 def __init__(self, gyp_path, path, build_file_dict):
79 self.gyp_path = gyp_path 90 self.gyp_path = gyp_path
80 self.path = path 91 self.path = path
81 self.project = gyp.xcodeproj_file.PBXProject(path=path) 92 self.project = gyp.xcodeproj_file.PBXProject(path=path)
82 projectDirPath = gyp.common.RelativePath( 93 projectDirPath = gyp.common.RelativePath(
83 os.path.dirname(os.path.abspath(self.gyp_path)), 94 os.path.dirname(os.path.abspath(self.gyp_path)),
84 os.path.dirname(path) or '.') 95 os.path.dirname(path) or '.')
85 self.project.SetProperty('projectDirPath', projectDirPath) 96 self.project.SetProperty('projectDirPath', projectDirPath)
86 self.project_file = \ 97 self.project_file = \
(...skipping 22 matching lines...) Expand all
109 xcbcs = xccl.GetProperty('buildConfigurations') 120 xcbcs = xccl.GetProperty('buildConfigurations')
110 for xcbc in xcbcs: 121 for xcbc in xcbcs:
111 name = xcbc.GetProperty('name') 122 name = xcbc.GetProperty('name')
112 if name not in configurations: 123 if name not in configurations:
113 configurations.append(name) 124 configurations.append(name)
114 125
115 # Replace the XCConfigurationList attached to the PBXProject object with 126 # Replace the XCConfigurationList attached to the PBXProject object with
116 # a new one specifying all of the configuration names used by the various 127 # a new one specifying all of the configuration names used by the various
117 # targets. 128 # targets.
118 try: 129 try:
119 xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []}) 130 xccl = CreateXCConfigurationList(configurations)
120 for configuration in configurations:
121 xcbc = gyp.xcodeproj_file.XCBuildConfiguration({'name': configuration})
122 xccl.AppendProperty('buildConfigurations', xcbc)
123 xccl.SetProperty('defaultConfigurationName', configurations[0])
124 self.project.SetProperty('buildConfigurationList', xccl) 131 self.project.SetProperty('buildConfigurationList', xccl)
125 except: 132 except:
126 import sys 133 import sys
127 sys.stderr.write("Problem with gyp file %s\n" % self.gyp_path) 134 sys.stderr.write("Problem with gyp file %s\n" % self.gyp_path)
128 raise 135 raise
129 136
130 # The need for this setting is explained above where _intermediate_var is 137 # The need for this setting is explained above where _intermediate_var is
131 # defined. The comments below about wanting to avoid project-wide build 138 # defined. The comments below about wanting to avoid project-wide build
132 # settings apply here too, but this needs to be set on a project-wide basis 139 # settings apply here too, but this needs to be set on a project-wide basis
133 # so that files relative to the _intermediate_var setting can be displayed 140 # so that files relative to the _intermediate_var setting can be displayed
(...skipping 19 matching lines...) Expand all
153 # tree view for UI display. 160 # tree view for UI display.
154 for xck, xcv in self.build_file_dict.get('xcode_settings', {}).iteritems(): 161 for xck, xcv in self.build_file_dict.get('xcode_settings', {}).iteritems():
155 xccl.SetBuildSetting(xck, xcv) 162 xccl.SetBuildSetting(xck, xcv)
156 163
157 # Sort the targets based on how they appeared in the input. 164 # Sort the targets based on how they appeared in the input.
158 # TODO(mark): Like a lot of other things here, this assumes internal 165 # TODO(mark): Like a lot of other things here, this assumes internal
159 # knowledge of PBXProject - in this case, of its "targets" property. 166 # knowledge of PBXProject - in this case, of its "targets" property.
160 167
161 # ordinary_targets are ordinary targets that are already in the project 168 # ordinary_targets are ordinary targets that are already in the project
162 # file. run_test_targets are the targets that run unittests and should be 169 # file. run_test_targets are the targets that run unittests and should be
163 # used for the Run All Tests target. 170 # used for the Run All Tests target. support_targets are the action/rule
171 # targets used by GYP file targets, just kept for the assert check.
164 ordinary_targets = [] 172 ordinary_targets = []
165 run_test_targets = [] 173 run_test_targets = []
174 support_targets = []
166 175
167 # targets is full list of targets in the project. 176 # targets is full list of targets in the project.
168 targets = [] 177 targets = []
169 178
170 # does the it define it's own "all"? 179 # does the it define it's own "all"?
171 has_custom_all = False 180 has_custom_all = False
172 181
173 # targets_for_all is the list of ordinary_targets that should be listed 182 # targets_for_all is the list of ordinary_targets that should be listed
174 # in this project's "All" target. It includes each non_runtest_target 183 # in this project's "All" target. It includes each non_runtest_target
175 # that does not have suppress_wildcard set. 184 # that does not have suppress_wildcard set.
176 targets_for_all = [] 185 targets_for_all = []
177 186
178 for target in self.build_file_dict['targets']: 187 for target in self.build_file_dict['targets']:
179 target_name = target['target_name'] 188 target_name = target['target_name']
180 toolset = target['toolset'] 189 toolset = target['toolset']
181 qualified_target = gyp.common.QualifiedTarget(self.gyp_path, target_name, 190 qualified_target = gyp.common.QualifiedTarget(self.gyp_path, target_name,
182 toolset) 191 toolset)
183 xcode_target = xcode_targets[qualified_target] 192 xcode_target = xcode_targets[qualified_target]
184 # Make sure that the target being added to the sorted list is already in 193 # Make sure that the target being added to the sorted list is already in
185 # the unsorted list. 194 # the unsorted list.
186 assert xcode_target in self.project._properties['targets'] 195 assert xcode_target in self.project._properties['targets']
187 targets.append(xcode_target) 196 targets.append(xcode_target)
188 ordinary_targets.append(xcode_target) 197 ordinary_targets.append(xcode_target)
198 if xcode_target.support_target:
199 support_targets.append(xcode_target.support_target)
200 targets.append(xcode_target.support_target)
189 201
190 if not int(target.get('suppress_wildcard', False)): 202 if not int(target.get('suppress_wildcard', False)):
191 targets_for_all.append(xcode_target) 203 targets_for_all.append(xcode_target)
192 204
193 if target_name.lower() == 'all': 205 if target_name.lower() == 'all':
194 has_custom_all = True; 206 has_custom_all = True;
195 207
196 # If this target has a 'run_as' attribute, or is a test, add its 208 # If this target has a 'run_as' attribute, or is a test, add its
197 # target to the targets, and (if it's a test) add it the to the 209 # target to the targets, and (if it's a test) add it the to the
198 # test targets. 210 # test targets.
199 is_test = int(target.get('test', 0)) 211 is_test = int(target.get('test', 0))
200 if target.get('run_as') or is_test: 212 if target.get('run_as') or is_test:
201 # Make a target to run something. It should have one 213 # Make a target to run something. It should have one
202 # dependency, the parent xcode target. 214 # dependency, the parent xcode target.
215 xccl = CreateXCConfigurationList(configurations)
203 run_target = gyp.xcodeproj_file.PBXAggregateTarget({ 216 run_target = gyp.xcodeproj_file.PBXAggregateTarget({
204 'name': 'Run ' + target_name, 217 'name': 'Run ' + target_name,
205 'productName': xcode_target.GetProperty('productName'), 218 'productName': xcode_target.GetProperty('productName'),
219 'buildConfigurationList': xccl,
206 }, 220 },
207 parent=self.project) 221 parent=self.project)
208 run_target.AddDependency(xcode_target) 222 run_target.AddDependency(xcode_target)
209 223
210 # The test runner target has a build phase that executes the 224 # The test runner target has a build phase that executes the
211 # test, if this has the 'test' attribute. If the 'run_as' tag 225 # test, if this has the 'test' attribute. If the 'run_as' tag
212 # doesn't exist (meaning that this must be a test), then we 226 # doesn't exist (meaning that this must be a test), then we
213 # define a default test command line. 227 # define a default test command line.
214 command = target.get('run_as', { 228 command = target.get('run_as', {
215 'action': ['${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}'] 229 'action': ['${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}']
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 270
257 # Add the run target to the project file. 271 # Add the run target to the project file.
258 targets.append(run_target) 272 targets.append(run_target)
259 if is_test: 273 if is_test:
260 run_test_targets.append(run_target) 274 run_test_targets.append(run_target)
261 xcode_target.test_runner = run_target 275 xcode_target.test_runner = run_target
262 276
263 277
264 # Make sure that the list of targets being replaced is the same length as 278 # Make sure that the list of targets being replaced is the same length as
265 # the one replacing it, but allow for the added test runner targets. 279 # the one replacing it, but allow for the added test runner targets.
266 assert len(self.project._properties['targets']) == len(ordinary_targets) 280 assert len(self.project._properties['targets']) == \
281 len(ordinary_targets) + len(support_targets)
267 282
268 self.project._properties['targets'] = targets 283 self.project._properties['targets'] = targets
269 284
270 # Get rid of unnecessary levels of depth in groups like the Source group. 285 # Get rid of unnecessary levels of depth in groups like the Source group.
271 self.project.RootGroupsTakeOverOnlyChildren(True) 286 self.project.RootGroupsTakeOverOnlyChildren(True)
272 287
273 # Sort the groups nicely. Do this after sorting the targets, because the 288 # Sort the groups nicely. Do this after sorting the targets, because the
274 # Products group is sorted based on the order of the targets. 289 # Products group is sorted based on the order of the targets.
275 self.project.SortGroups() 290 self.project.SortGroups()
276 291
277 # Create an "All" target if there's more than one target in this project 292 # Create an "All" target if there's more than one target in this project
278 # file and the project didn't define its own "All" target. Put a generated 293 # file and the project didn't define its own "All" target. Put a generated
279 # "All" target first so that people opening up the project for the first 294 # "All" target first so that people opening up the project for the first
280 # time will build everything by default. 295 # time will build everything by default.
281 if len(targets_for_all) > 1 and not has_custom_all: 296 if len(targets_for_all) > 1 and not has_custom_all:
282 xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []}) 297 xccl = CreateXCConfigurationList(configurations)
283 for configuration in configurations:
284 xcbc = gyp.xcodeproj_file.XCBuildConfiguration({'name': configuration})
285 xccl.AppendProperty('buildConfigurations', xcbc)
286 xccl.SetProperty('defaultConfigurationName', configurations[0])
287
288 all_target = gyp.xcodeproj_file.PBXAggregateTarget( 298 all_target = gyp.xcodeproj_file.PBXAggregateTarget(
289 { 299 {
290 'buildConfigurationList': xccl, 300 'buildConfigurationList': xccl,
291 'name': 'All', 301 'name': 'All',
292 }, 302 },
293 parent=self.project) 303 parent=self.project)
294 304
295 for target in targets_for_all: 305 for target in targets_for_all:
296 all_target.AddDependency(target) 306 all_target.AddDependency(target)
297 307
298 # TODO(mark): This is evil because it relies on internal knowledge of 308 # TODO(mark): This is evil because it relies on internal knowledge of
299 # PBXProject._properties. It's important to get the "All" target first, 309 # PBXProject._properties. It's important to get the "All" target first,
300 # though. 310 # though.
301 self.project._properties['targets'].insert(0, all_target) 311 self.project._properties['targets'].insert(0, all_target)
302 312
303 # The same, but for run_test_targets. 313 # The same, but for run_test_targets.
304 if len(run_test_targets) > 1: 314 if len(run_test_targets) > 1:
305 xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []}) 315 xccl = CreateXCConfigurationList(configurations)
306 for configuration in configurations:
307 xcbc = gyp.xcodeproj_file.XCBuildConfiguration({'name': configuration})
308 xccl.AppendProperty('buildConfigurations', xcbc)
309 xccl.SetProperty('defaultConfigurationName', configurations[0])
310 run_all_tests_target = gyp.xcodeproj_file.PBXAggregateTarget( 316 run_all_tests_target = gyp.xcodeproj_file.PBXAggregateTarget(
311 { 317 {
312 'buildConfigurationList': xccl, 318 'buildConfigurationList': xccl,
313 'name': 'Run All Tests', 319 'name': 'Run All Tests',
314 }, 320 },
315 parent=self.project) 321 parent=self.project)
316 for run_test_target in run_test_targets: 322 for run_test_target in run_test_targets:
317 run_all_tests_target.AddDependency(run_test_target) 323 run_all_tests_target.AddDependency(run_test_target)
318 324
319 # Insert after the "All" target, which must exist if there is more than 325 # Insert after the "All" target, which must exist if there is more than
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 qualified_target) 580 qualified_target)
575 configuration_names = [spec['default_configuration']] 581 configuration_names = [spec['default_configuration']]
576 for configuration_name in sorted(spec['configurations'].keys()): 582 for configuration_name in sorted(spec['configurations'].keys()):
577 if configuration_name not in configuration_names: 583 if configuration_name not in configuration_names:
578 configuration_names.append(configuration_name) 584 configuration_names.append(configuration_name)
579 xcp = xcode_projects[build_file] 585 xcp = xcode_projects[build_file]
580 pbxp = xcp.project 586 pbxp = xcp.project
581 587
582 # Set up the configurations for the target according to the list of names 588 # Set up the configurations for the target according to the list of names
583 # supplied. 589 # supplied.
584 xccl = gyp.xcodeproj_file.XCConfigurationList({'buildConfigurations': []}) 590 xccl = CreateXCConfigurationList(configuration_names)
585 for configuration_name in configuration_names:
586 xcbc = gyp.xcodeproj_file.XCBuildConfiguration({
587 'name': configuration_name})
588 xccl.AppendProperty('buildConfigurations', xcbc)
589 xccl.SetProperty('defaultConfigurationName', configuration_names[0])
590 591
591 # Create an XCTarget subclass object for the target. We use the type 592 # Create an XCTarget subclass object for the target. We use the type
592 # with "+bundle" appended if the target has "mac_bundle" set. 593 # with "+bundle" appended if the target has "mac_bundle" set.
593 _types = { 594 _types = {
594 'executable': 'com.apple.product-type.tool', 595 'executable': 'com.apple.product-type.tool',
595 'loadable_module': 'com.apple.product-type.library.dynamic', 596 'loadable_module': 'com.apple.product-type.library.dynamic',
596 'shared_library': 'com.apple.product-type.library.dynamic', 597 'shared_library': 'com.apple.product-type.library.dynamic',
597 'static_library': 'com.apple.product-type.library.static', 598 'static_library': 'com.apple.product-type.library.static',
598 'executable+bundle': 'com.apple.product-type.application', 599 'executable+bundle': 'com.apple.product-type.application',
599 'loadable_module+bundle': 'com.apple.product-type.bundle', 600 'loadable_module+bundle': 'com.apple.product-type.bundle',
(...skipping 14 matching lines...) Expand all
614 xctarget_type = gyp.xcodeproj_file.PBXNativeTarget 615 xctarget_type = gyp.xcodeproj_file.PBXNativeTarget
615 try: 616 try:
616 target_properties['productType'] = _types[type_bundle_key] 617 target_properties['productType'] = _types[type_bundle_key]
617 except KeyError, e: 618 except KeyError, e:
618 gyp.common.ExceptionAppend(e, "-- unknown product type while " 619 gyp.common.ExceptionAppend(e, "-- unknown product type while "
619 "writing target %s" % target_name) 620 "writing target %s" % target_name)
620 raise 621 raise
621 else: 622 else:
622 xctarget_type = gyp.xcodeproj_file.PBXAggregateTarget 623 xctarget_type = gyp.xcodeproj_file.PBXAggregateTarget
623 624
624 if 'product_name' in spec: 625 target_product_name = spec.get('product_name', None)
625 target_properties['productName'] = spec['product_name'] 626 if target_product_name:
627 target_properties['productName'] = target_product_name
626 628
627 xct = xctarget_type(target_properties, parent=pbxp, 629 xct = xctarget_type(target_properties, parent=pbxp,
628 force_extension=spec.get('product_extension', None)) 630 force_extension=spec.get('product_extension', None))
629 pbxp.AppendProperty('targets', xct) 631 pbxp.AppendProperty('targets', xct)
630 xcode_targets[qualified_target] = xct 632 xcode_targets[qualified_target] = xct
631 xcode_target_to_target_dict[xct] = spec 633 xcode_target_to_target_dict[xct] = spec
632 634
633 # Xcode does not have a distinct type for loadable_modules that are pure 635 # Xcode does not have a distinct type for loadable_modules that are pure
634 # BSD targets (ie-unbundled). It uses the same setup as a shared_library 636 # BSD targets (ie-unbundled). It uses the same setup as a shared_library
635 # but the mach-o type is explictly set in the settings. So before we do 637 # but the mach-o type is explictly set in the settings. So before we do
636 # anything else, for this one case, we stuff in that one setting. This 638 # anything else, for this one case, we stuff in that one setting. This
637 # would allow the other data in the spec to change it if need be. 639 # would allow the other data in the spec to change it if need be.
638 if type == 'loadable_module' and not is_bundle: 640 if type == 'loadable_module' and not is_bundle:
639 xccl.SetBuildSetting('MACH_O_TYPE', 'mh_bundle') 641 xccl.SetBuildSetting('MACH_O_TYPE', 'mh_bundle')
640 642
643 spec_actions = spec.get('actions', [])
644 spec_rules = spec.get('rules', [])
645
646 # Xcode has some "issues" with checking dependencies for the "Compile
647 # sources" step with any source files/headers generated by actions/rules.
648 # To work around this, if a target is building anything directly (not
649 # type "none"), then a second target as used to run the GYP actions/rules
650 # and is made a dependency of this target. This way the work is done
651 # before the dependency checks for what should be recompiled.
652 support_xct = None
653 if type != 'none' and (spec_actions or spec_rules):
654 support_xccl = CreateXCConfigurationList(configuration_names);
655 support_target_properties = {
656 'buildConfigurationList': support_xccl,
657 'name': target_name + ' Support',
658 }
659 if target_product_name:
660 support_target_properties['productName'] = \
661 target_product_name + ' Support'
662 support_xct = \
663 gyp.xcodeproj_file.PBXAggregateTarget(support_target_properties,
664 parent=pbxp)
665 pbxp.AppendProperty('targets', support_xct)
666 xct.AddDependency(support_xct)
667 # Hang the support target off the main target so it can be tested/found
668 # by the generator during Finalize.
669 xct.support_target = support_xct
670
641 prebuild_index = 0 671 prebuild_index = 0
642 672
643 # Add custom shell script phases for "actions" sections. 673 # Add custom shell script phases for "actions" sections.
644 for action in spec.get('actions', []): 674 for action in spec_actions:
645 # There's no need to write anything into the script to ensure that the 675 # There's no need to write anything into the script to ensure that the
646 # output directories already exist, because Xcode will look at the 676 # output directories already exist, because Xcode will look at the
647 # declared outputs and automatically ensure that they exist for us. 677 # declared outputs and automatically ensure that they exist for us.
648 678
649 # Do we have a message to print when this action runs? 679 # Do we have a message to print when this action runs?
650 message = action.get('message') 680 message = action.get('message')
651 if message: 681 if message:
652 message = 'echo note: ' + gyp.common.EncodePOSIXShellArgument(message) 682 message = 'echo note: ' + gyp.common.EncodePOSIXShellArgument(message)
653 else: 683 else:
654 message = '' 684 message = ''
(...skipping 15 matching lines...) Expand all
670 # exits signalling an error. 700 # exits signalling an error.
671 script += 'exec ' + action_string_sh + '\nexit 1\n' 701 script += 'exec ' + action_string_sh + '\nexit 1\n'
672 ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({ 702 ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({
673 'inputPaths': action['inputs'], 703 'inputPaths': action['inputs'],
674 'name': 'Action "' + action['action_name'] + '"', 704 'name': 'Action "' + action['action_name'] + '"',
675 'outputPaths': action['outputs'], 705 'outputPaths': action['outputs'],
676 'shellScript': script, 706 'shellScript': script,
677 'showEnvVarsInLog': 0, 707 'showEnvVarsInLog': 0,
678 }) 708 })
679 709
680 # TODO(mark): this assumes too much knowledge of the internals of 710 if support_xct:
681 # xcodeproj_file; some of these smarts should move into xcodeproj_file 711 support_xct.AppendProperty('buildPhases', ssbp)
682 # itself. 712 else:
683 xct._properties['buildPhases'].insert(prebuild_index, ssbp) 713 # TODO(mark): this assumes too much knowledge of the internals of
684 prebuild_index = prebuild_index + 1 714 # xcodeproj_file; some of these smarts should move into xcodeproj_file
715 # itself.
716 xct._properties['buildPhases'].insert(prebuild_index, ssbp)
717 prebuild_index = prebuild_index + 1
685 718
686 # TODO(mark): Should verify that at most one of these is specified. 719 # TODO(mark): Should verify that at most one of these is specified.
687 if int(action.get('process_outputs_as_sources', False)): 720 if int(action.get('process_outputs_as_sources', False)):
688 for output in action['outputs']: 721 for output in action['outputs']:
689 AddSourceToTarget(output, pbxp, xct) 722 AddSourceToTarget(output, pbxp, xct)
690 723
691 if int(action.get('process_outputs_as_mac_bundle_resources', False)): 724 if int(action.get('process_outputs_as_mac_bundle_resources', False)):
692 for output in action['outputs']: 725 for output in action['outputs']:
693 AddResourceToTarget(output, pbxp, xct) 726 AddResourceToTarget(output, pbxp, xct)
694 727
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 # compile. The rule action script would need to touch the dummy. 760 # compile. The rule action script would need to touch the dummy.
728 # 6584839 I need a way to declare additional inputs to a custom rule. 761 # 6584839 I need a way to declare additional inputs to a custom rule.
729 # A possible workaround is a shell script phase prior to 762 # A possible workaround is a shell script phase prior to
730 # compilation that touches a rule's primary input files if any 763 # compilation that touches a rule's primary input files if any
731 # would-be additional inputs are newer than the output. Modifying 764 # would-be additional inputs are newer than the output. Modifying
732 # the source tree - even just modification times - feels dirty. 765 # the source tree - even just modification times - feels dirty.
733 # 6564240 Xcode "custom script" build rules always dump all environment 766 # 6564240 Xcode "custom script" build rules always dump all environment
734 # variables. This is a low-prioroty problem and is not a 767 # variables. This is a low-prioroty problem and is not a
735 # show-stopper. 768 # show-stopper.
736 rules_by_ext = {} 769 rules_by_ext = {}
737 for rule in spec.get('rules', []): 770 for rule in spec_rules:
738 rules_by_ext[rule['extension']] = rule 771 rules_by_ext[rule['extension']] = rule
739 772
740 # First, some definitions: 773 # First, some definitions:
741 # 774 #
742 # A "rule source" is a file that was listed in a target's "sources" 775 # A "rule source" is a file that was listed in a target's "sources"
743 # list and will have a rule applied to it on the basis of matching the 776 # list and will have a rule applied to it on the basis of matching the
744 # rule's "extensions" attribute. Rule sources are direct inputs to 777 # rule's "extensions" attribute. Rule sources are direct inputs to
745 # rules. 778 # rules.
746 # 779 #
747 # Rule definitions may specify additional inputs in their "inputs" 780 # Rule definitions may specify additional inputs in their "inputs"
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 fi 978 fi
946 exec "${DEVELOPER_BIN_DIR}/make" -f "${PROJECT_FILE_PATH}/%s" -j "${JOB_COUNT}" 979 exec "${DEVELOPER_BIN_DIR}/make" -f "${PROJECT_FILE_PATH}/%s" -j "${JOB_COUNT}"
947 exit 1 980 exit 1
948 """ % makefile_name 981 """ % makefile_name
949 ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({ 982 ssbp = gyp.xcodeproj_file.PBXShellScriptBuildPhase({
950 'name': 'Rule "' + rule['rule_name'] + '"', 983 'name': 'Rule "' + rule['rule_name'] + '"',
951 'shellScript': script, 984 'shellScript': script,
952 'showEnvVarsInLog': 0, 985 'showEnvVarsInLog': 0,
953 }) 986 })
954 987
955 # TODO(mark): this assumes too much knowledge of the internals of 988 if support_xct:
956 # xcodeproj_file; some of these smarts should move into xcodeproj_file 989 support_xct.AppendProperty('buildPhases', ssbp)
957 # itself. 990 else:
958 xct._properties['buildPhases'].insert(prebuild_index, ssbp) 991 # TODO(mark): this assumes too much knowledge of the internals of
959 prebuild_index = prebuild_index + 1 992 # xcodeproj_file; some of these smarts should move into xcodeproj_file
993 # itself.
994 xct._properties['buildPhases'].insert(prebuild_index, ssbp)
995 prebuild_index = prebuild_index + 1
960 996
961 # Extra rule inputs also go into the project file. Concrete outputs were 997 # Extra rule inputs also go into the project file. Concrete outputs were
962 # already added when they were computed. 998 # already added when they were computed.
963 for group in ['inputs', 'inputs_excluded']: 999 for group in ['inputs', 'inputs_excluded']:
964 for item in rule.get(group, []): 1000 for item in rule.get(group, []):
965 pbxp.AddOrGetFileInRootGroup(item) 1001 pbxp.AddOrGetFileInRootGroup(item)
966 1002
967 # Add "sources". 1003 # Add "sources".
968 for source in spec.get('sources', []): 1004 for source in spec.get('sources', []):
969 (source_root, source_extension) = posixpath.splitext(source) 1005 (source_root, source_extension) = posixpath.splitext(source)
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
1035 # libraries. On some systems, ld is finicky and even requires the 1071 # libraries. On some systems, ld is finicky and even requires the
1036 # libraries to be ordered in such a way that unresolved symbols in 1072 # libraries to be ordered in such a way that unresolved symbols in
1037 # earlier-listed libraries may only be resolved by later-listed libraries. 1073 # earlier-listed libraries may only be resolved by later-listed libraries.
1038 # The Mac linker doesn't work that way, but other platforms do, and so 1074 # The Mac linker doesn't work that way, but other platforms do, and so
1039 # their linker invocations need to be constructed in this way. There's 1075 # their linker invocations need to be constructed in this way. There's
1040 # no compelling reason for Xcode's linker invocations to differ. 1076 # no compelling reason for Xcode's linker invocations to differ.
1041 1077
1042 if 'dependencies' in spec: 1078 if 'dependencies' in spec:
1043 for dependency in spec['dependencies']: 1079 for dependency in spec['dependencies']:
1044 xct.AddDependency(xcode_targets[dependency]) 1080 xct.AddDependency(xcode_targets[dependency])
1081 # The support project also gets the dependencies (in case they are
1082 # needed for the actions/rules to work).
1083 if support_xct:
1084 support_xct.AddDependency(xcode_targets[dependency])
1045 1085
1046 if 'libraries' in spec: 1086 if 'libraries' in spec:
1047 for library in spec['libraries']: 1087 for library in spec['libraries']:
1048 xct.FrameworksPhase().AddFile(library) 1088 xct.FrameworksPhase().AddFile(library)
1049 # Add the library's directory to LIBRARY_SEARCH_PATHS if necessary. 1089 # Add the library's directory to LIBRARY_SEARCH_PATHS if necessary.
1050 # I wish Xcode handled this automatically. 1090 # I wish Xcode handled this automatically.
1051 # TODO(mark): this logic isn't right. There are certain directories 1091 # TODO(mark): this logic isn't right. There are certain directories
1052 # that are always searched, we should check to see if the library is 1092 # that are always searched, we should check to see if the library is
1053 # in one of those directories, and if not, we should do the 1093 # in one of those directories, and if not, we should do the
1054 # AppendBuildSetting thing. 1094 # AppendBuildSetting thing.
(...skipping 30 matching lines...) Expand all
1085 1125
1086 for build_file in build_files: 1126 for build_file in build_files:
1087 xcode_projects[build_file].Finalize1(xcode_targets, serialize_all_tests) 1127 xcode_projects[build_file].Finalize1(xcode_targets, serialize_all_tests)
1088 1128
1089 for build_file in build_files: 1129 for build_file in build_files:
1090 xcode_projects[build_file].Finalize2(xcode_targets, 1130 xcode_projects[build_file].Finalize2(xcode_targets,
1091 xcode_target_to_target_dict) 1131 xcode_target_to_target_dict)
1092 1132
1093 for build_file in build_files: 1133 for build_file in build_files:
1094 xcode_projects[build_file].Write() 1134 xcode_projects[build_file].Write()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698