OLD | NEW |
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 20 matching lines...) Expand all Loading... |
31 import md5 | 31 import md5 |
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 import SCons.Util |
41 | 42 |
42 from SCons.Debug import Trace | 43 from SCons.Debug import Trace |
43 TODO = 0 | 44 TODO = 0 |
44 | 45 |
45 # Initialize random number generator | 46 # Initialize random number generator |
46 random.seed() | 47 random.seed() |
47 | 48 |
48 | 49 |
49 #------------------------------------------------------------------------------ | 50 #------------------------------------------------------------------------------ |
50 # Entry point for supplying a fixed map of GUIDs for testing. | 51 # Entry point for supplying a fixed map of GUIDs for testing. |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 if not topdown: | 214 if not topdown: |
214 yield top, dirs, nondirs | 215 yield top, dirs, nondirs |
215 | 216 |
216 #------------------------------------------------------------------------------ | 217 #------------------------------------------------------------------------------ |
217 | 218 |
218 class _MSVSFolder(FileList): | 219 class _MSVSFolder(FileList): |
219 """Folder in a Visual Studio solution.""" | 220 """Folder in a Visual Studio solution.""" |
220 | 221 |
221 entry_type_guid = '{2150E333-8FDC-42A3-9474-1A3956D46DE8}' | 222 entry_type_guid = '{2150E333-8FDC-42A3-9474-1A3956D46DE8}' |
222 | 223 |
223 def initialize(self, path, name = None, entries = None, guid = None, items = N
one): | 224 def initialize(self, path, name=None, entries=None, guid=None, items=None): |
224 """Initializes the folder. | 225 """Initializes the folder. |
225 | 226 |
226 Args: | 227 Args: |
227 path: The unique name of the folder, by which other MSVS Nodes can | 228 path: The unique name of the folder, by which other MSVS Nodes can |
228 refer to it. This is not necessarily the name that gets printed | 229 refer to it. This is not necessarily the name that gets printed |
229 in the .sln file. | 230 in the .sln file. |
230 name: The name of this folder as actually written in a generated | 231 name: The name of this folder as actually written in a generated |
231 .sln file. The default is | 232 .sln file. The default is |
232 entries: List of folder entries to nest inside this folder. May contain | 233 entries: List of folder entries to nest inside this folder. May contain |
233 Folder or Project objects. May be None, if the folder is empty. | 234 Folder or Project objects. May be None, if the folder is empty. |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 class MSVSTool(object): | 379 class MSVSTool(object): |
379 """Visual Studio tool.""" | 380 """Visual Studio tool.""" |
380 | 381 |
381 def __init__(self, Name, **attrs): | 382 def __init__(self, Name, **attrs): |
382 """Initializes the tool. | 383 """Initializes the tool. |
383 | 384 |
384 Args: | 385 Args: |
385 Name: Tool name. | 386 Name: Tool name. |
386 **attrs: Tool attributes. | 387 **attrs: Tool attributes. |
387 """ | 388 """ |
| 389 |
| 390 val = attrs.get('AdditionalDependencies') |
| 391 if val: |
| 392 if isinstance(val, list): |
| 393 val = ' '.join(val) |
| 394 attrs['AdditionalDependencies'] = val.replace('/', '\\') |
| 395 |
| 396 val = attrs.get('AdditionalIncludeDirectories') |
| 397 if val: |
| 398 if isinstance(val, list): |
| 399 val = ';'.join(val) |
| 400 attrs['AdditionalIncludeDirectories'] = val.replace('/', '\\') |
| 401 |
| 402 val = attrs.get('AdditionalManifestFiles') |
| 403 if val: |
| 404 if isinstance(val, list): |
| 405 val = ';'.join(val) |
| 406 attrs['AdditionalManifestFiles'] = val.replace('/', '\\') |
| 407 |
| 408 val = attrs.get('CommandLine') |
| 409 if val: |
| 410 if isinstance(val, list): |
| 411 val = '\r\n'.join(val) |
| 412 attrs['CommandLine'] = val.replace('/', '\\') |
| 413 |
| 414 val = attrs.get('PreprocessorDefinitions') |
| 415 if val: |
| 416 if isinstance(val, list): |
| 417 val = ';'.join(val) |
| 418 attrs['PreprocessorDefinitions'] = val |
| 419 |
| 420 for a in ('ImportLibrary', |
| 421 'ObjectFile', |
| 422 'OutputFile', |
| 423 'Outputs', |
| 424 'XMLDocumentationFileName'): |
| 425 val = attrs.get(a) |
| 426 if val: |
| 427 val = val.replace('/', '\\') |
| 428 attrs[a] = val |
| 429 |
388 self.Name = Name | 430 self.Name = Name |
389 self.attrs = attrs | 431 self.attrs = attrs |
390 | 432 |
391 def CreateElement(self, doc): | 433 def CreateElement(self, doc): |
392 """Creates an element for the tool. | 434 """Creates an element for the tool. |
393 | 435 |
394 Args: | 436 Args: |
395 doc: xml.dom.Document object to use for node creation. | 437 doc: xml.dom.Document object to use for node creation. |
396 | 438 |
397 Returns: | 439 Returns: |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 | 488 |
447 entry_type_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' | 489 entry_type_guid = '{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}' |
448 initialized = False | 490 initialized = False |
449 | 491 |
450 def initialize(self, env, path, name = None, | 492 def initialize(self, env, path, name = None, |
451 dependencies = None, | 493 dependencies = None, |
452 guid = None, | 494 guid = None, |
453 buildtargets = [], | 495 buildtargets = [], |
454 files = [], | 496 files = [], |
455 root_namespace = None, | 497 root_namespace = None, |
456 relative_path_prefix = '', | 498 keyword = None, |
| 499 relative_path_prefix = None, |
| 500 local_directory_prefix = None, |
| 501 relative_path_substitutions = [], |
457 tools = None, | 502 tools = None, |
458 configurations = None, | 503 configurations = None, |
459 **attrs): | 504 **attrs): |
460 """Initializes the project. | 505 """Initializes the project. |
461 | 506 |
462 Args: | 507 Args: |
463 path: Relative path to project file. | 508 path: Relative path to project file. |
464 name: Name of project. If None, the name will be the same as the base | 509 name: Name of project. If None, the name will be the same as the base |
465 name of the project file. | 510 name of the project file. |
466 dependencies: List of other Project objects this project is dependent | 511 dependencies: List of other Project objects this project is dependent |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 # pass | 549 # pass |
505 else: | 550 else: |
506 self.buildtargets = [] | 551 self.buildtargets = [] |
507 self.configurations = [] | 552 self.configurations = [] |
508 self.dependencies = [] | 553 self.dependencies = [] |
509 self.file_configurations = {} | 554 self.file_configurations = {} |
510 self.files = MSVSFiles([]) | 555 self.files = MSVSFiles([]) |
511 self.tool_files = [] | 556 self.tool_files = [] |
512 self.file_lists = [] | 557 self.file_lists = [] |
513 self.initialized = True | 558 self.initialized = True |
| 559 self.keyword = None |
| 560 self.local_directory_prefix = '' |
| 561 self.relative_path_prefix = '' |
| 562 self.relative_path_substitutions = [] |
| 563 self.root_namespace = name |
514 | 564 |
515 self.attrs = attrs | 565 self.attrs = attrs |
516 self.env = env | 566 self.env = env |
517 self.guid = guid | 567 self.guid = guid |
518 self.msvs_name = name | 568 self.msvs_name = name |
519 self.msvs_path = path | 569 self.msvs_path = path |
520 self.relative_path_prefix = relative_path_prefix | 570 if relative_path_prefix: |
521 self.root_namespace = root_namespace or self.msvs_name | 571 self.relative_path_prefix = relative_path_prefix |
| 572 if local_directory_prefix: |
| 573 self.local_directory_prefix = local_directory_prefix |
| 574 for left, right in relative_path_substitutions: |
| 575 t = (left.replace('/', '\\'), right.replace('/', '\\')) |
| 576 self.relative_path_substitutions.append(t) |
| 577 if root_namespace: |
| 578 self.root_namespace = root_namespace |
| 579 if keyword: |
| 580 self.keyword = keyword |
522 self.tools = tools | 581 self.tools = tools |
523 | 582 |
524 self.buildtargets.extend(buildtargets) | 583 self.buildtargets.extend(buildtargets) |
525 self.configurations.extend(configurations or []) | 584 self.configurations.extend(configurations or []) |
526 self.dependencies.extend(list(dependencies or [])) | 585 self.dependencies.extend(list(dependencies or [])) |
527 self.AddFiles(files) | 586 self.AddFiles(files) |
528 | 587 |
529 env.Command(self, [], MSVSProjectAction) | 588 env.Command(self, [], MSVSProjectAction) |
530 | 589 |
531 def args2nodes(self, entries): | 590 def args2nodes(self, entries): |
532 result = [] | 591 result = [] |
533 for entry in entries: | 592 for entry in entries: |
534 if SCons.Util.is_String(entry): | 593 if SCons.Util.is_String(entry): |
535 entry = self.env.File(entry) | 594 entry = self.env.File(entry) |
536 result.append(entry) | 595 result.append(entry.srcnode()) |
537 elif hasattr(entry, 'entries'): | 596 elif hasattr(entry, 'entries'): |
538 entry.entries = self.args2nodes(entry.entries) | 597 entry.entries = self.args2nodes(entry.entries) |
539 result.append(entry) | 598 result.append(entry) |
540 elif isinstance(entry, (list, UserList.UserList)): | 599 elif isinstance(entry, (list, UserList.UserList)): |
541 result.extend(self.args2nodes(entry)) | 600 result.extend(self.args2nodes(entry)) |
542 elif hasattr(entry, 'sources') and entry.sources: | 601 elif hasattr(entry, 'sources') and entry.sources: |
543 result.extend(entry.sources) | 602 result.extend(entry.sources) |
544 else: | 603 else: |
545 result.append(entry.srcnode()) | 604 result.append(entry.srcnode()) |
546 return result | 605 return result |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 # 4. We should be able to handle pre-built project files by reading the | 646 # 4. We should be able to handle pre-built project files by reading the |
588 # GUID from the files. | 647 # GUID from the files. |
589 guid = MakeGuid(self.msvs_path) | 648 guid = MakeGuid(self.msvs_path) |
590 self.guid = guid | 649 self.guid = guid |
591 return self.guid | 650 return self.guid |
592 | 651 |
593 def get_msvs_path(self, sln): | 652 def get_msvs_path(self, sln): |
594 return sln.rel_path(self).replace('/', '\\') | 653 return sln.rel_path(self).replace('/', '\\') |
595 | 654 |
596 def get_rel_path(self, node): | 655 def get_rel_path(self, node): |
597 result = self.relative_path_prefix + self.rel_path(node) | 656 result = self.rel_path(node) |
598 return result.replace('/', '\\') | 657 if self.relative_path_prefix: |
| 658 if not result.startswith('..'): |
| 659 result = self.relative_path_prefix + result |
| 660 elif not os.path.split(result)[0]: |
| 661 result = self.local_directory_prefix + result |
| 662 result = result.replace('/', '\\') |
| 663 for left, right in self.relative_path_substitutions: |
| 664 result = result.replace(left, right) |
| 665 return result |
599 | 666 |
600 def AddConfig(self, Name, tools=None, **attrs): | 667 def AddConfig(self, Name, tools=None, **attrs): |
601 """Adds a configuration to the parent node. | 668 """Adds a configuration to the parent node. |
602 | 669 |
603 Args: | 670 Args: |
604 Name: The name of the configuration. | 671 Name: The name of the configuration. |
605 tools: List of tools (strings or Tool objects); may be None. | 672 tools: List of tools (strings or Tool objects); may be None. |
606 **attrs: Configuration attributes. | 673 **attrs: Configuration attributes. |
607 """ | 674 """ |
608 if tools is None: | 675 if tools is None: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 xml_impl = xml.dom.getDOMImplementation() | 770 xml_impl = xml.dom.getDOMImplementation() |
704 self.doc = xml_impl.createDocument(None, 'VisualStudioProject', None) | 771 self.doc = xml_impl.createDocument(None, 'VisualStudioProject', None) |
705 | 772 |
706 # Add attributes to root element | 773 # Add attributes to root element |
707 root = self.doc.documentElement | 774 root = self.doc.documentElement |
708 root.setAttribute('ProjectType', 'Visual C++') | 775 root.setAttribute('ProjectType', 'Visual C++') |
709 root.setAttribute('Version', '8.00') | 776 root.setAttribute('Version', '8.00') |
710 root.setAttribute('Name', self.msvs_name) | 777 root.setAttribute('Name', self.msvs_name) |
711 root.setAttribute('ProjectGUID', self.get_guid()) | 778 root.setAttribute('ProjectGUID', self.get_guid()) |
712 root.setAttribute('RootNamespace', self.root_namespace) | 779 root.setAttribute('RootNamespace', self.root_namespace) |
713 root.setAttribute('Keyword', 'Win32Proj') | 780 if self.keyword: |
| 781 root.setAttribute('Keyword', self.keyword) |
714 | 782 |
715 # Add platform list | 783 # Add platform list |
716 platforms = self.doc.createElement('Platforms') | 784 platforms = self.doc.createElement('Platforms') |
717 root.appendChild(platforms) | 785 root.appendChild(platforms) |
718 n = self.doc.createElement('Platform') | 786 n = self.doc.createElement('Platform') |
719 n.setAttribute('Name', 'Win32') | 787 n.setAttribute('Name', 'Win32') |
720 platforms.appendChild(n) | 788 platforms.appendChild(n) |
721 | 789 |
722 # Add tool files section | 790 # Add tool files section |
723 tool_files = self.doc.createElement('ToolFiles') | 791 tool_files = self.doc.createElement('ToolFiles') |
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1088 'InheritedPropertySheets', | 1156 'InheritedPropertySheets', |
1089 ], | 1157 ], |
1090 'FileConfiguration' : [ | 1158 'FileConfiguration' : [ |
1091 'Name', | 1159 'Name', |
1092 'ExcludedFromBuild', | 1160 'ExcludedFromBuild', |
1093 ], | 1161 ], |
1094 'Tool' : [ | 1162 'Tool' : [ |
1095 'Name', | 1163 'Name', |
1096 'DisableSpecificWarnings', | 1164 'DisableSpecificWarnings', |
1097 | 1165 |
| 1166 'AdditionalIncludeDirectories', |
| 1167 'Description', |
| 1168 'CommandLine', |
| 1169 'OutputFile', |
| 1170 'ImportLibrary', |
1098 'PreprocessorDefinitions', | 1171 'PreprocessorDefinitions', |
1099 'UsePrecompiledHeader', | 1172 'UsePrecompiledHeader', |
1100 'PrecompiledHeaderThrough', | 1173 'PrecompiledHeaderThrough', |
1101 'ForcedIncludeFiles', | 1174 'ForcedIncludeFiles', |
1102 ], | 1175 ], |
1103 'VisualStudioProject' : [ | 1176 'VisualStudioProject' : [ |
1104 'ProjectType', | 1177 'ProjectType', |
1105 'Version', | 1178 'Version', |
1106 'Name', | 1179 'Name', |
1107 'ProjectGUID', | 1180 'ProjectGUID', |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1171 return result | 1244 return result |
1172 | 1245 |
1173 #------------------------------------------------------------------------------ | 1246 #------------------------------------------------------------------------------ |
1174 | 1247 |
1175 MSVSSolutionAction = SCons.Script.Action(MSVSAction, | 1248 MSVSSolutionAction = SCons.Script.Action(MSVSAction, |
1176 "Generating Visual Studio solution `$TA
RGET' ...") | 1249 "Generating Visual Studio solution `$TA
RGET' ...") |
1177 | 1250 |
1178 class _MSVSSolution(SCons.Node.FS.File): | 1251 class _MSVSSolution(SCons.Node.FS.File): |
1179 """Visual Studio solution.""" | 1252 """Visual Studio solution.""" |
1180 | 1253 |
1181 def initialize(self, env, path, entries = None, variants = None, websiteProper
ties = True): | 1254 def initialize(self, env, path, entries=None, variants=None, websiteProperties
=True): |
1182 """Initializes the solution. | 1255 """Initializes the solution. |
1183 | 1256 |
1184 Args: | 1257 Args: |
1185 path: Path to solution file. | 1258 path: Path to solution file. |
1186 entries: List of entries in solution. May contain Folder or Project | 1259 entries: List of entries in solution. May contain Folder or Project |
1187 objects. May be None, if the folder is empty. | 1260 objects. May be None, if the folder is empty. |
1188 variants: List of build variant strings. If none, a default list will | 1261 variants: List of build variant strings. If none, a default list will |
1189 be used. | 1262 be used. |
1190 """ | 1263 """ |
1191 self.msvs_path = path | 1264 self.msvs_path = path |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1363 | 1436 |
1364 def MSVSSolution(env, item, *args, **kw): | 1437 def MSVSSolution(env, item, *args, **kw): |
1365 if not SCons.Util.is_String(item): | 1438 if not SCons.Util.is_String(item): |
1366 return item | 1439 return item |
1367 item = env.subst(item) | 1440 item = env.subst(item) |
1368 result = env.fs._lookup(item, None, _MSVSSolution, create=1) | 1441 result = env.fs._lookup(item, None, _MSVSSolution, create=1) |
1369 result.initialize(env, item, *args, **kw) | 1442 result.initialize(env, item, *args, **kw) |
1370 LookupAdd(item, result) | 1443 LookupAdd(item, result) |
1371 return result | 1444 return result |
1372 | 1445 |
| 1446 class Derived(SCons.Util.Proxy): |
| 1447 def srcnode(self, *args, **kw): |
| 1448 return self |
| 1449 def __getattr__(self, name): |
| 1450 if name == 'sources': |
| 1451 return [] |
| 1452 return SCons.Util.Proxy.__getattr__(self, name) |
| 1453 def __hash__(self, *args, **kw): |
| 1454 return id(self) |
| 1455 |
1373 import __builtin__ | 1456 import __builtin__ |
1374 | 1457 |
| 1458 __builtin__.Derived = Derived |
1375 __builtin__.MSVSConfig = MSVSConfig | 1459 __builtin__.MSVSConfig = MSVSConfig |
1376 __builtin__.MSVSFilter = MSVSFilter | 1460 __builtin__.MSVSFilter = MSVSFilter |
1377 __builtin__.MSVSProject = MSVSProject | 1461 __builtin__.MSVSProject = MSVSProject |
1378 __builtin__.MSVSSolution = MSVSSolution | 1462 __builtin__.MSVSSolution = MSVSSolution |
1379 __builtin__.MSVSTool = MSVSTool | 1463 __builtin__.MSVSTool = MSVSTool |
OLD | NEW |