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

Side by Side Diff: site_scons/site_tools/_Node_MSVS.py

Issue 17327: Back out r7826, which broke the Linux build (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: Created 11 years, 11 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
« no previous file with comments | « net/tools/tld_cleanup/tld_cleanup.scons ('k') | site_scons/site_tools/chromium_builders.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # 1 #
2 # __COPYRIGHT__ 2 # __COPYRIGHT__
3 # 3 #
4 # Permission is hereby granted, free of charge, to any person obtaining 4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and associated documentation files (the 5 # a copy of this software and associated documentation files (the
6 # "Software"), to deal in the Software without restriction, including 6 # "Software"), to deal in the Software without restriction, including
7 # without limitation the rights to use, copy, modify, merge, publish, 7 # without limitation the rights to use, copy, modify, merge, publish,
8 # distribute, sublicense, and/or sell copies of the Software, and to 8 # distribute, sublicense, and/or sell copies of the Software, and to
9 # permit persons to whom the Software is furnished to do so, subject to 9 # permit persons to whom the Software is furnished to do so, subject to
10 # the following conditions: 10 # the following conditions:
(...skipping 21 matching lines...) Expand all
32 import os 32 import os
33 import random 33 import random
34 import re 34 import re
35 import UserList 35 import UserList
36 import xml.dom 36 import xml.dom
37 import xml.dom.minidom 37 import xml.dom.minidom
38 38
39 import SCons.Node.FS 39 import SCons.Node.FS
40 import SCons.Script 40 import SCons.Script
41 41
42 from SCons.Debug import Trace
43 TODO = 0
44 42
45 # Initialize random number generator 43 # Initialize random number generator
46 random.seed() 44 random.seed()
47 45
48 46
49 #------------------------------------------------------------------------------ 47 #------------------------------------------------------------------------------
50 # Entry point for supplying a fixed map of GUIDs for testing. 48 # Entry point for supplying a fixed map of GUIDs for testing.
51 49
52 GUIDMap = {} 50 GUIDMap = {}
53 51
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 def get_msvs_path(self, sln): 257 def get_msvs_path(self, sln):
260 return self.msvs_name 258 return self.msvs_name
261 259
262 def MSVSFolder(env, item, *args, **kw): 260 def MSVSFolder(env, item, *args, **kw):
263 return LookupCreate(_MSVSFolder, item, *args, **kw) 261 return LookupCreate(_MSVSFolder, item, *args, **kw)
264 262
265 #------------------------------------------------------------------------------ 263 #------------------------------------------------------------------------------
266 264
267 class MSVSConfig(object): 265 class MSVSConfig(object):
268 """Visual Studio configuration.""" 266 """Visual Studio configuration."""
269 def __init__(self, Name, config_type, tools=None, **attrs): 267 def __init__(self, Name, config_type, tools=[], **attrs):
270 """Initializes the configuration. 268 """Initializes the configuration.
271 269
272 Args: 270 Args:
273 **attrs: Configuration attributes. 271 **attrs: Configuration attributes.
274 """ 272 """
275 # Special handling for attributes that we want to make more 273 # Special handling for attributes that we want to make more
276 # convenient for the user. 274 # convenient for the user.
277 ips = attrs.get('InheritedPropertySheets') 275 ips = attrs.get('InheritedPropertySheets')
278 if ips: 276 if ips:
279 if isinstance(ips, list): 277 if isinstance(ips, list):
280 ips = ';'.join(ips) 278 ips = ';'.join(ips)
281 attrs['InheritedPropertySheets'] = ips.replace('/', '\\') 279 attrs['InheritedPropertySheets'] = ips.replace('/', '\\')
282 280
281 tools = tools or []
282 if not SCons.Util.is_List(tools):
283 tools = [tools]
284 tool_objects = []
285 for t in tools:
286 if not isinstance(t, MSVSTool):
287 t = MSVSTool(t)
288 tool_objects.append(t)
289
283 self.Name = Name 290 self.Name = Name
284 self.config_type = config_type 291 self.config_type = config_type
285 self.tools = tools 292 self.tools = tool_objects
286 self.attrs = attrs 293 self.attrs = attrs
287 294
288 def CreateElement(self, doc, project): 295 def CreateElement(self, doc):
289 """Creates an element for the configuration. 296 """Creates an element for the configuration.
290 297
291 Args: 298 Args:
292 doc: xml.dom.Document object to use for node creation. 299 doc: xml.dom.Document object to use for node creation.
293 300
294 Returns: 301 Returns:
295 A new xml.dom.Element for the configuration. 302 A new xml.dom.Element for the configuration.
296 """ 303 """
297 node = doc.createElement(self.config_type) 304 node = doc.createElement(self.config_type)
298 node.setAttribute('Name', self.Name) 305 node.setAttribute('Name', self.Name)
299 for k, v in self.attrs.items(): 306 for k, v in self.attrs.items():
300 node.setAttribute(k, v) 307 node.setAttribute(k, v)
301 308 for t in self.tools:
302 tools = self.tools
303 if tools is None:
304 tools = project.tools or []
305 if not SCons.Util.is_List(tools):
306 tools = [tools]
307 tool_objects = []
308 for t in tools:
309 if not isinstance(t, MSVSTool):
310 t = MSVSTool(t)
311 tool_objects.append(t)
312 for t in tool_objects:
313 node.appendChild(t.CreateElement(doc)) 309 node.appendChild(t.CreateElement(doc))
314
315 return node 310 return node
316 311
317 312
318 class MSVSFileListBase(FileList): 313 class MSVSFileListBase(FileList):
319 """Base class for a file list in a Visual Studio project file.""" 314 """Base class for a file list in a Visual Studio project file."""
320 315
321 def CreateElement(self, doc, node_func=lambda x: x): 316 def CreateElement(self, doc, node_func=lambda x: x):
322 """Creates an element for an MSVSFileListBase subclass. 317 """Creates an element for an MSVSFileListBase subclass.
323 318
324 Args: 319 Args:
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 391
397 Returns: 392 Returns:
398 A new xml.dom.Element for the tool. 393 A new xml.dom.Element for the tool.
399 """ 394 """
400 node = doc.createElement('Tool') 395 node = doc.createElement('Tool')
401 node.setAttribute('Name', self.Name) 396 node.setAttribute('Name', self.Name)
402 for k, v in self.attrs.items(): 397 for k, v in self.attrs.items():
403 node.setAttribute(k, v) 398 node.setAttribute(k, v)
404 return node 399 return node
405 400
406 def _format(self):
407 """Formats a tool specification for debug printing"""
408 xml_impl = xml.dom.getDOMImplementation()
409 doc = xml_impl.createDocument(None, 'VisualStudioProject', None)
410 return self.CreateElement(doc).toprettyxml()
411
412 def diff(self, other):
413 for key, value in self.attrs.items():
414 if other.attrs[key] == value:
415 del self.attrs[key]
416
417 401
418 class MSVSToolFile(object): 402 class MSVSToolFile(object):
419 """Visual Studio tool file specification.""" 403 """Visual Studio tool file specification."""
420 404
421 def __init__(self, node, **attrs): 405 def __init__(self, node, **attrs):
422 """Initializes the tool. 406 """Initializes the tool.
423 407
424 Args: 408 Args:
425 node: Node for the Tool File 409 node: Node for the Tool File
426 **attrs: Tool File attributes. 410 **attrs: Tool File attributes.
(...skipping 11 matching lines...) Expand all
438 def MSVSAction(target, source, env): 422 def MSVSAction(target, source, env):
439 target[0].Write(env) 423 target[0].Write(env)
440 424
441 MSVSProjectAction = SCons.Script.Action(MSVSAction, 425 MSVSProjectAction = SCons.Script.Action(MSVSAction,
442 "Generating Visual Studio project `$TARG ET' ...") 426 "Generating Visual Studio project `$TARG ET' ...")
443 427
444 class _MSVSProject(SCons.Node.FS.File): 428 class _MSVSProject(SCons.Node.FS.File):
445 """Visual Studio project.""" 429 """Visual Studio project."""
446 430
447 entry_type_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' 431 entry_type_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}'
448 initialized = False
449 432
450 def initialize(self, env, path, name = None, 433 def initialize(self, env, path, name = None,
451 dependencies = None, 434 dependencies = None,
452 guid = None, 435 guid = None,
453 buildtargets = [], 436 buildtargets = [],
454 files = [], 437 files = [],
455 root_namespace = None, 438 root_namespace = None,
456 relative_path_prefix = '', 439 relative_path_prefix = '',
457 tools = None, 440 tools = None,
458 configurations = None, 441 configurations = None):
459 **attrs):
460 """Initializes the project. 442 """Initializes the project.
461 443
462 Args: 444 Args:
463 path: Relative path to project file. 445 path: Relative path to project file.
464 name: Name of project. If None, the name will be the same as the base 446 name: Name of project. If None, the name will be the same as the base
465 name of the project file. 447 name of the project file.
466 dependencies: List of other Project objects this project is dependent 448 dependencies: List of other Project objects this project is dependent
467 upon, if not None. 449 upon, if not None.
468 guid: GUID to use for project, if not None. 450 guid: GUID to use for project, if not None.
469 buildtargets: List of target(s) being built by this project. 451 buildtargets: List of target(s) being built by this project.
470 files: List of source files for the project. This will be 452 files: List of source files for the project. This will be
471 supplemented by any source files of buildtargets. 453 supplemented by any source files of buildtargets.
472 root_namespace: The value of the RootNamespace attribute of the 454 root_namespace: The value of the RootNamespace attribute of the
473 project, if not None. The default is to use the same 455 project, if not None. The default is to use the same
474 string as the name. 456 string as the name.
475 relative_path_prefix: A prefix to be appended to the beginning of 457 relative_path_prefix: A prefix to be appended to the beginning of
476 every file name in the list. The canonical use is to specify 458 every file name in the list. The canonical use is to specify
477 './' to make files explicitly relative to the local directory. 459 './' to make files explicitly relative to the local directory.
478 tools: A list of MSVSTool objects or strings representing 460 tools: A list of MSVSTool objects or strings representing
479 tools to be used to build this project. This will be used 461 tools to be used to build this project. This will be used
480 for any configurations that don't provide their own 462 for any configurations that don't provide their own
481 per-configuration tool list. 463 per-configuration tool list.
482 configurations: A list of MSVSConfig objects representing 464 configurations: A list of MSVSConfig objects representing
483 configurations built by this project. 465 configurations built by this project.
484 """ 466 """
467 self.msvs_path = path
468 self.msvs_node = env.File(path)
485 if name is None: 469 if name is None:
486 if buildtargets: 470 if buildtargets:
487 name = os.path.splitext(buildtargets[0].name)[0] 471 name = os.path.splitext(buildtargets[0].name)[0]
488 else: 472 else:
489 name = os.path.splitext(os.path.basename(path))[0] 473 name = os.path.splitext(os.path.basename(path))[0]
490 if not root_namespace: 474 self.msvs_name = name
491 root_namespace or name 475 self.root_namespace = root_namespace or self.msvs_name
476 self.buildtargets = buildtargets
477 self.relative_path_prefix = relative_path_prefix
478 self.tools = tools
492 479
493 if self.initialized:
494 # TODO(sgk): fill in
495 if self.msvs_name != name:
496 pass
497 if self.root_namespace != root_namespace:
498 pass
499 if self.relative_path_prefix != relative_path_prefix:
500 pass
501 if self.guid != guid:
502 pass
503 #if self.env != env:
504 # pass
505 else:
506 self.buildtargets = []
507 self.configurations = []
508 self.dependencies = []
509 self.file_configurations = {}
510 self.files = MSVSFiles([])
511 self.tool_files = []
512 self.file_lists = []
513 self.initialized = True
514
515 self.attrs = attrs
516 self.env = env 480 self.env = env
517 self.guid = guid 481 self.guid = guid
518 self.msvs_name = name
519 self.msvs_path = path
520 self.relative_path_prefix = relative_path_prefix
521 self.root_namespace = root_namespace or self.msvs_name
522 self.tools = tools
523 482
524 self.buildtargets.extend(buildtargets) 483 self.dependencies = list(dependencies or [])
525 self.configurations.extend(configurations or []) 484 self.configurations = list(configurations or [])
526 self.dependencies.extend(list(dependencies or [])) 485 self.file_configurations = {}
527 self.AddFiles(files) 486 self.tool_files = []
528 487
529 env.Command(self, [], MSVSProjectAction) 488 if not isinstance(files, MSVSFiles):
489 files = MSVSFiles(self.args2nodes(files))
490 self.files = files
491
492 env.Command(self, [], MSVSSolutionAction)
530 493
531 def args2nodes(self, entries): 494 def args2nodes(self, entries):
532 result = [] 495 result = []
533 for entry in entries: 496 for entry in entries:
534 if SCons.Util.is_String(entry): 497 if SCons.Util.is_String(entry):
535 entry = self.env.File(entry) 498 entry = self.env.File(entry)
536 result.append(entry) 499 result.append(entry)
537 elif hasattr(entry, 'entries'): 500 elif hasattr(entry, 'entries'):
538 entry.entries = self.args2nodes(entry.entries) 501 entry.entries = self.args2nodes(entry.entries)
539 result.append(entry) 502 result.append(entry)
540 elif isinstance(entry, (list, UserList.UserList)): 503 elif isinstance(entry, (list, UserList.UserList)):
541 result.extend(self.args2nodes(entry)) 504 result.extend(self.args2nodes(entry))
542 elif hasattr(entry, 'sources') and entry.sources: 505 elif hasattr(entry, 'sources') and entry.sources:
543 result.extend(entry.sources) 506 result.extend(entry.sources)
544 else: 507 else:
545 result.append(entry.srcnode()) 508 result.append(entry)
546 return result 509 return result
547 510
548 def FindFile(self, node): 511 def FindFile(self, node):
549 try: 512 try:
550 flat_file_dict = self.flat_file_dict 513 flat_file_dict = self.flat_file_dict
551 except AttributeError: 514 except AttributeError:
552 flat_file_dict = {} 515 flat_file_dict = {}
553 file_list = self.files[:] 516 file_list = self.files[:]
554 while file_list: 517 while file_list:
555 entry = file_list.pop(0) 518 entry = file_list.pop(0)
556 if not isinstance(entry, (list, UserList.UserList)): 519 if not isinstance(entry, (list, UserList.UserList)):
557 entry = [entry] 520 entry = [entry]
558 for f in entry: 521 for f in entry:
559 if hasattr(f, 'entries'): 522 if hasattr(f, 'entries'):
560 file_list.extend(f.entries) 523 file_list.extend(f.entries)
561 else: 524 else:
562 flat_file_dict[f] = True 525 flat_file_dict[f] = True
563 flat_file_dict[f.srcnode()] = True
564 if hasattr(f, 'sources'): 526 if hasattr(f, 'sources'):
565 for s in f.sources: 527 for s in f.sources:
566 flat_file_dict[s] = True 528 flat_file_dict[s] = True
567 flat_file_dict[s.srcnode()] = True
568 self.flat_file_dict = flat_file_dict 529 self.flat_file_dict = flat_file_dict
569 530
570 return flat_file_dict.get(node) 531 return flat_file_dict.get(node)
571 532
572 def get_guid(self): 533 def get_guid(self):
573 if self.guid is None: 534 if self.guid is None:
574 guid = GUIDMap.get(self.msvs_path) 535 guid = GUIDMap.get(self.msvs_path)
575 if not guid: 536 if not guid:
576 # Set GUID from path 537 # Set GUID from path
577 # TODO(rspangler): This is fragile. 538 # TODO(rspangler): This is fragile.
578 # 1. We can't just use the project filename sans path, since there 539 # 1. We can't just use the project filename sans path, since there
579 # could be multiple projects with the same base name (for example, 540 # could be multiple projects with the same base name (for example,
580 # foo/unittest.vcproj and bar/unittest.vcproj). 541 # foo/unittest.vcproj and bar/unittest.vcproj).
581 # 2. The path needs to be relative to $SOURCE_ROOT, so that the project 542 # 2. The path needs to be relative to $SOURCE_ROOT, so that the project
582 # GUID is the same whether it's included from base/base.sln or 543 # GUID is the same whether it's included from base/base.sln or
583 # foo/bar/baz/baz.sln. 544 # foo/bar/baz/baz.sln.
584 # 3. The GUID needs to be the same each time this builder is invoked, 545 # 3. The GUID needs to be the same each time this builder is invoked,
585 # so that we don't need to rebuild the solution when the 546 # so that we don't need to rebuild the solution when the
586 # project changes. 547 # project changes.
587 # 4. We should be able to handle pre-built project files by reading the 548 # 4. We should be able to handle pre-built project files by reading the
588 # GUID from the files. 549 # GUID from the files.
589 guid = MakeGuid(self.msvs_path) 550 guid = MakeGuid(self.msvs_path)
590 self.guid = guid 551 self.guid = guid
591 return self.guid 552 return self.guid
592 553
593 def get_msvs_path(self, sln): 554 def get_msvs_path(self, sln):
594 return sln.rel_path(self).replace('/', '\\') 555 return sln.rel_path(self).replace('/', '\\')
595 556
596 def get_rel_path(self, node): 557 def get_rel_path(self, node):
597 result = self.relative_path_prefix + self.rel_path(node) 558 result = self.relative_path_prefix + self.msvs_node.rel_path(node)
598 return result.replace('/', '\\') 559 return result.replace('/', '\\')
599 560
600 def AddConfig(self, Name, tools=None, **attrs): 561 def AddConfig(self, Name, tools=None, **attrs):
601 """Adds a configuration to the parent node. 562 """Adds a configuration to the parent node.
602 563
603 Args: 564 Args:
604 Name: The name of the configuration. 565 Name: The name of the configuration.
605 tools: List of tools (strings or Tool objects); may be None. 566 tools: List of tools (strings or Tool objects); may be None.
606 **attrs: Configuration attributes. 567 **attrs: Configuration attributes.
607 """ 568 """
608 if tools is None: 569 if tools is None:
609 # No tool list specifically for this configuration, 570 # No tool list specifically for this configuration,
610 # use the Project's as a default. 571 # use the Project's as a default.
611 tools = self.tools 572 tools = self.tools
612 if not attrs.has_key('ConfigurationType'):
613 # No ConfigurationType specifically for this configuration,
614 # use the Project's as a default.
615 try:
616 attrs['ConfigurationType'] = self.attrs['ConfigurationType']
617 except KeyError:
618 pass
619 if attrs.has_key('InheritedPropertySheets'):
620 ips = attrs['InheritedPropertySheets']
621 attrs['InheritedPropertySheets'] = self.env.subst(ips)
622 c = MSVSConfig(Name, 'Configuration', tools=tools, **attrs) 573 c = MSVSConfig(Name, 'Configuration', tools=tools, **attrs)
623 self.configurations.append(c) 574 self.configurations.append(c)
624 575
625 def AddFiles(self, files): 576 def AddFiles(self, files):
626 """Adds files to the project. 577 """Adds files to the project.
627 578
628 Args: 579 Args:
629 files: A list of Filter objects and/or relative paths to files. 580 files: A list of Filter objects and/or relative paths to files.
630 581
631 This makes a copy of the file/filter tree at the time of this call. If you 582 This makes a copy of the file/filter tree at the time of this call. If you
632 later add files to a Filter object which was passed into a previous call 583 later add files to a Filter object which was passed into a previous call
633 to AddFiles(), it will not be reflected in this project. 584 to AddFiles(), it will not be reflected in this project.
634 """ 585 """
635 self.file_lists.append(self.args2nodes(files)) 586 # TODO(rspangler) This also doesn't handle adding files to an existing
636 587 # filter. That is, it doesn't merge the trees.
637 def _FilesToSourceFiles(self, files): 588 self.files.extend(self.args2nodes(files))
638 file_list = files[:]
639 result = []
640 while file_list:
641 entry = file_list.pop(0)
642 if not isinstance(entry, (list, UserList.UserList)):
643 entry = [entry]
644 for f in entry:
645 if hasattr(f, 'entries'):
646 self._FilesToSourceFiles(f.entries)
647 result.append(f)
648 else:
649 if f.sources:
650 flist = f.sources
651 else:
652 flist = [f]
653 for x in flist:
654 result.append(x.srcnode())
655 files[:] = result
656
657 def _MergeFiles(self, dest_list, src_list):
658 for f in src_list:
659 if f not in dest_list:
660 dest_list.append(f)
661 continue
662 #if hasattr(f, 'entries'):
663 # self._FilesToSourceFiles(f.entries)
664 589
665 def AddFileConfig(self, path, Name, tools=None, **attrs): 590 def AddFileConfig(self, path, Name, tools=None, **attrs):
666 """Adds a configuration to a file. 591 """Adds a configuration to a file.
667 592
668 Args: 593 Args:
669 path: Relative path to the file. 594 path: Relative path to the file.
670 Name: Name of configuration to add. 595 Name: Name of configuration to add.
671 tools: List of tools (strings or MSVSTool objects); may be None. 596 tools: List of tools (strings or MSVSTool objects); may be None.
672 **attrs: Configuration attributes. 597 **attrs: Configuration attributes.
673 598
674 Raises: 599 Raises:
675 ValueError: Relative path does not match any file added via AddFiles(). 600 ValueError: Relative path does not match any file added via AddFiles().
676 """ 601 """
677 # Store as the VariantDir node, not as the source node.
678 node = self.env.File(path) 602 node = self.env.File(path)
603 if not self.FindFile(node):
604 raise ValueError('AddFileConfig: file "%s" not in project' % path)
679 c = MSVSConfig(Name, 'FileConfiguration', tools=tools, **attrs) 605 c = MSVSConfig(Name, 'FileConfiguration', tools=tools, **attrs)
680 config_list = self.file_configurations.get(node) 606 config_list = self.file_configurations.get(node)
681 if config_list is None: 607 if config_list is None:
682 config_list = [] 608 config_list = []
683 self.file_configurations[node] = config_list 609 self.file_configurations[node] = config_list
684 config_list.append(c) 610 config_list.append(c)
685 611
686 def AddToolFile(self, path): 612 def AddToolFile(self, path):
687 """Adds a tool file to the project. 613 """Adds a tool file to the project.
688 614
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 # Add tool files section 648 # Add tool files section
723 tool_files = self.doc.createElement('ToolFiles') 649 tool_files = self.doc.createElement('ToolFiles')
724 root.appendChild(tool_files) 650 root.appendChild(tool_files)
725 for tf in self.tool_files: 651 for tf in self.tool_files:
726 tool_files.appendChild(tf.CreateElement(self.doc, self)) 652 tool_files.appendChild(tf.CreateElement(self.doc, self))
727 653
728 # Add configurations section 654 # Add configurations section
729 configs = self.doc.createElement('Configurations') 655 configs = self.doc.createElement('Configurations')
730 root.appendChild(configs) 656 root.appendChild(configs)
731 for c in self.configurations: 657 for c in self.configurations:
732 configs.appendChild(c.CreateElement(self.doc, self)) 658 configs.appendChild(c.CreateElement(self.doc))
733 659
734 # Add empty References section 660 # Add empty References section
735 root.appendChild(self.doc.createElement('References')) 661 root.appendChild(self.doc.createElement('References'))
736 662
737 # Add files section 663 # Add files section
738 root.appendChild(self.files.CreateElement(self.doc, self.CreateFileElement)) 664 root.appendChild(self.files.CreateElement(self.doc, self.CreateFileElement))
739 665
740 # Add empty Globals section 666 # Add empty Globals section
741 root.appendChild(self.doc.createElement('Globals')) 667 root.appendChild(self.doc.createElement('Globals'))
742 668
743 def CreateFileElement(self, file): 669 def CreateFileElement(self, file):
744 """Create a DOM node for the specified file. 670 """Create a DOM node for the specified file.
745 671
746 Args: 672 Args:
747 file: The file Node being considered. 673 file: The file Node being considered.
748 674
749 Returns: 675 Returns:
750 A DOM Node for the File, with a relative path to the current 676 A DOM Node for the File, with a relative path to the current
751 project object, and any file configurations attached to the 677 project object, and any file configurations attached to the
752 project. 678 project.
753 """ 679 """
754 680
755 node = self.doc.createElement('File') 681 node = self.doc.createElement('File')
756 node.setAttribute('RelativePath', self.get_rel_path(file)) 682 node.setAttribute('RelativePath', self.get_rel_path(file))
757 for c in self.file_configurations.get(file, []): 683 for c in self.file_configurations.get(file, []):
758 node.appendChild(c.CreateElement(self.doc, self)) 684 node.appendChild(c.CreateElement(self.doc))
759 return node 685 return node
760 686
761 def VCCLCompilerTool(self, args): 687 def _AddFileConfigurationDifferences(self, target, source, base_env, file_env) :
762 default_attrs = {
763 'BufferSecurityCheck' : "false",
764 'CompileAs' : 0, # default
765 'DebugInformationFormat' : 0, # TODO(???)
766 'DisableSpecificWarnings' : [],
767 'EnableFiberSafeOptimizations' : "false",
768 'EnableFunctionLevelLinking' : "false",
769 'EnableIntrinsicFunctions' : "false",
770 'FavorSizeOrSpeed' : 0, # favorNone
771 'InlineFunctionExpansion' : 1, # expandDisable
772 'MinimalRebuild' : "false",
773 'OmitFramePointers' : "false",
774 'Optimization' : 1, # optimizeDisabled TODO(???)
775 'PreprocessorDefinitions' : [],
776 'RuntimeLibrary' : TODO,
777 'RuntimeTypeInfo' : "false",
778 'StringPooling' : "false",
779 'SuppressStartupBanner' : "false",
780 'WarningAsError' : "false",
781 'WarningLevel' : 1, # warningLevel_1
782 'WholeProgramOptimization' : "false",
783 }
784
785 tool = MSVSTool('VCCLCompilerTool', **default_attrs)
786 attrs = tool.attrs
787
788 for arg in args:
789 if arg in ('/c',):
790 continue
791 if arg.startswith('/Fo'):
792 continue
793 if arg.startswith('/D'):
794 attrs['PreprocessorDefinitions'].append(arg[2:])
795 elif arg == '/EH':
796 attrs['ExceptionHandling'] = 0
797 elif arg == '/GF':
798 attrs['StringPooling'] = "true"
799 elif arg == '/GL':
800 attrs['WholeProgramOptimization'] = "true"
801 elif arg == '/GM':
802 attrs['MinimalRebuild'] = "true"
803 elif arg == '/GR-':
804 attrs['RuntimeTypeInfo'] = "true"
805 elif arg == '/Gs':
806 attrs['BufferSecurityCheck'] = "true"
807 elif arg == '/Gs-':
808 attrs['BufferSecurityCheck'] = "false"
809 elif arg == '/GT':
810 attrs['EnableFiberSafeOptimizations'] = "true"
811 elif arg == '/Gy':
812 attrs['EnableFunctionLevelLinking'] = "true"
813 elif arg == '/MD':
814 attrs['RuntimeLibrary'] = 1 # rtMultiThreadedDebug
815 elif arg == '/MDd':
816 attrs['RuntimeLibrary'] = 2 # rtMultiThreadedDebugDLL
817 elif arg == '/MT':
818 attrs['RuntimeLibrary'] = 0 # rtMultiThreaded
819 elif arg == '/MTd':
820 attrs['RuntimeLibrary'] = 3 # rtMultiThreadedDLL
821 elif arg == '/nologo':
822 attrs['SuppressStartupBanner'] = "true"
823 elif arg == '/O1':
824 attrs['InlineFunctionExpansion'] = 4 # optimizeMinSpace
825 elif arg == '/O2':
826 attrs['InlineFunctionExpansion'] = 3 # optimizeMaxSpeed
827 elif arg == '/Ob1':
828 attrs['InlineFunctionExpansion'] = 2 # expandOnlyInline
829 elif arg == '/Ob2':
830 attrs['InlineFunctionExpansion'] = 0 # expandAnySuitable
831 elif arg == '/Od':
832 attrs['Optimization'] = 0
833 elif arg == '/Oi':
834 attrs['EnableIntrinsicFunctions'] = "true"
835 elif arg == '/Os':
836 attrs['FavorSizeOrSpeed'] = 1 # favorSize
837 elif arg == '/Ot':
838 attrs['FavorSizeOrSpeed'] = 2 # favorSpeed
839 elif arg == '/Ox':
840 attrs['Optimization'] = 2 # optimizeFull
841 elif arg == '/Oy':
842 attrs['OmitFramePointers'] = "true"
843 elif arg == '/Oy-':
844 attrs['TODO'] = "true"
845 elif arg in ('/Tc', '/TC'):
846 attrs['CompileAs'] = 1 # compileAsC
847 elif arg in ('/Tp', '/TP'):
848 attrs['CompileAs'] = 2 # compileAsCPlusPlus
849 elif arg == '/WX':
850 attrs['WarnAsError'] = "true"
851 elif arg.startswith('/W'):
852 attrs['WarningLevel'] = int(arg[2:]) # 0 through 4
853 elif arg.startswith('/wd'):
854 attrs['DisableSpecificWarnings'].append(str(arg[3:]))
855 elif arg == '/Z7':
856 attrs['DebugInformationFormat'] = 3 # debugOldSytleInfo TODO(???)
857 elif arg == '/Zd':
858 attrs['DebugInformationFormat'] = 0 # debugDisabled
859 elif arg == '/Zi':
860 attrs['DebugInformationFormat'] = 2 # debugEnabled TODO(???)
861 elif arg == '/ZI':
862 attrs['DebugInformationFormat'] = 1 # debugEditAndContinue TODO(???)
863
864 cppdefines = attrs['PreprocessorDefinitions']
865 if cppdefines:
866 attrs['PreprocessorDefinitions'] = ';'.join(cppdefines)
867 warnings = attrs['DisableSpecificWarnings']
868 if warnings:
869 warnings = SCons.Util.uniquer(warnings)
870 attrs['DisableSpecificWarnings'] = ';'.join(warnings)
871
872 return tool
873
874 def VCLibrarianTool(self, args):
875 default_attrs = {
876 'LinkTimeCodeGeneration' : "false",
877 'SuppressStartupBanner' : "false",
878 }
879
880 tool = MSVSTool('VCLibrarianTool', **default_attrs)
881 attrs = tool.attrs
882
883 for arg in args:
884 if arg.startswith('/OUT'):
885 continue
886 if arg == '/ltcg':
887 attrs['LinkTimeCodeGeneration'] = "true"
888 elif arg == '/nologo':
889 attrs['SuppressStartupBanner'] = "true"
890
891 return tool
892
893 def VCLinkerTool(self, args):
894 default_attrs = {
895 'LinkIncremental' : "false",
896 'LinkTimeCodeGeneration' : "false",
897 'EnableCOMDATFolding' : TODO,
898 'OptimizeForWindows98' : TODO,
899 'OptimizeReferences' : TODO,
900 'Profile' : "false",
901 'SuppressStartupBanner' : "false",
902 }
903
904 tool = MSVSTool('VCLinkerTool', **default_attrs)
905 attrs = tool.attrs
906
907 for arg in args:
908 if arg == '':
909 continue
910 if arg == '/INCREMENTAL':
911 attrs['LinkIncremental'] = "true"
912 elif arg == '/INCREMENTAL:NO':
913 attrs['LinkIncremental'] = "false"
914 elif arg == '/LTCG':
915 attrs['LinkTimeCodeGeneration'] = "true"
916 elif arg == '/nologo':
917 attrs['SuppressStartupBanner'] = "true"
918 elif arg == '/OPT:NOICF':
919 attrs['EnableCOMDATFolding'] = 2 #
920 elif arg == '/OPT:NOWIN98':
921 attrs['OptimizeForWindows98'] = 1 #
922 elif arg == '/OPT:REF':
923 attrs['OptimizeReferences'] = 2 #
924 elif arg == '/PROFILE':
925 attrs['Profile'] = "true"
926
927 return tool
928
929 command_to_tool_map = {
930 'cl' : 'VCCLCompilerTool',
931 'cl.exe' : 'VCCLCompilerTool',
932 'lib' : 'VCLibrarianTool',
933 'lib.exe' : 'VCLibrarianTool',
934 'link' : 'VCLinkerTool',
935 'link.exe' : 'VCLinkerTool',
936 }
937
938 def cl_to_tool(self, args):
939 command = os.path.basename(args[0])
940 method_name = self.command_to_tool_map.get(command)
941 if not method_name:
942 return None
943 return getattr(self, method_name)(args[1:])
944
945 def _AddFileConfigurationDifferences(self, target, source, base_env, file_env, name):
946 """Adds a per-file configuration. 688 """Adds a per-file configuration.
947 689
948 Args: 690 Args:
949 target: The target being built from the source. 691 target: The target being built from the source.
950 source: The source to which the file configuration is being added. 692 source: The source to which the file configuration is being added.
951 base_env: The base construction environment for the project. 693 base_env: The base construction environment for the project.
952 Differences from this will go into the FileConfiguration 694 Differences from this will go into the FileConfiguration
953 in the project file. 695 in the project file.
954 file_env: The construction environment for the target, containing 696 file_env: The construction environment for the target, containing
955 the per-target settings. 697 the per-target settings.
956 """ 698 """
957 executor = target.get_executor() 699 pass
958 base_cl = map(str, base_env.subst_list(executor)[0])
959 file_cl = map(str, file_env.subst_list(executor)[0])
960 if base_cl == file_cl:
961 return
962
963 base_tool = self.cl_to_tool(base_cl)
964 file_tool = self.cl_to_tool(file_cl)
965
966 file_tool.diff(base_tool)
967
968 self.AddFileConfig(source, name, tools=[file_tool])
969 700
970 def _AddFileConfigurations(self, env): 701 def _AddFileConfigurations(self, env):
971 """Adds per-file configurations for the buildtarget's sources. 702 """Adds per-file configurations for the buildtarget's sources.
972 703
973 Args: 704 Args:
974 env: The base construction environment for the project. 705 env: The base construction environment for the project.
975 """ 706 """
976 if not self.buildtargets: 707 if not self.buildtargets:
977 return 708 return
978 709
979 for bt in self.buildtargets: 710 bt = self.buildtargets[0]
980 executor = bt.get_executor() 711 additional_files = []
981 build_env = bt.get_build_env() 712 for t in bt.sources:
982 bt_cl = map(str, build_env.subst_list(executor)[0])
983 tool = self.cl_to_tool(bt_cl)
984 default_tool = self.cl_to_tool([bt_cl[0]])
985 if default_tool:
986 tool.diff(default_tool)
987 else:
988 print "no tool for %r" % bt_cl[0]
989 for t in bt.sources:
990 e = t.get_build_env() 713 e = t.get_build_env()
991 additional_files = SCons.Util.UniqueList()
992 for s in t.sources: 714 for s in t.sources:
993 s = env.arg2nodes([s])[0].srcnode() 715 s = env.arg2nodes([s])[0]
994 if not self.FindFile(s): 716 if not self.FindFile(s):
995 additional_files.append(s) 717 additional_files.append(s)
996 if not build_env is e: 718 if not env is e:
997 # TODO(sgk): This test may be bogus, but it works for now. 719 self._AddFileConfigurationDifferences(t, s, env, e)
998 # We're trying to figure out if the file configuration 720 self.AddFiles(additional_files)
999 # differences need to be added one per build target, or one
1000 # per configuration for the entire project. The assumption
1001 # is that if the number of buildtargets configured matches
1002 # the number of project configurations, that we use those
1003 # in preference to the project configurations.
1004 if len(self.buildtargets) == len(self.configurations):
1005 self._AddFileConfigurationDifferences(t, s, build_env, e, e.subst( '$MSVSCONFIGURATIONNAME'))
1006 else:
1007 for config in self.configurations:
1008 self._AddFileConfigurationDifferences(t, s, build_env, e, config .Name)
1009 self._MergeFiles(self.files, additional_files)
1010 721
1011 def Write(self, env): 722 def Write(self, env):
1012 """Writes the project file.""" 723 """Writes the project file."""
1013 for flist in self.file_lists:
1014 self._FilesToSourceFiles(flist)
1015 self._MergeFiles(self.files, flist)
1016 for k, v in self.file_configurations.items():
1017 self.file_configurations[str(k)] = v
1018 k = self.env.File(k).srcnode()
1019 self.file_configurations[k] = v
1020 self.file_configurations[str(k)] = v
1021 self._AddFileConfigurations(env) 724 self._AddFileConfigurations(env)
1022 725
1023 self.Create() 726 self.Create()
1024 727
1025 f = open(str(self), 'wt') 728 f = open(str(self.msvs_node), 'wt')
1026 f.write(self.formatMSVSProjectXML(self.doc)) 729 f.write(self.formatMSVSProjectXML(self.doc))
1027 f.close() 730 f.close()
1028 731
1029 # Methods for formatting XML as nearly identically to Microsoft's 732 # Methods for formatting XML as nearly identically to Microsoft's
1030 # .vcproj output as we can practically make it. 733 # .vcproj output as we can practically make it.
1031 # 734 #
1032 # The general design here is copied from: 735 # The general design here is copied from:
1033 # 736 #
1034 # Bruce Eckels' MindView, Inc: 12-09-04 XML Oddyssey 737 # Bruce Eckels' MindView, Inc: 12-09-04 XML Oddyssey
1035 # http://www.mindview.net/WebLog/log-0068 738 # http://www.mindview.net/WebLog/log-0068
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 'ConfigurationType', 782 'ConfigurationType',
1080 'InheritedPropertySheets', 783 'InheritedPropertySheets',
1081 ], 784 ],
1082 'FileConfiguration' : [ 785 'FileConfiguration' : [
1083 'Name', 786 'Name',
1084 'ExcludedFromBuild', 787 'ExcludedFromBuild',
1085 ], 788 ],
1086 'Tool' : [ 789 'Tool' : [
1087 'Name', 790 'Name',
1088 'DisableSpecificWarnings', 791 'DisableSpecificWarnings',
1089
1090 'PreprocessorDefinitions',
1091 'UsePrecompiledHeader',
1092 'PrecompiledHeaderThrough',
1093 'ForcedIncludeFiles',
1094 ], 792 ],
1095 'VisualStudioProject' : [ 793 'VisualStudioProject' : [
1096 'ProjectType', 794 'ProjectType',
1097 'Version', 795 'Version',
1098 'Name', 796 'Name',
1099 'ProjectGUID', 797 'ProjectGUID',
1100 'RootNamespace', 798 'RootNamespace',
1101 'Keyword', 799 'Keyword',
1102 ], 800 ],
1103 } 801 }
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
1357 if not SCons.Util.is_String(item): 1055 if not SCons.Util.is_String(item):
1358 return item 1056 return item
1359 item = env.subst(item) 1057 item = env.subst(item)
1360 result = env.fs._lookup(item, None, _MSVSSolution, create=1) 1058 result = env.fs._lookup(item, None, _MSVSSolution, create=1)
1361 result.initialize(env, item, *args, **kw) 1059 result.initialize(env, item, *args, **kw)
1362 LookupAdd(item, result) 1060 LookupAdd(item, result)
1363 return result 1061 return result
1364 1062
1365 import __builtin__ 1063 import __builtin__
1366 1064
1367 __builtin__.MSVSConfig = MSVSConfig
1368 __builtin__.MSVSFilter = MSVSFilter 1065 __builtin__.MSVSFilter = MSVSFilter
1369 __builtin__.MSVSProject = MSVSProject 1066 __builtin__.MSVSProject = MSVSProject
1370 __builtin__.MSVSSolution = MSVSSolution 1067 __builtin__.MSVSSolution = MSVSSolution
1371 __builtin__.MSVSTool = MSVSTool 1068 __builtin__.MSVSTool = MSVSTool
OLDNEW
« no previous file with comments | « net/tools/tld_cleanup/tld_cleanup.scons ('k') | site_scons/site_tools/chromium_builders.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698