3 # Copyright The SCons Foundation
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 A testing framework for the SCons software construction tool.
27 A TestSConsMSVS environment object is created via the usual invocation:
29 test = TestSConsMSVS()
31 TestSConsMSVS is a subsclass of TestSCons, which is in turn a subclass
32 of TestCommon, which is in turn is a subclass of TestCmd), and hence
33 has available all of the methods and attributes from those classes,
34 as well as any overridden or additional methods or attributes defined
42 from xml
.etree
import ElementTree
50 from TestSCons
import *
51 from TestSCons
import __all__
54 PROJECT_GUID
= "{00000000-0000-0000-0000-000000000000}"
55 PROJECT_GUID_1
= "{11111111-1111-1111-1111-111111111111}"
56 PROJECT_GUID_2
= "{22222222-2222-2222-2222-222222222222}"
58 SOLUTION_GUID_1
= "{88888888-8888-8888-8888-888888888888}"
59 SOLUTION_GUID_2
= "{99999999-9999-9999-9999-999999999999}"
61 expected_dspfile_6_0
= '''\
62 # Microsoft Developer Studio Project File - Name="Test" - Package Owner=<4>
63 # Microsoft Developer Studio Generated Build File, Format Version 6.00
66 # TARGTYPE "Win32 (x86) External Target" 0x0106
68 CFG=Test - Win32 Release
69 !MESSAGE This is not a valid makefile. To build this project using NMAKE,
70 !MESSAGE use the Export Makefile command and run
72 !MESSAGE NMAKE /f "Test.mak".
74 !MESSAGE You can specify a configuration when running NMAKE
75 !MESSAGE by defining the macro CFG on the command line. For example:
77 !MESSAGE NMAKE /f "Test.mak" CFG="Test - Win32 Release"
79 !MESSAGE Possible choices for configuration are:
81 !MESSAGE "Test - Win32 Release" (based on "Win32 (x86) External Target")
85 # PROP AllowPerConfigDependencies 0
86 # PROP Scc_ProjName ""
87 # PROP Scc_LocalPath ""
89 !IF "$(CFG)" == "Test - Win32 Release"
92 # PROP BASE Use_Debug_Libraries 0
93 # PROP BASE Output_Dir ""
94 # PROP BASE Intermediate_Dir ""
95 # PROP BASE Cmd_Line "echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
96 # PROP BASE Rebuild_Opt "-c && echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
97 # PROP BASE Target_File "Test.exe"
98 # PROP BASE Bsc_Name ""
99 # PROP BASE Target_Dir ""
101 # PROP Use_Debug_Libraries 0
103 # PROP Intermediate_Dir ""
104 # PROP Cmd_Line "echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
105 # PROP Rebuild_Opt "-c && echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN>" -C "<WORKPATH>" -f SConstruct "Test.exe""
106 # PROP Target_File "Test.exe"
114 # Name "Test - Win32 Release"
116 !IF "$(CFG)" == "Test - Win32 Release"
120 # Begin Group "Header Files"
122 # PROP Default_Filter "h;hpp;hxx;hm;inl"
128 # Begin Group "Local Headers"
130 # PROP Default_Filter "h;hpp;hxx;hm;inl"
136 # Begin Group "Other Files"
138 # PROP Default_Filter ""
144 # Begin Group "Resource Files"
146 # PROP Default_Filter "r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
152 # Begin Group "Source Files"
154 # PROP Default_Filter "cpp;c;cxx;l;y;def;odl;idl;hpj;bat"
162 SOURCE="<SCONSCRIPT>"
168 expected_dswfile_6_0
= '''\
169 Microsoft Developer Studio Workspace File, Format Version 6.00
170 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
172 ###############################################################################
174 Project: "Test"="Test.dsp" - Package Owner=<4>
184 ###############################################################################
196 ###############################################################################
199 SConscript_contents_6_0
= """\
200 env=Environment(tools=['msvs'],
202 HOST_ARCH='%(HOST_ARCH)s')
206 testlocalincs = ['test.h']
207 testresources = ['test.rc']
208 testmisc = ['readme.txt']
210 env.MSVSProject(target = 'Test.dsp',
213 localincs = testlocalincs,
214 resources = testresources,
216 buildtarget = 'Test.exe',
221 expected_slnfile_7_0
= """\
222 Microsoft Visual Studio Solution File, Format Version 7.00
223 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test.vcproj", "<PROJECT_GUID>"
227 \tGlobalSection(SolutionConfiguration) = preSolution
228 \t\tConfigName.0 = Release
230 \tGlobalSection(ProjectDependencies) = postSolution
232 \tGlobalSection(ProjectConfiguration) = postSolution
233 \t\t<PROJECT_GUID>.Release.ActiveCfg = Release|Win32
234 \t\t<PROJECT_GUID>.Release.Build.0 = Release|Win32
236 \tGlobalSection(ExtensibilityGlobals) = postSolution
238 \tGlobalSection(ExtensibilityAddIns) = postSolution
243 expected_vcprojfile_7_0
= """\
244 <?xml version="1.0" encoding="Windows-1252"?>
246 \tProjectType="Visual C++"
249 \tProjectGUID="<PROJECT_GUID>"
251 \tKeyword="MakeFileProj">
258 \t\t\tName="Release|Win32"
259 \t\t\tOutputDirectory=""
260 \t\t\tIntermediateDirectory=""
261 \t\t\tConfigurationType="0"
263 \t\t\tATLMinimizesCRunTimeLibraryUsage="FALSE">
265 \t\t\t\tName="VCNMakeTool"
266 \t\t\t\tBuildCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "Test.exe""
267 \t\t\t\tReBuildCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "Test.exe""
268 \t\t\t\tCleanCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct -c "Test.exe""
269 \t\t\t\tOutput="Test.exe"/>
274 \t\t\tName="Header Files"
275 \t\t\tFilter="h;hpp;hxx;hm;inl">
277 \t\t\t\tRelativePath="sdk.h">
281 \t\t\tName="Local Headers"
282 \t\t\tFilter="h;hpp;hxx;hm;inl">
284 \t\t\t\tRelativePath="test.h">
288 \t\t\tName="Other Files"
291 \t\t\t\tRelativePath="readme.txt">
295 \t\t\tName="Resource Files"
296 \t\t\tFilter="r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
298 \t\t\t\tRelativePath="test.rc">
302 \t\t\tName="Source Files"
303 \t\t\tFilter="cpp;c;cxx;l;y;def;odl;idl;hpj;bat">
305 \t\t\t\tRelativePath="test1.cpp">
308 \t\t\t\tRelativePath="test2.cpp">
312 \t\t\tRelativePath="<SCONSCRIPT>">
317 </VisualStudioProject>
320 SConscript_contents_7_0
= """\
321 env=Environment(tools=['msvs'],
323 HOST_ARCH='%(HOST_ARCH)s')
325 testsrc = ['test1.cpp', 'test2.cpp']
327 testlocalincs = ['test.h']
328 testresources = ['test.rc']
329 testmisc = ['readme.txt']
331 env.MSVSProject(target = 'Test.vcproj',
332 MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
333 slnguid = '{SLNGUID}',
336 localincs = testlocalincs,
337 resources = testresources,
339 buildtarget = 'Test.exe',
344 expected_slnfile_7_1
= """\
345 Microsoft Visual Studio Solution File, Format Version 8.00
346 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test.vcproj", "<PROJECT_GUID>"
347 \tProjectSection(ProjectDependencies) = postProject
352 \tGlobalSection(SolutionConfiguration) = preSolution
353 \t\tConfigName.0 = Release
355 \tGlobalSection(ProjectDependencies) = postSolution
357 \tGlobalSection(ProjectConfiguration) = postSolution
358 \t\t<PROJECT_GUID>.Release.ActiveCfg = Release|Win32
359 \t\t<PROJECT_GUID>.Release.Build.0 = Release|Win32
361 \tGlobalSection(ExtensibilityGlobals) = postSolution
363 \tGlobalSection(ExtensibilityAddIns) = postSolution
368 expected_vcprojfile_7_1
= """\
369 <?xml version="1.0" encoding="Windows-1252"?>
371 \tProjectType="Visual C++"
374 \tProjectGUID="<PROJECT_GUID>"
376 \tKeyword="MakeFileProj">
383 \t\t\tName="Release|Win32"
384 \t\t\tOutputDirectory=""
385 \t\t\tIntermediateDirectory=""
386 \t\t\tConfigurationType="0"
388 \t\t\tATLMinimizesCRunTimeLibraryUsage="FALSE">
390 \t\t\t\tName="VCNMakeTool"
391 \t\t\t\tBuildCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "Test.exe""
392 \t\t\t\tReBuildCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "Test.exe""
393 \t\t\t\tCleanCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct -c "Test.exe""
394 \t\t\t\tOutput="Test.exe"/>
401 \t\t\tName="Header Files"
402 \t\t\tFilter="h;hpp;hxx;hm;inl">
404 \t\t\t\tRelativePath="sdk.h">
408 \t\t\tName="Local Headers"
409 \t\t\tFilter="h;hpp;hxx;hm;inl">
411 \t\t\t\tRelativePath="test.h">
415 \t\t\tName="Other Files"
418 \t\t\t\tRelativePath="readme.txt">
422 \t\t\tName="Resource Files"
423 \t\t\tFilter="r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
425 \t\t\t\tRelativePath="test.rc">
429 \t\t\tName="Source Files"
430 \t\t\tFilter="cpp;c;cxx;l;y;def;odl;idl;hpj;bat">
432 \t\t\t\tRelativePath="test1.cpp">
435 \t\t\t\tRelativePath="test2.cpp">
439 \t\t\tRelativePath="<SCONSCRIPT>">
444 </VisualStudioProject>
447 SConscript_contents_7_1
= """\
448 env=Environment(tools=['msvs'],
450 HOST_ARCH='%(HOST_ARCH)s')
452 testsrc = ['test1.cpp', 'test2.cpp']
454 testlocalincs = ['test.h']
455 testresources = ['test.rc']
456 testmisc = ['readme.txt']
458 env.MSVSProject(target = 'Test.vcproj',
459 MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
460 slnguid = '{SLNGUID}',
463 localincs = testlocalincs,
464 resources = testresources,
466 buildtarget = 'Test.exe',
471 expected_slnfile_fmt
= """\
472 Microsoft Visual Studio Solution File, Format Version %(FORMAT_VERSION)s
473 # Visual Studio %(VS_NUMBER)s
474 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME)s", "%(PROJECT_FILE)s", "<PROJECT_GUID>"
478 \tGlobalSection(SolutionConfigurationPlatforms) = preSolution
479 \t\tRelease|Win32 = Release|Win32
481 \tGlobalSection(ProjectConfigurationPlatforms) = postSolution
482 \t\t<PROJECT_GUID>.Release|Win32.ActiveCfg = Release|Win32
483 \t\t<PROJECT_GUID>.Release|Win32.Build.0 = Release|Win32
485 \tGlobalSection(SolutionProperties) = preSolution
486 \t\tHideSolutionNode = FALSE
491 expected_vcprojfile_fmt
= """\
492 <?xml version="1.0" encoding="Windows-1252"?>
494 \tProjectType="Visual C++"
495 \tVersion="%(TOOLS_VERSION)s"
496 \tName="%(PROJECT_BASENAME)s"
497 \tProjectGUID="<PROJECT_GUID>"
498 \tRootNamespace="%(PROJECT_BASENAME)s"
500 \tKeyword="MakeFileProj">
509 \t\t\tName="Release|Win32"
510 \t\t\tConfigurationType="0"
512 \t\t\tATLMinimizesCRunTimeLibraryUsage="false"
515 \t\t\t\tName="VCNMakeTool"
516 \t\t\t\tBuildCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "%(PROJECT_BASENAME)s.exe""
517 \t\t\t\tReBuildCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "%(PROJECT_BASENAME)s.exe""
518 \t\t\t\tCleanCommandLine="echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct -c "%(PROJECT_BASENAME)s.exe""
519 \t\t\t\tOutput="%(PROJECT_BASENAME)s.exe"
520 \t\t\t\tPreprocessorDefinitions="DEF1;DEF2;DEF3=1234"
521 \t\t\t\tIncludeSearchPath="%(INCLUDE_DIRS)s"
522 \t\t\t\tForcedIncludes=""
523 \t\t\t\tAssemblySearchPath=""
524 \t\t\t\tForcedUsingAssemblies=""
525 \t\t\t\tCompileAsManaged=""
533 \t\t\tName="Header Files"
534 \t\t\tFilter="h;hpp;hxx;hm;inl">
536 \t\t\t\tRelativePath="sdk_dir\\sdk.h">
540 \t\t\tName="Local Headers"
541 \t\t\tFilter="h;hpp;hxx;hm;inl">
543 \t\t\t\tRelativePath="test.h">
547 \t\t\tName="Other Files"
550 \t\t\t\tRelativePath="readme.txt">
554 \t\t\tName="Resource Files"
555 \t\t\tFilter="r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
557 \t\t\t\tRelativePath="test.rc">
561 \t\t\tName="Source Files"
562 \t\t\tFilter="cpp;c;cxx;l;y;def;odl;idl;hpj;bat">
564 \t\t\t\tRelativePath="test1.cpp">
567 \t\t\t\tRelativePath="test2.cpp">
571 \t\t\tRelativePath="<SCONSCRIPT>">
576 </VisualStudioProject>
579 expected_vcxprojfile_fmt
= """\
580 <?xml version="1.0" encoding="utf-8"?>
581 <Project DefaultTargets="Build" ToolsVersion="%(TOOLS_VERSION)s" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
582 \t<ItemGroup Label="ProjectConfigurations">
583 \t\t<ProjectConfiguration Include="Release|Win32">
584 \t\t\t<Configuration>Release</Configuration>
585 \t\t\t<Platform>Win32</Platform>
586 \t\t</ProjectConfiguration>
588 \t<PropertyGroup Label="Globals">
589 \t\t<ProjectGuid>%(PROJECT_GUID)s</ProjectGuid>
591 \t\t<RootNamespace>%(PROJECT_BASENAME)s</RootNamespace>
592 \t\t<Keyword>MakeFileProj</Keyword>
593 \t\t<VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
595 \t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
596 \t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
597 \t\t<ConfigurationType>Makefile</ConfigurationType>
598 \t\t<UseOfMfc>false</UseOfMfc>
599 \t\t<PlatformToolset>%(PLATFORM_TOOLSET)s</PlatformToolset>
601 \t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
602 \t<ImportGroup Label="ExtensionSettings">
604 \t<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
605 \t\t<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
607 \t<PropertyGroup Label="UserMacros" />
609 \t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
610 \t\t<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "%(PROJECT_BASENAME)s.exe"</NMakeBuildCommandLine>
611 \t\t<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct "%(PROJECT_BASENAME)s.exe"</NMakeReBuildCommandLine>
612 \t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons && "<PYTHON>" -c "<SCONS_SCRIPT_MAIN_XML>" -C "<WORKPATH>" -f SConstruct -c "%(PROJECT_BASENAME)s.exe"</NMakeCleanCommandLine>
613 \t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PROJECT_BASENAME)s.exe</NMakeOutput>
614 \t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">DEF1;DEF2;DEF3=1234</NMakePreprocessorDefinitions>
615 \t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(INCLUDE_DIRS)s</NMakeIncludeSearchPath>
616 \t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
617 \t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
618 \t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
619 \t\t<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"></AdditionalOptions>
622 \t\t<ClInclude Include="sdk_dir\\sdk.h" />
625 \t\t<ClInclude Include="test.h" />
628 \t\t<None Include="readme.txt" />
631 \t\t<None Include="test.rc" />
634 \t\t<ClCompile Include="test1.cpp" />
635 \t\t<ClCompile Include="test2.cpp" />
638 \t\t<None Include="SConstruct" />
640 \t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
641 \t<ImportGroup Label="ExtensionTargets">
646 SConscript_contents_fmt
= """\
647 env=Environment(tools=['msvs'],
648 MSVS_VERSION='%(MSVS_VERSION)s',
649 CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
650 CPPPATH=['inc1', 'inc2'],
651 HOST_ARCH='%(HOST_ARCH)s')
653 testsrc = ['test1.cpp', 'test2.cpp']
654 testincs = [r'sdk_dir\\sdk.h']
655 testlocalincs = ['test.h']
656 testresources = ['test.rc']
657 testmisc = ['readme.txt']
659 env.MSVSProject(target = '%(PROJECT_FILE)s',
660 MSVS_PROJECT_GUID = '%(PROJECT_GUID)s',
661 slnguid = '{SLNGUID}',
664 localincs = testlocalincs,
665 resources = testresources,
667 buildtarget = 'Test.exe',
671 expected_projects_slnfile_fmt
= """\
672 Microsoft Visual Studio Solution File, Format Version %(FORMAT_VERSION)s
673 # Visual Studio %(VS_NUMBER)s
674 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_1)s", "%(PROJECT_FILE_1)s", "<PROJECT_GUID_1>"
676 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_2)s", "%(PROJECT_FILE_2)s", "<PROJECT_GUID_2>"
680 \tGlobalSection(SolutionConfigurationPlatforms) = preSolution
681 \t\tRelease|Win32 = Release|Win32
683 \tGlobalSection(ProjectConfigurationPlatforms) = postSolution
684 \t\t<PROJECT_GUID_1>.Release|Win32.ActiveCfg = Release|Win32
685 \t\t<PROJECT_GUID_1>.Release|Win32.Build.0 = Release|Win32
686 \t\t<PROJECT_GUID_2>.Release|Win32.ActiveCfg = Release|Win32
687 \t\t<PROJECT_GUID_2>.Release|Win32.Build.0 = Release|Win32
689 \tGlobalSection(SolutionProperties) = preSolution
690 \t\tHideSolutionNode = FALSE
695 expected_projects_slnfile_fmt_slnnodes
= """\
696 Microsoft Visual Studio Solution File, Format Version %(FORMAT_VERSION)s
697 # Visual Studio %(VS_NUMBER)s
698 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_1)s", "%(PROJECT_FILE_1)s", "<PROJECT_GUID_1>"
700 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(SOLUTION_FILE_1)s", "%(SOLUTION_FILE_1)s", "<SOLUTION_GUID_1>"
702 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME_2)s", "%(PROJECT_FILE_2)s", "<PROJECT_GUID_2>"
704 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(SOLUTION_FILE_2)s", "%(SOLUTION_FILE_2)s", "<SOLUTION_GUID_2>"
708 \tGlobalSection(SolutionConfigurationPlatforms) = preSolution
709 \t\tRelease|Win32 = Release|Win32
711 \tGlobalSection(ProjectConfigurationPlatforms) = postSolution
712 \t\t<PROJECT_GUID_1>.Release|Win32.ActiveCfg = Release|Win32
713 \t\t<PROJECT_GUID_1>.Release|Win32.Build.0 = Release|Win32
714 \t\t<SOLUTION_GUID_1>.Release|Win32.ActiveCfg = Release|Win32
715 \t\t<SOLUTION_GUID_1>.Release|Win32.Build.0 = Release|Win32
716 \t\t<PROJECT_GUID_2>.Release|Win32.ActiveCfg = Release|Win32
717 \t\t<PROJECT_GUID_2>.Release|Win32.Build.0 = Release|Win32
718 \t\t<SOLUTION_GUID_2>.Release|Win32.ActiveCfg = Release|Win32
719 \t\t<SOLUTION_GUID_2>.Release|Win32.Build.0 = Release|Win32
721 \tGlobalSection(SolutionProperties) = preSolution
722 \t\tHideSolutionNode = FALSE
727 SConscript_projects_contents_fmt
= """\
730 MSVS_VERSION='%(MSVS_VERSION)s',
731 CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
732 CPPPATH=['inc1', 'inc2'],
733 HOST_ARCH='%(HOST_ARCH)s',
736 testsrc = ['test1.cpp', 'test2.cpp']
737 testincs = [r'sdk_dir\\sdk.h']
738 testlocalincs = ['test.h']
739 testresources = ['test.rc']
740 testmisc = ['readme.txt']
742 p1 = env.MSVSProject(
743 target = '%(PROJECT_FILE_1)s',
744 MSVS_PROJECT_GUID = '%(PROJECT_GUID_1)s',
745 slnguid = '{SLNGUID}',
748 localincs = testlocalincs,
749 resources = testresources,
751 buildtarget = 'Test_1.exe',
753 auto_build_solution = %(AUTOBUILD_SOLUTION)s,
756 p2 = env.MSVSProject(
757 target = '%(PROJECT_FILE_2)s',
758 MSVS_PROJECT_GUID = '%(PROJECT_GUID_2)s',
759 slnguid = '{SLNGUID}',
762 localincs = testlocalincs,
763 resources = testresources,
765 buildtarget = 'Test_2.exe',
767 auto_build_solution = %(AUTOBUILD_SOLUTION)s,
771 target = '%(SOLUTION_FILE)s',
774 auto_filter_projects = %(AUTOFILTER_PROJECTS)s,
778 SConscript_projects_defaultguids_contents_fmt
= """\
781 MSVS_VERSION='%(MSVS_VERSION)s',
782 CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
783 CPPPATH=['inc1', 'inc2'],
784 HOST_ARCH='%(HOST_ARCH)s',
787 testsrc = ['test1.cpp', 'test2.cpp']
788 testincs = [r'sdk_dir\\sdk.h']
789 testlocalincs = ['test.h']
790 testresources = ['test.rc']
791 testmisc = ['readme.txt']
793 p1 = env.MSVSProject(
794 target = '%(PROJECT_FILE_1)s',
795 slnguid = '{SLNGUID}',
798 localincs = testlocalincs,
799 resources = testresources,
801 buildtarget = 'Test_1.exe',
803 auto_build_solution = %(AUTOBUILD_SOLUTION)s,
806 p2 = env.MSVSProject(
807 target = '%(PROJECT_FILE_2)s',
808 slnguid = '{SLNGUID}',
811 localincs = testlocalincs,
812 resources = testresources,
814 buildtarget = 'Test_2.exe',
816 auto_build_solution = %(AUTOBUILD_SOLUTION)s,
820 target = '%(SOLUTION_FILE)s',
823 auto_filter_projects = %(AUTOFILTER_PROJECTS)s,
828 def get_tested_proj_file_vc_versions():
830 Returns all MSVC versions that we want to test project file creation for.
832 return ['8.0', '9.0', '10.0', '11.0', '12.0', '14.0', '14.1', '14.2', '14.3']
835 class TestSConsMSVS(TestSCons
):
836 """Subclass for testing MSVS-specific portions of SCons."""
838 def msvs_versions(self
):
839 if not hasattr(self
, '_msvs_versions'):
840 # Determine the SCons version and the versions of the MSVS
841 # environments installed on the test machine.
843 # We do this by executing SCons with an SConstruct file
844 # (piped on stdin) that spits out Python assignments that
845 # we can just exec(). We construct the SCons.__"version"__
846 # string in the input here so that the SCons build itself
847 # doesn't fill it in when packaging SCons.
851 import SCons.Tool.MSCommon
852 print("self.scons_version =%%s"%%repr(SCons.__%s__))
853 print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions(env=None)))
858 self
.run(arguments
='-n -q -Q -f -', stdin
=input)
861 return self
._msvs
_versions
863 def vcproj_sys_path(self
, fname
) -> None:
865 orig
= 'sys.path = [ join(sys'
867 enginepath
= repr(os
.path
.join(self
._cwd
, '..', 'engine'))
868 replace
= f
'sys.path = [ {enginepath}, join(sys'
870 contents
= self
.read(fname
, mode
='r')
871 contents
= contents
.replace(orig
, replace
)
872 self
.write(fname
, contents
)
882 vcproj_sccinfo
: str = '',
883 sln_sccinfo
: str = '',
885 if not hasattr(self
, '_msvs_versions'):
889 workpath
= self
.workpath(subdir
)
891 workpath
= self
.workpath()
893 if sconscript
is None:
894 sconscript
= self
.workpath('SConstruct')
897 python
= sys
.executable
899 if project_guid
is None:
900 project_guid
= PROJECT_GUID
902 if 'SCONS_LIB_DIR' in os
.environ
:
903 exec_script_main
= f
"from os.path import join; import sys; sys.path = [ r'{os.environ['SCONS_LIB_DIR']}' ] + sys.path; import SCons.Script; SCons.Script.main()"
905 exec_script_main
= f
"from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-{self.scons_version}'), join(sys.prefix, 'scons-{self.scons_version}'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()"
906 exec_script_main_xml
= exec_script_main
.replace("'", "'")
908 result
= input.replace(r
'<WORKPATH>', workpath
)
909 result
= result
.replace(r
'<PYTHON>', python
)
910 result
= result
.replace(r
'<SCONSCRIPT>', sconscript
)
911 result
= result
.replace(r
'<SCONS_SCRIPT_MAIN>', exec_script_main
)
912 result
= result
.replace(r
'<SCONS_SCRIPT_MAIN_XML>', exec_script_main_xml
)
913 result
= result
.replace(r
'<PROJECT_GUID>', project_guid
)
914 result
= result
.replace('<SCC_VCPROJ_INFO>\n', vcproj_sccinfo
)
915 result
= result
.replace('<SCC_SLN_INFO>\n', sln_sccinfo
)
918 def get_msvs_executable(self
, version
, env
=None):
919 """Returns a full path to the executable (MSDEV or devenv)
920 for the specified version of Visual Studio.
922 from SCons
.Tool
.MSCommon
import get_vs_by_version
924 msvs
= get_vs_by_version(version
, env
)
927 return msvs
.get_executable()
929 def run(self
, *args
, **kw
):
931 Suppress MSVS deprecation warnings.
933 save_sconsflags
= os
.environ
.get('SCONSFLAGS')
935 sconsflags
= [save_sconsflags
]
938 sconsflags
= sconsflags
+ ['--warn=no-deprecated']
939 os
.environ
['SCONSFLAGS'] = ' '.join(sconsflags
)
941 result
= TestSCons
.run(self
, *args
, **kw
)
943 os
.environ
['SCONSFLAGS'] = save_sconsflags
or ''
946 def get_vs_host_arch(self
):
947 """Returns an MSVS, SDK, and/or MSVS acceptable platform arch."""
949 # Dict to 'canonicalize' the arch (synchronize with MSCommon\vc.py)
950 _ARCH_TO_CANONICAL
= {
957 "ia64": "ia64", # deprecated
958 "itanium": "ia64", # deprecated
970 winkey
= winreg
.OpenKeyEx(
971 winreg
.HKEY_LOCAL_MACHINE
,
972 r
'SYSTEM\CurrentControlSet\Control\Session Manager\Environment',
974 host_platform
, _
= winreg
.QueryValueEx(winkey
, 'PROCESSOR_ARCHITECTURE')
978 if not host_platform
:
979 host_platform
= platform
.machine()
982 host
= _ARCH_TO_CANONICAL
[host_platform
.lower()]
983 except KeyError as e
:
984 # Default to x86 for all other platforms
989 def validate_msvs_file(self
, file) -> None:
991 x
= ElementTree
.parse(file)
993 print("--------------------------------------------------------------")
994 print("--------------------------------------------------------------")
995 print(traceback
.format_exc())
996 print("Failed to validate xml in MSVS file: ")
998 print("--------------------------------------------------------------")
999 print("--------------------------------------------------------------")
1002 def parse_vc_version(self
, vc_version
):
1004 Parses the string vc_version to determine the major and minor version
1007 components
= vc_version
.split('.')
1008 major
= int(components
[0])
1009 minor
= 0 if len(components
) < 2 else int(components
[1])
1012 def _get_solution_file_format_version(self
, vc_version
) -> str:
1014 Returns the Visual Studio format version expected in the .sln file.
1016 major
, _
= self
.parse_vc_version(vc_version
)
1026 raise SCons
.Errors
.UserError(f
'Received unexpected VC version {vc_version}')
1028 def _get_solution_file_vs_number(self
, vc_version
) -> str:
1030 Returns the Visual Studio number expected in the .sln file.
1032 major
, minor
= self
.parse_vc_version(vc_version
)
1043 elif major
== 14 and (minor
== 0 or minor
== 1):
1044 # Visual Studio 2015 and 2017 both use 15 in this entry.
1046 elif major
== 14 and minor
== 2:
1048 elif major
== 14 and minor
== 3:
1051 raise SCons
.Errors
.UserError(f
'Received unexpected VC version {vc_version}')
1053 def _get_vcxproj_file_tools_version(self
, vc_version
) -> str:
1055 Returns the version entry expected in the project file.
1056 For .vcxproj files, this goes is ToolsVersion.
1057 For .vcproj files, this goes in Version.
1059 major
, minor
= self
.parse_vc_version(vc_version
)
1067 # ToolsVersion='4.0'
1069 elif major
== 14 and minor
== 0:
1070 # ToolsVersion='14.0'
1072 elif major
== 14 and minor
== 1:
1073 # ToolsVersion='15.0'
1075 elif vc_version
== '14.2':
1078 elif vc_version
== '14.3':
1082 raise SCons
.Errors
.UserError(f
'Received unexpected VC version {vc_version}')
1084 def _get_vcxproj_file_platform_toolset(self
, vc_version
) -> str:
1086 Returns the version entry expected in the project file.
1087 For .vcxproj files, this goes is PlatformToolset.
1088 For .vcproj files, not applicable.
1090 major
, minor
= self
.parse_vc_version(vc_version
)
1091 return f
"v{major}{minor}"
1093 def _get_vcxproj_file_cpp_path(self
, dirs
):
1094 """Returns the include paths expected in the .vcxproj file"""
1095 return ';'.join([self
.workpath(dir) for dir in dirs
])
1097 def get_expected_sln_file_contents(self
, vc_version
, project_file
):
1099 Returns the expected .sln file contents.
1100 Currently this function only supports the newer VC versions that use
1101 the .vcxproj file format.
1103 return expected_slnfile_fmt
% {
1104 'FORMAT_VERSION': self
._get
_solution
_file
_format
_version
(vc_version
),
1105 'VS_NUMBER': self
._get
_solution
_file
_vs
_number
(vc_version
),
1106 'PROJECT_NAME': project_file
.split('.')[0],
1107 'PROJECT_FILE': project_file
,
1110 def get_expected_proj_file_contents(self
, vc_version
, dirs
, project_file
):
1111 """Returns the expected .vcxproj file contents"""
1112 if project_file
.endswith('.vcxproj'):
1113 fmt
= expected_vcxprojfile_fmt
1115 fmt
= expected_vcprojfile_fmt
1116 project_filename
= os
.path
.split(project_file
)[-1]
1117 project_basename
= os
.path
.splitext(project_filename
)[0]
1119 'PROJECT_BASENAME': project_basename
,
1120 'PROJECT_GUID': PROJECT_GUID
,
1121 'TOOLS_VERSION': self
._get
_vcxproj
_file
_tools
_version
(vc_version
),
1122 'INCLUDE_DIRS': self
._get
_vcxproj
_file
_cpp
_path
(dirs
),
1123 'PLATFORM_TOOLSET': self
._get
_vcxproj
_file
_platform
_toolset
(vc_version
),
1126 def get_expected_sconscript_file_contents(self
, vc_version
, project_file
):
1127 return SConscript_contents_fmt
% {
1128 'HOST_ARCH': self
.get_vs_host_arch(),
1129 'MSVS_VERSION': vc_version
,
1130 'PROJECT_GUID': PROJECT_GUID
,
1131 'PROJECT_FILE': project_file
,
1134 def msvs_substitute_projects(
1141 project_guid_1
=None,
1142 project_guid_2
=None,
1143 solution_guid_1
=None,
1144 solution_guid_2
=None,
1145 vcproj_sccinfo
: str = '',
1146 sln_sccinfo
: str = '',
1148 if not hasattr(self
, '_msvs_versions'):
1149 self
.msvs_versions()
1152 workpath
= self
.workpath(subdir
)
1154 workpath
= self
.workpath()
1156 if sconscript
is None:
1157 sconscript
= self
.workpath('SConstruct')
1160 python
= sys
.executable
1162 if project_guid_1
is None:
1163 project_guid_1
= PROJECT_GUID_1
1165 if project_guid_2
is None:
1166 project_guid_2
= PROJECT_GUID_2
1168 if solution_guid_1
is None:
1169 solution_guid_1
= SOLUTION_GUID_1
1171 if solution_guid_2
is None:
1172 solution_guid_2
= SOLUTION_GUID_2
1174 if 'SCONS_LIB_DIR' in os
.environ
:
1175 exec_script_main
= f
"from os.path import join; import sys; sys.path = [ r'{os.environ['SCONS_LIB_DIR']}' ] + sys.path; import SCons.Script; SCons.Script.main()"
1177 exec_script_main
= f
"from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-{self.scons_version}'), join(sys.prefix, 'scons-{self.scons_version}'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()"
1178 exec_script_main_xml
= exec_script_main
.replace("'", "'")
1180 result
= input.replace(r
'<WORKPATH>', workpath
)
1181 result
= result
.replace(r
'<PYTHON>', python
)
1182 result
= result
.replace(r
'<SCONSCRIPT>', sconscript
)
1183 result
= result
.replace(r
'<SCONS_SCRIPT_MAIN>', exec_script_main
)
1184 result
= result
.replace(r
'<SCONS_SCRIPT_MAIN_XML>', exec_script_main_xml
)
1185 result
= result
.replace(r
'<PROJECT_GUID_1>', project_guid_1
)
1186 result
= result
.replace(r
'<PROJECT_GUID_2>', project_guid_2
)
1187 result
= result
.replace(r
'<SOLUTION_GUID_1>', solution_guid_1
)
1188 result
= result
.replace(r
'<SOLUTION_GUID_2>', solution_guid_2
)
1189 result
= result
.replace('<SCC_VCPROJ_INFO>\n', vcproj_sccinfo
)
1190 result
= result
.replace('<SCC_SLN_INFO>\n', sln_sccinfo
)
1193 def get_expected_projects_proj_file_contents(
1194 self
, vc_version
, dirs
, project_file
, project_guid
1196 """Returns the expected .vcxproj file contents"""
1197 if project_file
.endswith('.vcxproj'):
1198 fmt
= expected_vcxprojfile_fmt
1200 fmt
= expected_vcprojfile_fmt
1201 project_filename
= os
.path
.split(project_file
)[-1]
1202 project_basename
= os
.path
.splitext(project_filename
)[0]
1204 'PROJECT_BASENAME': project_basename
,
1205 'PROJECT_GUID': project_guid
,
1206 'TOOLS_VERSION': self
._get
_vcxproj
_file
_tools
_version
(vc_version
),
1207 'INCLUDE_DIRS': self
._get
_vcxproj
_file
_cpp
_path
(dirs
),
1208 'PLATFORM_TOOLSET': self
._get
_vcxproj
_file
_platform
_toolset
(vc_version
),
1211 def get_expected_projects_sln_file_contents(
1216 have_solution_project_nodes
=False,
1217 autofilter_solution_project_nodes
=None,
1219 if not have_solution_project_nodes
or autofilter_solution_project_nodes
:
1220 rval
= expected_projects_slnfile_fmt
% {
1221 'FORMAT_VERSION': self
._get
_solution
_file
_format
_version
(vc_version
),
1222 'VS_NUMBER': self
._get
_solution
_file
_vs
_number
(vc_version
),
1223 'PROJECT_NAME_1': project_file_1
.split('.')[0],
1224 'PROJECT_FILE_1': project_file_1
,
1225 'PROJECT_NAME_2': project_file_2
.split('.')[0],
1226 'PROJECT_FILE_2': project_file_2
,
1229 rval
= expected_projects_slnfile_fmt_slnnodes
% {
1230 'FORMAT_VERSION': self
._get
_solution
_file
_format
_version
(vc_version
),
1231 'VS_NUMBER': self
._get
_solution
_file
_vs
_number
(vc_version
),
1232 'PROJECT_NAME_1': project_file_1
.split('.')[0],
1233 'PROJECT_FILE_1': project_file_1
,
1234 'PROJECT_NAME_2': project_file_2
.split('.')[0],
1235 'PROJECT_FILE_2': project_file_2
,
1236 'SOLUTION_FILE_1': project_file_1
.split('.')[0] + ".sln",
1237 'SOLUTION_FILE_2': project_file_2
.split('.')[0] + ".sln",
1241 def get_expected_projects_sconscript_file_contents(
1247 autobuild_solution
=0,
1248 autofilter_projects
=None,
1249 default_guids
=False,
1252 'HOST_ARCH': self
.get_vs_host_arch(),
1253 'MSVS_VERSION': vc_version
,
1254 'PROJECT_FILE_1': project_file_1
,
1255 'PROJECT_FILE_2': project_file_2
,
1256 'SOLUTION_FILE': solution_file
,
1257 "AUTOBUILD_SOLUTION": autobuild_solution
,
1258 "AUTOFILTER_PROJECTS": autofilter_projects
,
1262 format
= SConscript_projects_defaultguids_contents_fmt
1264 format
= SConscript_projects_contents_fmt
1268 'PROJECT_GUID_1': PROJECT_GUID_1
,
1269 'PROJECT_GUID_2': PROJECT_GUID_2
,
1272 return format
% values
1277 # indent-tabs-mode:nil
1279 # vim: set expandtab tabstop=4 shiftwidth=4: