From: stevenknight Date: Thu, 15 Jan 2004 13:28:43 +0000 (+0000) Subject: Fix MSVS Project file invocation when running scons.bat. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9110dcd1120cea5a545b56c9c4c41bf1892fcc2f;p=scons.git Fix MSVS Project file invocation when running scons.bat. git-svn-id: http://scons.tigris.org/svn/scons/trunk@876 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d5675604..45b9df3f 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -122,6 +122,10 @@ RELEASE 0.95 - XXX - Supply meaningful error messages, not stack traces, if we try to add a non-Node as a source, dependency, or ignored dependency of a Node. + - Generate MSVS Project files that re-invoke SCons properly regardless + of whether the file was built via scons.bat or scons.py. + (Thanks to Niall Douglas for contributing code and testing.) + From Vincent Risi: - Add support for the bcc32, ilink32 and tlib Borland tools. diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index ee860e3d..e4272c3c 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -77,6 +77,29 @@ def _generateGUID(slnfile, name): solution = "{" + solution[:8] + "-" + solution[8:12] + "-" + solution[12:16] + "-" + solution[16:28] + "}" return solution +# This is how we re-invoke SCons from inside MSVS Project files. +# The problem is that we might have been invoked as either scons.bat +# or scons.py. If we were invoked directly as scons.py, then we could +# use sys.argv[0] to find the SCons "executable," but that doesn't work +# if we were invoked as scons.bat, which uses "python -c" to execute +# things and ends up with "-c" as sys.argv[0]. Consequently, we have +# the MSVS Project file invoke SCons the same way that scons.bat does, +# which works regardless of how we were invoked. +exec_script_main = "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-__VERSION__'), join(sys.prefix, 'scons-__VERSION__'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()" +exec_script_main_xml = string.replace(exec_script_main, "'", "'") + +# The string for the Python executable we tell the Project file to use +# is either sys.executable or, if an external PYTHON_ROOT environment +# variable exists, $(PYTHON)ROOT\\python.exe (generalized a little to +# pluck the actual executable name from sys.executable). +try: + python_root = os.environ['PYTHON_ROOT'] +except KeyError: + python_executable = sys.executable +else: + python_executable = os.path.join('$(PYTHON_ROOT)', + os.path.split(sys.executable)[1]) + class Config: pass @@ -233,7 +256,9 @@ class _GenerateV6DSP(_DSPGenerator): self.file.write('# PROP %sOutput_Dir "%s"\n' '# PROP %sIntermediate_Dir "%s"\n' % (base,outdir,base,outdir)) (d,c) = os.path.split(str(self.conspath)) - cmd = '%s %s -C %s -f %s %s' % (sys.executable, os.path.normpath(sys.argv[0]), d, c, buildtarget) + cmd = '%s -c "%s" -C %s -f %s %s' % (python_executable, + exec_script_main, + d, c, buildtarget) self.file.write('# PROP %sCmd_Line "%s"\n' '# PROP %sRebuild_Opt "-c && %s"\n' '# PROP %sTarget_File "%s"\n' @@ -356,11 +381,16 @@ class _GenerateV6DSP(_DSPGenerator): class _GenerateV7DSP(_DSPGenerator): """Generates a Project file for MSVS .NET""" + def __init__(self, dspfile, source, env, version): + _DSPGenerator.__init__(self, dspfile, source, env) + if version==7.0: self.version="7.00" + else: self.version="7.10" + def PrintHeader(self): self.file.write('\n' '\n' ' \n' - ' \n' % self.name) + ' \n' % (self.version, self.name)) def PrintProject(self): @@ -383,13 +413,13 @@ class _GenerateV7DSP(_DSPGenerator): buildtarget = self.configs[kind].buildtarget (d,c) = os.path.split(str(self.conspath)) - cmd = '%s %s -C %s -f %s %s\n' % (sys.executable,\ - os.path.normpath(sys.argv[0]),\ - d,c,buildtarget) + cmd = '%s -c "%s" -C %s -f %s %s' % (python_executable, + exec_script_main_xml, + d, c, buildtarget) - cleancmd = '%s %s -C %s -f %s -c %s' % (sys.executable,\ - os.path.normpath(sys.argv[0]),\ - d,c,buildtarget) + cleancmd = '%s -c "%s" -C %s -f %s -c %s' % (python_executable, + exec_script_main_xml, + d, c, buildtarget) self.file.write(' = 7.0: - g = _GenerateV7DSP(dspfile, source, env) + g = _GenerateV7DSP(dspfile, source, env, float(env['MSVS_VERSION'])) g.Build() else: g = _GenerateV6DSP(dspfile, source, env) @@ -683,7 +716,7 @@ def GenerateDSW(dswfile, dspfile, source, env): """Generates a Solution/Workspace file based on the version of MSVS that is being used""" if env.has_key('MSVS_VERSION') and float(env['MSVS_VERSION']) >= 7.0: - g = _GenerateV7DSW(dswfile, dspfile, source, env) + g = _GenerateV7DSW(dswfile, dspfile, source, env, float(env['MSVS_VERSION'])) g.Build() else: g = _GenerateV6DSW(dswfile, dspfile, source, env) diff --git a/test/msvs.py b/test/msvs.py index 03f08cb6..e447cb0b 100644 --- a/test/msvs.py +++ b/test/msvs.py @@ -24,14 +24,16 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" -import TestSCons -import sys -import re -import os.path import os -import TestCmd +import os.path +import re +import string +import sys import time +import TestCmd +import TestSCons + expected_dspfile = '''\ # Microsoft Developer Studio Project File - Name="Test" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 @@ -66,8 +68,8 @@ CFG=Test - Win32 Release # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "" # PROP BASE Intermediate_Dir "" -# PROP BASE Cmd_Line " -C -f SConstruct \Test.exe" -# PROP BASE Rebuild_Opt "-c && -C -f SConstruct \Test.exe" +# PROP BASE Cmd_Line " -c "" -C -f SConstruct \Test.exe" +# PROP BASE Rebuild_Opt "-c && -c "" -C -f SConstruct \Test.exe" # PROP BASE Target_File "\Test.exe" # PROP BASE Bsc_Name "" # PROP BASE Target_Dir "" @@ -75,8 +77,8 @@ CFG=Test - Win32 Release # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" # PROP Intermediate_Dir "" -# PROP Cmd_Line " -C -f SConstruct \Test.exe" -# PROP Rebuild_Opt "-c && -C -f SConstruct \Test.exe" +# PROP Cmd_Line " -c "" -C -f SConstruct \Test.exe" +# PROP Rebuild_Opt "-c && -c "" -C -f SConstruct \Test.exe" # PROP Target_File "\Test.exe" # PROP Bsc_Name "" # PROP Target_Dir "" @@ -214,10 +216,10 @@ expected_vcprojfile = '''\ ATLMinimizesCRunTimeLibraryUsage="FALSE"> -c "" -C -f SConstruct \Test.exe " - CleanCommandLine=" -C -f SConstruct -c \Test.exe" - RebuildCommandLine=" -C -f SConstruct \Test.exe + CleanCommandLine=" -c "" -C -f SConstruct -c \Test.exe" + RebuildCommandLine=" -c "" -C -f SConstruct \Test.exe " Output="\Test.exe"/> @@ -272,6 +274,16 @@ test = TestSCons.TestSCons(match = TestCmd.match_re) if sys.platform != 'win32': test.pass_test() +exec_script_main = "from os.path import join; import sys; sys.path = [ join(sys.prefix, 'Lib', 'site-packages', 'scons-0.94'), join(sys.prefix, 'scons-0.94'), join(sys.prefix, 'Lib', 'site-packages', 'scons'), join(sys.prefix, 'scons') ] + sys.path; import SCons.Script; SCons.Script.main()" +exec_script_main_xml = string.replace(exec_script_main, "'", "'") + +def substitute(input, workpath=test.workpath(), python=sys.executable): + result = string.replace(input, r'', workpath) + result = string.replace(result, r'', python) + result = string.replace(result, r'', exec_script_main) + result = string.replace(result, r'', exec_script_main_xml) + return result + #### # Determine which environments are installed on the test machine. test.write('SConstruct',''' @@ -312,25 +324,15 @@ env.MSVSProject(target = 'Test.dsp', test.run(arguments="Test.dsp") test.fail_test(not os.path.exists(test.workpath('Test.dsp'))) - test.fail_test(not os.path.exists(test.workpath('Test.dsw'))) - - # check to see that we got what we expected: - expected_dspfile = expected_dspfile.replace(r'',test.workpath()) - expected_dspfile = expected_dspfile.replace(r'',sys.executable) - expected_dspfile = expected_dspfile.replace(r'',os.path.join(os.environ['SCONS_SCRIPT_DIR'],'scons.py')) - expected_dswfile = expected_dswfile.replace(r'',test.workpath()) - - f = open(test.workpath('Test.dsp')) - dsp = f.read() - f.close() - + dsp = test.read('Test.dsp', 'r') + expect = substitute(expected_dspfile) # don't compare the pickled data - assert dsp[:len(expected_dspfile)] == expected_dspfile + assert dsp[:len(expect)] == expect - f = open(test.workpath('Test.dsw')) - dsw = f.read() - f.close() - assert dsw == expected_dswfile + test.fail_test(not os.path.exists(test.workpath('Test.dsw'))) + dsw = test.read('Test.dsw', 'r') + expect = substitute(expected_dswfile) + assert dsw == expect test.run(arguments='-c .') @@ -374,23 +376,16 @@ env.MSVSProject(target = 'Test.vcproj', test.run(arguments="Test.vcproj") test.fail_test(not os.path.exists(test.workpath('Test.vcproj'))) - test.fail_test(not os.path.exists(test.workpath('Test.sln'))) - - f = open(test.workpath('Test.vcproj')) - vcproj = f.read() - f.close() - expected_vcprojfile = expected_vcprojfile.replace(r'',test.workpath()) - expected_vcprojfile = expected_vcprojfile.replace(r'',sys.executable) - expected_vcprojfile = expected_vcprojfile.replace(r'',os.path.join(os.environ['SCONS_SCRIPT_DIR'],'scons.py')) - + test.read('Test.vcproj', 'r') + expect = substitute(expected_vcprojfile) # don't compare the pickled data - assert vcproj[:len(expected_vcprojfile)] == expected_vcprojfile + assert vcproj[:len(expect)] == expect - f = open(test.workpath('Test.sln')) - sln = f.read() - f.close() - - assert sln[:len(expected_slnfile)] == expected_slnfile + test.fail_test(not os.path.exists(test.workpath('Test.sln'))) + sln = test.read('Test.sln', 'r') + expect = substitute(expected_slnfile) + # don't compare the pickled data + assert sln[:len(expect)] == expect test.run(arguments='-c .') @@ -407,9 +402,18 @@ env.MSVSProject(target = 'Test.vcproj', test.fail_test(os.path.exists(test.workpath('Test.vcproj'))) test.fail_test(os.path.exists(test.workpath('Test.sln'))) -test.pass_test() - + # Test that running SCons with $PYTHON_ROOT in the environment + # changes the .vcproj output as expected. + os.environ['PYTHON_ROOT'] = 'xyzzy' + test.run(arguments='Test.vcproj') + python = os.path.join('$(PYTHON_ROOT)', os.path.split(sys.executable)[1]) + test.fail_test(not os.path.exists(test.workpath('Test.vcproj'))) + test.read('Test.vcproj', 'r') + expect = substitute(expected_vcprojfile, python=python) + # don't compare the pickled data + assert vcproj[:len(expect)] == expect +test.pass_test()