Merged revisions 3088-3319,3321-3322,3324-3349,3351-3481,3483-3484,3486-3520,3522...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 21 Feb 2009 16:58:07 +0000 (16:58 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 21 Feb 2009 16:58:07 +0000 (16:58 +0000)
http://scons.tigris.org/svn/scons/branches/vs_revamp

................
  r3089 | cournape | 2008-06-17 20:20:32 -0700 (Tue, 17 Jun 2008) | 3 lines

  Initialized merge tracking via "svnmerge" with revisions "1-3088" from
  http://scons.tigris.org/svn/scons/branches/core
................
  r3090 | cournape | 2008-06-18 02:36:58 -0700 (Wed, 18 Jun 2008) | 1 line

  Start working on MSVCCommon: we can find the product dir from registry and/or VS*COMTOOLS.
................
  r3102 | cournape | 2008-06-24 01:22:38 -0700 (Tue, 24 Jun 2008) | 1 line

  Get output from the bat file for vs.
................
  r3103 | cournape | 2008-06-24 01:26:21 -0700 (Tue, 24 Jun 2008) | 1 line

  Add function to parse vcbat output into env var.
................
  r3104 | cournape | 2008-06-24 01:42:47 -0700 (Tue, 24 Jun 2008) | 1 line

  Fix parsing output.
................
  r3105 | cournape | 2008-06-24 02:06:56 -0700 (Tue, 24 Jun 2008) | 1 line

  Set directly the variables to a list of path.
................
  r3106 | cournape | 2008-06-24 02:28:43 -0700 (Tue, 24 Jun 2008) | 1 line

  Add a function get_new to get only new paths which are added by the .bat file.
................
  r3107 | cournape | 2008-06-24 02:45:28 -0700 (Tue, 24 Jun 2008) | 1 line

  Better code for parse_output: do not swing with keys unnecessarily.
................
  r3108 | cournape | 2008-06-24 02:56:06 -0700 (Tue, 24 Jun 2008) | 1 line

  Put everything together in varbat_variables function.
................
  r3109 | cournape | 2008-06-24 03:03:36 -0700 (Tue, 24 Jun 2008) | 1 line

  More code cleaning for parse_output.
................
  r3110 | cournape | 2008-06-24 03:07:25 -0700 (Tue, 24 Jun 2008) | 1 line

  Handle empty path.
................
  r3111 | cournape | 2008-06-24 03:23:41 -0700 (Tue, 24 Jun 2008) | 1 line

  Add MSVCCommon to the manifest.
................
  r3112 | cournape | 2008-06-24 03:24:16 -0700 (Tue, 24 Jun 2008) | 1 line

  Plug the code to get env from reg/env to msvc tool.
................
  r3319 | cournape | 2008-08-28 00:53:53 -0700 (Thu, 28 Aug 2008) | 188 lines

  Merged revisions 3094,3115-3128,3181-3182,3194,3204,3206,3217-3218,3231,3237-3247,3249,3265 via svnmerge from
  http://scons.tigris.org/svn/scons/branches/core

  ................
    r3094 | stevenknight | 2008-06-20 01:52:16 +0900 (Fri, 20 Jun 2008) | 3 lines

    Change the User's Guide to use the new Variables object and its
    associated function for controlling command-line build variables.
  ................
    r3115 | stevenknight | 2008-06-25 22:46:36 +0900 (Wed, 25 Jun 2008) | 2 lines

    Issue 2072:  end indentation after generated Builder text.
  ................
    r3116 | stevenknight | 2008-06-26 11:07:15 +0900 (Thu, 26 Jun 2008) | 2 lines

    Reorganize the command-line arguments chapter.
  ................
    r3117 | stevenknight | 2008-06-26 11:13:58 +0900 (Thu, 26 Jun 2008) | 2 lines

    Editing pass for formatting in the Glob() sections.
  ................
    r3118 | stevenknight | 2008-06-26 11:23:09 +0900 (Thu, 26 Jun 2008) | 3 lines

    Wording changing:  Preventing => Controlling, because the chapter
    also talks about how to clean additional targets.
  ................
    r3119 | stevenknight | 2008-06-26 11:50:41 +0900 (Thu, 26 Jun 2008) | 2 lines

    Fix missing </literal> tags, minor wording fix.
  ................
    r3120 | stevenknight | 2008-06-26 11:58:34 +0900 (Thu, 26 Jun 2008) | 2 lines

    Add "the Default Function" to the appropriate subsection title.
  ................
    r3121 | stevenknight | 2008-06-27 00:33:43 +0900 (Fri, 27 Jun 2008) | 2 lines

    Issue 1988:  Document the Variables.UnknownVariables() method.
  ................
    r3122 | stevenknight | 2008-06-27 00:35:51 +0900 (Fri, 27 Jun 2008) | 3 lines

    Remove comments listing some of the variables that have been
    documented recently.
  ................
    r3123 | stevenknight | 2008-06-27 04:42:53 +0900 (Fri, 27 Jun 2008) | 2 lines

    Issue 2118:  Fix incorrectly swapped man page text.  (Alexey Zezukin)
  ................
    r3124 | bdbaddog | 2008-06-27 13:23:46 +0900 (Fri, 27 Jun 2008) | 2 lines

    Fix bug 2108 - duplicate text in description of interactive mode
  ................
    r3125 | stevenknight | 2008-06-28 13:54:56 +0900 (Sat, 28 Jun 2008) | 3 lines

    Issue 1993:  Document the $*COMSTR variables, the Progress() function,
    and create a common "Controlling Build Output" chapter.
  ................
    r3126 | garyo | 2008-06-28 21:46:44 +0900 (Sat, 28 Jun 2008) | 1 line

    Fix issue 2105; temporarily omit doc saying that SetOption can override user-created Options (until that is implemented).
  ................
    r3127 | stevenknight | 2008-06-28 23:29:18 +0900 (Sat, 28 Jun 2008) | 2 lines

    Issue 1747:  Explicitly document use of Node lists as input to Depends().
  ................
    r3128 | stevenknight | 2008-06-28 23:48:32 +0900 (Sat, 28 Jun 2008) | 6 lines

    White space change:  indent the construction environment sections
    further to make way for combining this chapter with others to make
    one big "Controlling Environments" chapter.
    Also, get rid of some now-unnecessary doc from the old Cons classic
    POD, that was taking up space here waiting to be documented.
  ................
    r3181 | stevenknight | 2008-07-08 23:17:27 +0900 (Tue, 08 Jul 2008) | 4 lines

    Reorganize the discussion of different environments into one chapter.
    Document the SetDefault(), PrependUnique(), AppendUnique(),
    PrependENVPath() and AppendENVPath() functions.
  ................
    r3182 | stevenknight | 2008-07-09 00:47:55 +0900 (Wed, 09 Jul 2008) | 2 lines

    Issue 1998:  Docment the ARGLIST variable in the User's Guide.
  ................
    r3194 | GregNoel | 2008-07-10 15:16:51 +0900 (Thu, 10 Jul 2008) | 1 line

    remove unnecessary trailing spaces on lines
  ................
    r3204 | stevenknight | 2008-07-12 00:29:18 +0900 (Sat, 12 Jul 2008) | 2 lines

    Issue 1853:  Remove referenc to SCons.Util.CLVar from a doc example.
  ................
    r3206 | GregNoel | 2008-07-12 18:08:19 +0900 (Sat, 12 Jul 2008) | 1 line

    Another go at describing VariantDir()
  ................
    r3217 | stevenknight | 2008-07-16 22:52:44 +0900 (Wed, 16 Jul 2008) | 2 lines

    Update the copyright year in the User's Guide.
  ................
    r3218 | stevenknight | 2008-07-16 23:08:52 +0900 (Wed, 16 Jul 2008) | 3 lines

    Issue 1881:  Add man page text clarifying the behavior of
    Add{Pre,Post}Action() when multiple targets are specified.
  ................
    r3231 | stevenknight | 2008-07-22 17:58:11 +0900 (Tue, 22 Jul 2008) | 4 lines

    Enhance MSVSProject() tests so they're runnable on any system, regardless
    of whether Visual Studio is installed, or if it's even a Windows system
    at all.
  ................
    r3237 | GregNoel | 2008-07-26 16:07:49 +0900 (Sat, 26 Jul 2008) | 1 line

    Issue 1983: Document ParseConfig, MergeFlags, and ParseFlags for the Users' Guide
  ................
    r3238 | stevenknight | 2008-07-27 00:38:18 +0900 (Sun, 27 Jul 2008) | 3 lines

    Follow-ons for building the User's Guide with Greg's recent additions
    for MergeFlags() and ParseFlags().
  ................
    r3239 | stevenknight | 2008-07-27 01:52:40 +0900 (Sun, 27 Jul 2008) | 3 lines

    Re-arrange some sections talking about creating construction environments
    and fetching/expanding variables.
  ................
    r3240 | stevenknight | 2008-07-27 04:16:11 +0900 (Sun, 27 Jul 2008) | 2 lines

    Stylistic editing of new {Merge,Parse}{Config,Flags} sections.
  ................
    r3241 | GregNoel | 2008-07-27 04:42:42 +0900 (Sun, 27 Jul 2008) | 1 line

    Issue 1987: Document SideEffect for Users' Guide (incomplete)
  ................
    r3242 | stevenknight | 2008-07-27 05:27:56 +0900 (Sun, 27 Jul 2008) | 2 lines

    Correct dumb XML mistakes in my last checkin.
  ................
    r3243 | stevenknight | 2008-07-27 05:34:05 +0900 (Sun, 27 Jul 2008) | 2 lines

    One-character typo.  Gah.
  ................
    r3244 | stevenknight | 2008-07-27 05:44:14 +0900 (Sun, 27 Jul 2008) | 2 lines

    Issue 1977,1980:  document the Exit() and Flatten() functions.
  ................
    r3245 | stevenknight | 2008-07-28 02:24:12 +0900 (Mon, 28 Jul 2008) | 14 lines

    Updates to the new SideEffect section (kudos to Greg).

    While working on this, Greg discovered a bug (issue #2154) that prevents
    a SideEffect() file from being used as input to another builder call; it
    makes the builder target not get build when run in paralle (e.g. -j2)...
    :-(  So this patch comments out that section of Greg's section.

    This also contains my usual editing pass.  In this case I changed some
    of the examples and added a bunch of text to try to help clarify some
    things that seemed important.  I also added a closing paragraph warning
    that SideEffect() really shouldn't be used as an alternative to specifying
    multiple target files in a Builder call when a command builds more than
    one file that you care about.
  ................
    r3246 | stevenknight | 2008-07-28 02:31:17 +0900 (Mon, 28 Jul 2008) | 2 lines

    Proofreading edits of the MergeFlags() section.  (Greg Noel)
  ................
    r3247 | stevenknight | 2008-07-28 03:17:27 +0900 (Mon, 28 Jul 2008) | 2 lines

    Issue 1976:  document ensure{Python,SCons}Version() in the User's Guide.
  ................
    r3249 | GregNoel | 2008-07-29 07:57:00 +0900 (Tue, 29 Jul 2008) | 1 line

    Add svn-bisect script
  ................
    r3265 | stevenknight | 2008-08-09 23:08:40 +0900 (Sat, 09 Aug 2008) | 14 lines

    Merged revisions 3060-3264 via svnmerge from
    http://scons.tigris.org/svn/scons/trunk

    ........
      r3092 | stevenknight | 2008-06-19 06:35:38 -0700 (Thu, 19 Jun 2008) | 2 lines

      Fix typo:  caes => case(s).
    ........
      r3093 | stevenknight | 2008-06-19 06:42:52 -0700 (Thu, 19 Jun 2008) | 3 lines

      Another typo fix (cse => case) and clarification of why submitting a
      test case is good.
    ........
  ................
................
  r3321 | cournape | 2008-08-28 01:24:20 -0700 (Thu, 28 Aug 2008) | 1 line

  Fix indenting issues.
................
  r3324 | cournape | 2008-08-29 04:56:16 -0700 (Fri, 29 Aug 2008) | 2 lines

  Fix eol to unix for msvc files.
................
  r3398 | cournape | 2008-09-12 23:55:41 -0700 (Fri, 12 Sep 2008) | 2 lines

  Add a function FindMSVSBatFile.
................
  r3399 | cournape | 2008-09-12 23:56:03 -0700 (Fri, 12 Sep 2008) | 6 lines

  Merge commit '5258bd36b856d1f042aa9ca8df419af96e1d7bf8' into work

  Conflicts:

   src/engine/SCons/Tool/MSVCCommon.py
................
  r3400 | cournape | 2008-09-13 02:13:24 -0700 (Sat, 13 Sep 2008) | 1 line
................
  r3403 | cournape | 2008-09-13 22:02:26 -0700 (Sat, 13 Sep 2008) | 1 line

  Do not use None as default argument for FindMSVSBatFile, as it does not make sense.
................
  r3404 | cournape | 2008-09-13 22:06:23 -0700 (Sat, 13 Sep 2008) | 1 line

  Do not raise IOError in find_ functions, but return None.
................
  r3405 | cournape | 2008-09-13 22:35:59 -0700 (Sat, 13 Sep 2008) | 1 line

  Remove common paths between os.environ and var parsed by ParseBatFile.
................
  r3406 | cournape | 2008-09-13 22:50:00 -0700 (Sat, 13 Sep 2008) | 1 line

  Add MergeMSVSBatFile function.
................
  r3407 | cournape | 2008-09-13 23:12:19 -0700 (Sat, 13 Sep 2008) | 2 lines

  Remove trailing spaces.
................
  r3408 | cournape | 2008-09-13 23:12:47 -0700 (Sat, 13 Sep 2008) | 2 lines

  Remove printing debug statement.
................
  r3409 | cournape | 2008-09-13 23:13:16 -0700 (Sat, 13 Sep 2008) | 2 lines

  Improve documentation of public functions for MSVCCommon.py.
................
  r3410 | cournape | 2008-09-13 23:23:09 -0700 (Sat, 13 Sep 2008) | 2 lines

  Set a default version of use for MergeMSVSBatFile.
................
  r3411 | cournape | 2008-09-13 23:23:31 -0700 (Sat, 13 Sep 2008) | 2 lines

  Update examples.
................
  r3412 | cournape | 2008-09-13 23:23:54 -0700 (Sat, 13 Sep 2008) | 2 lines

  Look for several versions before giving up.
................
  r3413 | cournape | 2008-09-13 23:24:17 -0700 (Sat, 13 Sep 2008) | 2 lines

  Improve documentation for MergeMSVSBatFile.
................
  r3483 | cournape | 2008-09-25 22:20:11 -0700 (Thu, 25 Sep 2008) | 1 line

  Indent docstrings correctly.
................
  r3486 | cournape | 2008-09-26 00:17:47 -0700 (Fri, 26 Sep 2008) | 1 line

  Use PrependENVPath to merge MSVC variables.
................
  r3487 | cournape | 2008-09-26 00:18:35 -0700 (Fri, 26 Sep 2008) | 1 line

  Use new MSVC support instead of the old one by default.
................
  r3488 | cournape | 2008-09-26 00:30:34 -0700 (Fri, 26 Sep 2008) | 1 line

  Add a small note about new msvc support.
................
  r3493 | stevenknight | 2008-09-27 08:02:30 -0700 (Sat, 27 Sep 2008) | 4 lines

  Change our catching of implicit RegError and InternalError exceptions
  when trying to do "MSVS stuff" into raising and catching a new explicit
  MSVCError exception.
................
  r3494 | stevenknight | 2008-09-27 08:16:30 -0700 (Sat, 27 Sep 2008) | 8 lines

  Fix it so tests will work on Linux:
  * Use full names of SCons.Util.* things so we don't die at import time
    if they don't exist.
  * Use the new SCons.Errors.MSVCError exception.
  Also:
  * Sort import statements.
  * Add copyright and doc string.
................
  r3495 | stevenknight | 2008-09-27 08:18:11 -0700 (Sat, 27 Sep 2008) | 2 lines

  Python 1.5 portability:  no "import ... as" and no list comprehensions.
................
  r3496 | cournape | 2008-09-27 23:07:55 -0700 (Sat, 27 Sep 2008) | 2 lines

  Fix pdir_from_reg for VS 2003 .net.
................
  r3497 | cournape | 2008-09-28 00:01:12 -0700 (Sun, 28 Sep 2008) | 1 line

  Add comments about discrepancies between various VS versions.
................
  r3498 | cournape | 2008-09-28 00:02:38 -0700 (Sun, 28 Sep 2008) | 1 line

  Fix pdir_from_env for VS 2003 .net.
................
  r3499 | cournape | 2008-09-28 00:04:09 -0700 (Sun, 28 Sep 2008) | 1 line

  Remove dead code.
................
  r3500 | cournape | 2008-09-28 01:16:12 -0700 (Sun, 28 Sep 2008) | 1 line

  Fix typo: exceptions are raised, not returned...
................
  r3501 | cournape | 2008-09-28 01:16:45 -0700 (Sun, 28 Sep 2008) | 1 line

  Add a small comment on vsvars32 vs vsvarsall.
................
  r3502 | cournape | 2008-09-28 01:17:20 -0700 (Sun, 28 Sep 2008) | 1 line

  Fix detect for msvc tool.
................
  r3503 | cournape | 2008-09-28 03:42:22 -0700 (Sun, 28 Sep 2008) | 1 line

  Add WoW6432 info.
................
  r3504 | cournape | 2008-09-28 03:42:46 -0700 (Sun, 28 Sep 2008) | 1 line

  Add a function is_win64, needed to detect 32 bits VS on 64 bits windows.
................
  r3505 | cournape | 2008-09-28 04:08:20 -0700 (Sun, 28 Sep 2008) | 1 line

  Use required version if set; look for a valid version otherwise.
................
  r3506 | cournape | 2008-09-28 04:13:25 -0700 (Sun, 28 Sep 2008) | 1 line

  Forgot to call with env gar.
................
  r3507 | cournape | 2008-09-28 04:20:30 -0700 (Sun, 28 Sep 2008) | 1 line

  Fix typo.
................
  r3508 | cournape | 2008-09-28 04:24:30 -0700 (Sun, 28 Sep 2008) | 1 line

  And another typo.
................
  r3509 | cournape | 2008-09-28 04:27:15 -0700 (Sun, 28 Sep 2008) | 1 line

  And another...
................
  r3510 | cournape | 2008-09-28 04:35:02 -0700 (Sun, 28 Sep 2008) | 1 line

  Add a FindDefaultMSVSBatFile function to use in msvc.
................
  r3511 | cournape | 2008-09-28 04:35:27 -0700 (Sun, 28 Sep 2008) | 1 line

  Use FindDefaultMSVSBatFile to detect msvc if no specific version was required.
................
  r3512 | cournape | 2008-09-28 04:49:26 -0700 (Sun, 28 Sep 2008) | 1 line

  Fix get_required_version.
................
  r3513 | cournape | 2008-09-28 04:52:14 -0700 (Sun, 28 Sep 2008) | 1 line

  Typo.
................
  r3516 | cournape | 2008-09-29 05:54:51 -0700 (Mon, 29 Sep 2008) | 1 line

  Add our own custom query_versions to detect available VS versions on the build machine.
................
  r3517 | cournape | 2008-09-29 06:02:46 -0700 (Mon, 29 Sep 2008) | 1 line

  Add a function to get default version of MS VS, but using new logic based on bat file instead of registry insanity.
................
  r3518 | cournape | 2008-09-29 06:27:46 -0700 (Mon, 29 Sep 2008) | 1 line

  Use query_version to get actual VS version to use; my previous attempt was totally bogus.
................
  r3519 | cournape | 2008-09-29 07:03:58 -0700 (Mon, 29 Sep 2008) | 1 line

  Update our fake test for debugging purpose.
................
  r3522 | cournape | 2008-09-29 21:54:53 -0700 (Mon, 29 Sep 2008) | 1 line

  Always succeed msvc.generate, even when no compiler is found.
................
  r3532 | garyo | 2008-10-01 21:48:33 -0700 (Wed, 01 Oct 2008) | 1 line

  vs_revamp: look for paths non-case-sensitively for e.g. VC9 Express.
................
  r3553 | cournape | 2008-10-06 06:00:05 -0700 (Mon, 06 Oct 2008) | 2 lines

  Rename default_version function.
................
  r3554 | cournape | 2008-10-06 06:00:34 -0700 (Mon, 06 Oct 2008) | 2 lines

  Put MSVCCommon import on top.
................
  r3555 | cournape | 2008-10-06 06:00:56 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use new MSVS detection in mslink tool.
................
  r3556 | cournape | 2008-10-06 06:01:24 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use detect_msvs function for every MS-tool detect method.
................
  r3557 | cournape | 2008-10-06 06:01:52 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use single function to detect default msvs version.
................
  r3558 | cournape | 2008-10-06 06:02:12 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use common function to detect msvs version for mslib tool.
................
  r3559 | cournape | 2008-10-06 06:02:33 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use common msvc funcs in linkloc tool.
................
  r3560 | cournape | 2008-10-06 06:02:53 -0700 (Mon, 06 Oct 2008) | 2 lines

  Remove old code for msvc: not used anymore.
................
  r3561 | cournape | 2008-10-06 06:03:13 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use merge_default_version in msvs tool.
................
  r3562 | cournape | 2008-10-06 06:03:34 -0700 (Mon, 06 Oct 2008) | 2 lines

  Remove more obsolete cruft.
................
  r3563 | cournape | 2008-10-06 06:03:53 -0700 (Mon, 06 Oct 2008) | 2 lines

  Use common msvs detection instead of cutom one in midl.py.
................
  r3564 | cournape | 2008-10-06 06:04:13 -0700 (Mon, 06 Oct 2008) | 2 lines

  Removed obsolete is_msvs_installed.
................
  r3565 | cournape | 2008-10-06 06:04:32 -0700 (Mon, 06 Oct 2008) | 2 lines

  Make sure we still use string in MSVS_VERSION, even if we use float internally everywhere otherwise.
................
  r3567 | cournape | 2008-10-06 07:41:16 -0700 (Mon, 06 Oct 2008) | 1 line

  Add env argument to MergeBatFile.
................
  r3568 | cournape | 2008-10-06 07:43:07 -0700 (Mon, 06 Oct 2008) | 1 line

  Add env argument to get_output to control environment executing the bat file.
................
  r3573 | cournape | 2008-10-07 01:48:05 -0700 (Tue, 07 Oct 2008) | 1 line

  Remove obsolete varbat_variables.
................
  r3574 | cournape | 2008-10-07 01:48:33 -0700 (Tue, 07 Oct 2008) | 1 line

  Define a DEFVERSIONSTR.
................
  r3575 | cournape | 2008-10-07 01:48:57 -0700 (Tue, 07 Oct 2008) | 1 line

  Set supported versions in a global variable.
................
  r3576 | cournape | 2008-10-07 01:49:21 -0700 (Tue, 07 Oct 2008) | 1 line

  Trailing spaces.
................
  r3577 | cournape | 2008-10-07 01:49:43 -0700 (Tue, 07 Oct 2008) | 1 line

  Add a function to normalize environments for some keys set.
................
  r3578 | cournape | 2008-10-07 01:50:10 -0700 (Tue, 07 Oct 2008) | 1 line

  Use normalized env when executing the .bat file.
................
  r3579 | cournape | 2008-10-07 02:02:18 -0700 (Tue, 07 Oct 2008) | 1 line

  Typo.
................
  r3580 | cournape | 2008-10-07 02:13:26 -0700 (Tue, 07 Oct 2008) | 1 line

  Fix wrong definition of version to env var dictionary.
................
  r3581 | cournape | 2008-10-07 02:15:24 -0700 (Tue, 07 Oct 2008) | 1 line

  Fix missed variable.
................
  r3582 | cournape | 2008-10-07 02:28:35 -0700 (Tue, 07 Oct 2008) | 1 line

  Use values and not keys of env.
................
  r3583 | cournape | 2008-10-07 03:45:50 -0700 (Tue, 07 Oct 2008) | 1 line

  Handle string encoding when reading env from .bat file.
................
  r3584 | cournape | 2008-10-07 04:07:26 -0700 (Tue, 07 Oct 2008) | 1 line

  Directly return the parsed variables, since we use a sanitize env now.
................
  r3585 | cournape | 2008-10-07 04:33:34 -0700 (Tue, 07 Oct 2008) | 1 line

  Add locations of MS sdk (from registry only).
................
  r3586 | cournape | 2008-10-07 04:43:32 -0700 (Tue, 07 Oct 2008) | 1 line

  Mention that MS SDK has only been investigated for 6.1.
................
  r3587 | cournape | 2008-10-07 04:43:56 -0700 (Tue, 07 Oct 2008) | 1 line

  Add function to get the MS SDK directory from registry.
................
  r3588 | cournape | 2008-10-07 04:50:52 -0700 (Tue, 07 Oct 2008) | 1 line

  Fix typo in variable.
................
  r3589 | cournape | 2008-10-07 05:12:27 -0700 (Tue, 07 Oct 2008) | 1 line

  Remove unused keep arg of get_output.
................
  r3590 | cournape | 2008-10-07 05:12:49 -0700 (Tue, 07 Oct 2008) | 1 line

  Fix typo in MS SDK reg key.
................
  r3591 | cournape | 2008-10-07 05:30:50 -0700 (Tue, 07 Oct 2008) | 1 line

  Fix parse_output for cases where keys do not have special treatment.
................
  r3597 | cournape | 2008-10-08 01:18:17 -0700 (Wed, 08 Oct 2008) | 1 line

  Add a function to parse outputstring into env dict.
................
  r3602 | cournape | 2008-10-09 10:34:10 -0700 (Thu, 09 Oct 2008) | 1 line

  Use version string for default version.
................
  r3605 | cournape | 2008-10-10 06:36:45 -0700 (Fri, 10 Oct 2008) | 1 line

  Start working on using def path if requested to avoid huge cost of executing the .bat files.
................
  r3606 | cournape | 2008-10-10 06:47:43 -0700 (Fri, 10 Oct 2008) | 1 line

  Rename global var to get windows sdk from registry.
................
  r3607 | cournape | 2008-10-10 07:01:39 -0700 (Fri, 10 Oct 2008) | 1 line

  Handle platform sdk in default env.
................
  r3661 | cournape | 2008-10-11 03:47:55 -0700 (Sat, 11 Oct 2008) | 1 line

  Move MSVCCommon module into a subpackage.
................
  r3662 | cournape | 2008-10-11 04:06:15 -0700 (Sat, 11 Oct 2008) | 1 line

  Start splitting MSVCCommon module in multiple files.
................
  r3663 | cournape | 2008-10-11 04:09:30 -0700 (Sat, 11 Oct 2008) | 1 line

  Put sdk-stuff in separate module.
................
  r3664 | cournape | 2008-10-11 04:20:25 -0700 (Sat, 11 Oct 2008) | 1 line

  Put defaults and environment parsing/bat execution in separate module.
................
  r3665 | cournape | 2008-10-11 04:27:29 -0700 (Sat, 11 Oct 2008) | 1 line

  Add a version module for version handling/detection.
................
  r3666 | cournape | 2008-10-11 04:56:52 -0700 (Sat, 11 Oct 2008) | 1 line

  Fix various broken imports related to refactoring of MSVCCommon.
................
  r3667 | cournape | 2008-10-11 05:00:57 -0700 (Sat, 11 Oct 2008) | 1 line

  Move msvc notes in our new module.
................
  r3668 | cournape | 2008-10-11 06:12:34 -0700 (Sat, 11 Oct 2008) | 1 line

  Add COMSPEC to default env['ENV'] + put system32 into the path.
................
  r3669 | cournape | 2008-10-11 06:14:02 -0700 (Sat, 11 Oct 2008) | 1 line

  Set up PATH correctly.
................
  r3671 | cournape | 2008-10-11 06:17:07 -0700 (Sat, 11 Oct 2008) | 1 line

  Fix various import issues left over by the refactorization.
................
  r3674 | cournape | 2008-10-11 06:42:57 -0700 (Sat, 11 Oct 2008) | 1 line

  SDK versions can have letters in them: cannot use float, have to use strings.
................
  r3675 | cournape | 2008-10-11 06:55:28 -0700 (Sat, 11 Oct 2008) | 1 line

  Update msvc notes.
................
  r3680 | cournape | 2008-10-14 01:17:13 -0700 (Tue, 14 Oct 2008) | 1 line

  Add some info I found out on sdk mess.
................
  r3681 | cournape | 2008-10-14 02:15:07 -0700 (Tue, 14 Oct 2008) | 1 line

  Add some more comments on how we get the SDK.
................
  r3682 | cournape | 2008-10-14 03:05:08 -0700 (Tue, 14 Oct 2008) | 1 line

  The SDK tool can find the 2003R2 SDK too.
................
  r3686 | cournape | 2008-10-14 20:13:20 -0700 (Tue, 14 Oct 2008) | 1 line

  Fix tab vs space.
................
  r3687 | cournape | 2008-10-14 20:14:40 -0700 (Tue, 14 Oct 2008) | 2 lines

  Add UUID for sdk 2003R1
  .
................
  r3688 | cournape | 2008-10-14 20:33:18 -0700 (Tue, 14 Oct 2008) | 1 line

  Add comment on which version of the SDK the sdk module can find.
................
  r3690 | cournape | 2008-10-15 01:14:12 -0700 (Wed, 15 Oct 2008) | 1 line

  Update the msvc notes.
................
  r3696 | cournape | 2008-10-16 23:23:14 -0700 (Thu, 16 Oct 2008) | 1 line

  Change sanity check files for SDK 6.0A and 6.1.
................
  r3697 | cournape | 2008-10-16 23:35:03 -0700 (Thu, 16 Oct 2008) | 1 line

  Do not handle sdk in defaults.
................
  r3698 | cournape | 2008-10-16 23:49:25 -0700 (Thu, 16 Oct 2008) | 1 line

  Add docstring for exists method of ms tools.
................
  r3699 | cournape | 2008-10-17 00:04:17 -0700 (Fri, 17 Oct 2008) | 1 line

  Fix spave vs tab issue.
................
  r3700 | cournape | 2008-10-17 00:26:50 -0700 (Fri, 17 Oct 2008) | 1 line

  Add a TODO.
................
  r3701 | cournape | 2008-10-17 00:58:27 -0700 (Fri, 17 Oct 2008) | 1 line

  Find VC98 product dir from the registry.
................
  r3702 | cournape | 2008-10-17 01:01:51 -0700 (Fri, 17 Oct 2008) | 1 line

  Refactor find_v* functions: 3 different batname needed now that we support VC98.
................
  r3703 | cournape | 2008-10-17 01:03:20 -0700 (Fri, 17 Oct 2008) | 1 line

  Fix dos EOL.
................
  r3704 | cournape | 2008-10-17 01:04:28 -0700 (Fri, 17 Oct 2008) | 1 line

  More fixes dos EOL.
................
  r3705 | cournape | 2008-10-17 01:08:59 -0700 (Fri, 17 Oct 2008) | 1 line

  Fix typo in bat filename for VS 2005/2008.
................
  r3706 | cournape | 2008-10-17 01:10:12 -0700 (Fri, 17 Oct 2008) | 1 line

  VC98 now correctly detected in query_versions.
................
  r3707 | cournape | 2008-10-17 01:58:49 -0700 (Fri, 17 Oct 2008) | 1 line

  Fix some encoding issues when parsing the .bat file ouptut.
................
  r3708 | cournape | 2008-10-17 02:35:25 -0700 (Fri, 17 Oct 2008) | 1 line

  Remove unused/dead code.
................
  r3713 | cournape | 2008-10-24 05:40:31 -0700 (Fri, 24 Oct 2008) | 1 line

  Add a function to detect VCINSTALLDIR and VSINSTALLDIR.
................
  r3714 | cournape | 2008-10-24 05:41:48 -0700 (Fri, 24 Oct 2008) | 1 line

  'inline' trivial functions.
................
  r3715 | cournape | 2008-10-24 05:45:40 -0700 (Fri, 24 Oct 2008) | 1 line

  Fix bad function name in previous commit.
................
  r3716 | cournape | 2008-10-24 05:50:34 -0700 (Fri, 24 Oct 2008) | 1 line

  Rename find_msvs_path since several paths are returned.
................
  r3717 | cournape | 2008-10-24 05:51:00 -0700 (Fri, 24 Oct 2008) | 1 line

  Return correct variable in find_msvs_paths.
................
  r3718 | cournape | 2008-10-24 05:51:42 -0700 (Fri, 24 Oct 2008) | 1 line

  Fix VSINSTALLDIR.
................
  r3719 | cournape | 2008-10-24 05:52:40 -0700 (Fri, 24 Oct 2008) | 1 line

  Normalize paths returned by find_msvs_paths.
................
  r3720 | cournape | 2008-10-25 04:06:14 -0700 (Sat, 25 Oct 2008) | 1 line

  Adapt empty test case to new msvc support.
................
  r3721 | cournape | 2008-10-25 04:10:53 -0700 (Sat, 25 Oct 2008) | 1 line

  Handle os.environ overriding a bit better.
................
  r3722 | cournape | 2008-10-25 04:29:22 -0700 (Sat, 25 Oct 2008) | 1 line

  Add our get_msvs_install_dirs function to be compatible with old unit test suite.
................
  r3723 | cournape | 2008-10-25 04:31:21 -0700 (Sat, 25 Oct 2008) | 1 line

  Fix empty test case.
................
  r3724 | cournape | 2008-10-25 05:16:32 -0700 (Sat, 25 Oct 2008) | 1 line

  Start working on net frameworks detection.
................
  r3725 | cournape | 2008-10-25 05:21:06 -0700 (Sat, 25 Oct 2008) | 1 line

  Fix forgotten colon.
................
  r3726 | cournape | 2008-10-25 05:25:57 -0700 (Sat, 25 Oct 2008) | 1 line

  Add a function to query available .net frameworks.
................
  r3727 | cournape | 2008-10-25 05:27:15 -0700 (Sat, 25 Oct 2008) | 1 line

  Fix typo.
................
  r3728 | cournape | 2008-10-25 05:28:03 -0700 (Sat, 25 Oct 2008) | 1 line

  Forgot to improt string module.
................
  r3729 | cournape | 2008-10-25 05:42:51 -0700 (Sat, 25 Oct 2008) | 1 line

  Add a method to detect the MS SDK.
................
  r3730 | cournape | 2008-10-25 05:54:16 -0700 (Sat, 25 Oct 2008) | 1 line

  Simplify merge_default_version: do not use MSVS_USE_DEFAULT_PATHS anymore.
................
  r3731 | cournape | 2008-10-25 06:10:36 -0700 (Sat, 25 Oct 2008) | 1 line

  Add functions to add sdk depending on MS toolsuite.
................
  r3732 | cournape | 2008-10-25 06:11:55 -0700 (Sat, 25 Oct 2008) | 1 line

  Set up the SDK in merge_default_version.
................
  r3733 | cournape | 2008-10-25 06:14:08 -0700 (Sat, 25 Oct 2008) | 1 line

  Use float version, not string version for FindMSVSBatFile.
................
  r3734 | cournape | 2008-10-25 06:14:59 -0700 (Sat, 25 Oct 2008) | 1 line

  Forgot to pass scons env argument for psdk functions.
................
  r3735 | cournape | 2008-10-25 06:17:11 -0700 (Sat, 25 Oct 2008) | 1 line

  Pass correct versions tring.
................
  r3736 | cournape | 2008-10-25 06:17:47 -0700 (Sat, 25 Oct 2008) | 1 line

  Fix typo.
................
  r3737 | cournape | 2008-10-25 07:55:25 -0700 (Sat, 25 Oct 2008) | 1 line

  Add MSVCCommon module to MANIFEST.
................
  r3738 | cournape | 2008-10-25 08:23:30 -0700 (Sat, 25 Oct 2008) | 1 line

  Add MSVCCommon to distutils setup files.
................
  r3739 | cournape | 2008-10-25 08:43:40 -0700 (Sat, 25 Oct 2008) | 1 line

  Include 8 in the msvs versions to Set PSDK.
................
  r3740 | cournape | 2008-10-25 08:47:09 -0700 (Sat, 25 Oct 2008) | 1 line

  Set up PSDK in msvc tool only.
................
  r3832 | stevenknight | 2008-12-12 08:10:24 -0800 (Fri, 12 Dec 2008) | 2 lines

  Set svn:ignore on the Tool/MSVCCommon subdirectory.
................
  r3833 | stevenknight | 2008-12-12 08:27:06 -0800 (Fri, 12 Dec 2008) | 4 lines

  When appending to the PATH, use get_system_root() instead of assuming
  SYSTEMROOT is in env['ENV'].  Make using get_system_root() repeatedly
  more acceptable by returning a cached value after the first call.
................
  r3834 | stevenknight | 2008-12-12 10:17:01 -0800 (Fri, 12 Dec 2008) | 5 lines

  Define WindowsError and other necessary things (HKEY_*, RegGetValue())
  on non-Windows platforms, so we can run platform-independent vs_revamp
  tests on non-Windows platforms without having to teach the rest of the
  code that they might not be running on a Windows system.
................
  r3835 | stevenknight | 2008-12-12 10:18:30 -0800 (Fri, 12 Dec 2008) | 2 lines

  Add an AppendENVPath() method to our fake Environment class.
................
  r3933 | stevenknight | 2009-01-30 05:54:00 -0800 (Fri, 30 Jan 2009) | 3 lines

  Add copyright statements, __revision__ specifications and __doc__ string
  place-holders.
................
  r3934 | stevenknight | 2009-01-30 06:39:56 -0800 (Fri, 30 Jan 2009) | 2 lines

  Python 1.5 portability.
................
  r3935 | stevenknight | 2009-01-30 07:12:20 -0800 (Fri, 30 Jan 2009) | 3 lines

  Add copyright and __revision__, fix import module for
  {Find,Parse,Merge}BatFile() (from SCons.Tool.MSVCCommon.misc).
................
  r3937 | stevenknight | 2009-01-31 07:40:31 -0800 (Sat, 31 Jan 2009) | 5 lines

  Fix NameError on the msvs_parse_version() call in merge_default_version().
  This (showed up in test\PharLap.py.  The import should be moved to the
  top eventually, but would currently cause a circular error with imports
  that try to find merge_default_version() itself.
................
  r3938 | stevenknight | 2009-01-31 07:51:16 -0800 (Sat, 31 Jan 2009) | 2 lines

  Fix 80-char line wrap on imported variables.
................
  r3939 | stevenknight | 2009-01-31 08:00:44 -0800 (Sat, 31 Jan 2009) | 10 lines

  Fix the test\MSVS\vs-*-exec.py tests by restoring the old
  get__{default,}_visual_studio*() and get_msvs_install_dirs()
  functions to src/engine/SCons/Tool/msvs.py.  The last one
  is still used by the test infrastructure (specifically
  QMTest\TestSConsMSVS.py) to get the path to the visual studio
  executable (devenv.exe).  We can clean this up by removing
  these wrappers in favor of better interfaces directly from
  MSVCCommon, but I want to get the tests working first and
  then fine-tune the aesthetics.
................
  r3964 | stevenknight | 2009-02-05 06:51:32 -0800 (Thu, 05 Feb 2009) | 15 lines

  First stab at refactoring SDK detection:
  * Add a separate 'mssdk' tool to provide a direct interface to applying
    SDK information to a construction environment.  (Currently used by 'msvc'.)
  * Add support for $MSSDK_DIR and $MSSDK_VERSION variables to give the
    user explicit control over how to specify where to find an SDK.
  * Collect information about different possibly installed SDK versions (what
    sanity check file to use, what HKEY to look up) from being scattered in
    multiple lists to a common list of definitions, specified by concrete
    WindowsSDK and PlatformSDK subclasses of an abstract SDKDefinition
    base class.
  * Cache results of trying to find SDKs so we only have to go out to the
    registry and disk once, regardless of how many times we're asked.
  * Cache lists of variables to be appended so we only have to look for
    'mfc' and 'atl' subdirectories once.
................
  r3965 | stevenknight | 2009-02-05 19:34:25 -0800 (Thu, 05 Feb 2009) | 2 lines

  Fix name errors in my reworking of sdk searching.
................
  r3966 | stevenknight | 2009-02-05 21:34:19 -0800 (Thu, 05 Feb 2009) | 5 lines

  Fix get_output() to use the subprocess.Popen.std{out,err} attributes
  directly instead subprocess.Popen.communicate(), which uses the
  threading module and therefore won't work on Pythons not built with
  thread support.
................
  r3969 | stevenknight | 2009-02-06 08:38:57 -0800 (Fri, 06 Feb 2009) | 5 lines

  Fix some test errors on cygwin:
  * Generalize the expected error message(s) in Install.py
  * Make sure M4 is attached to all the environments.
  * Use the TestSCons.file_expr expression in PCHSTOP-errors.py
................
  r3971 | stevenknight | 2009-02-06 10:00:59 -0800 (Fri, 06 Feb 2009) | 2 lines

  Fix use of TestSCons.file_expr.
................
  r3972 | stevenknight | 2009-02-06 10:09:57 -0800 (Fri, 06 Feb 2009) | 2 lines

  Fixes for use of regular expressions with must_contain_all_lines().
................
  r3974 | stevenknight | 2009-02-06 10:37:40 -0800 (Fri, 06 Feb 2009) | 2 lines

  Update expected error string list for Cygwin.
................
  r3975 | stevenknight | 2009-02-06 10:41:38 -0800 (Fri, 06 Feb 2009) | 2 lines

  Relax the expected PCH speedup to 90% of the non-PCH compilation.
................
  r3976 | stevenknight | 2009-02-06 10:48:08 -0800 (Fri, 06 Feb 2009) | 2 lines

  Add skeleton of XML doc of new MSSDK_* variables.
................
  r3984 | garyo | 2009-02-08 08:51:52 -0800 (Sun, 08 Feb 2009) | 11 lines

  Fixes for some of the failing msvsTests.py tests on vs_revamp branch.

  CODE FIXES:
   * SCons/Util.py: removed extra trailing backslash from registry lookup.
   * Started on a path to handling vs 8.0 express in msvs.py, version.py, and common.py, but need feedback here.

  TEST FIXES:
   * Added a MSVS 8.0 std version test, since that's what's on my home machine.  I got the fake registry data by exporting my real registry subtree.
   * I changed the expected values of many of the tests to conform to what the code actually returns.  I think that's right, because it's using fake registry data anyway.
   * Tests now monkey-patch os.path.isfile and os.path.isdir to return true, just like os.path.exists already was.
   * Improved some test error reporting and added some debug logging.
................
  r3985 | stevenknight | 2009-02-08 19:58:23 -0800 (Sun, 08 Feb 2009) | 2 lines

  Re-fix use of file_expr, wiped out in last merge from trunk.
................
  r3986 | stevenknight | 2009-02-09 10:27:15 -0800 (Mon, 09 Feb 2009) | 2 lines

  Add emacs and vim editing settings to the bottom of vs_revamp *.py files.
................
  r3993 | stevenknight | 2009-02-11 05:00:55 -0800 (Wed, 11 Feb 2009) | 3 lines

  Separate error message for an SDK that's not supported, vs. one that's
  supported but not installed.
................
  r3994 | stevenknight | 2009-02-11 05:03:51 -0800 (Wed, 11 Feb 2009) | 2 lines

  Minor code cleanup.
................
  r3995 | stevenknight | 2009-02-11 05:04:40 -0800 (Wed, 11 Feb 2009) | 2 lines

  Link reference to $MSVS_VERSION.
................
  r4000 | stevenknight | 2009-02-12 18:51:30 -0800 (Thu, 12 Feb 2009) | 12 lines

  First cut at collecting the different version-specific logic from
  different modules and methods and putting it in a common MSVCCommon/vs.py
  module.  This also basically gets rid of the separation of "version" and
  "flavor" or "suite" arguments in favor of just treating Express as
  separate versions, and versions are now strings, not floats:  "8.0"
  and "8.0Exp".  (It's not like there's so much commonality between the
  Express and Pro versions that keeping things synchronized will be a burden.)

  This is only part way through absorbing the current API into the new
  scheme and getting rid of some now-unused functions, but should support
  testing from various people while that work proceeds.
................
  r4001 | stevenknight | 2009-02-12 20:40:14 -0800 (Thu, 12 Feb 2009) | 3 lines

  Add comments with the official Microsoft names of the different releases.
  (I can never remember the mapping of names to version numbers.)
................
  r4002 | stevenknight | 2009-02-12 20:41:55 -0800 (Thu, 12 Feb 2009) | 2 lines

  Fix some 80-char line wrap.
................
  r4012 | stevenknight | 2009-02-19 06:24:58 -0800 (Thu, 19 Feb 2009) | 3 lines

  Add a $MSVS_ARCH variable and support for 'amd64' in some of
  the supported Visual Studio versions.  (Roberto de Vecchi)
................
  r4013 | stevenknight | 2009-02-19 06:36:55 -0800 (Thu, 19 Feb 2009) | 2 lines

  Fetch the VisualStudio object using .get(), not .has_key().
................
  r4014 | stevenknight | 2009-02-19 06:53:31 -0800 (Thu, 19 Feb 2009) | 2 lines

  Start getting rid of unnecessary code.  Cosmetic cleanups.  Comments.
................
  r4015 | stevenknight | 2009-02-19 06:59:06 -0800 (Thu, 19 Feb 2009) | 2 lines

  Move query_versions() into MSVCCommon/vs.py.  Fix variable names.
................
  r4016 | stevenknight | 2009-02-19 07:27:01 -0800 (Thu, 19 Feb 2009) | 3 lines

  Get rid of MSVCCommon/misc.py and MSVCCommon/version.py, now that
  the necessary logic has been migrated to MSVCCommon/vs.py.
................
  r4017 | stevenknight | 2009-02-19 08:40:20 -0800 (Thu, 19 Feb 2009) | 2 lines

  Add trailing commas.
................
  r4018 | stevenknight | 2009-02-19 09:55:33 -0800 (Thu, 19 Feb 2009) | 3 lines

  Get rid of one-line wrappers in msvs.py in favor of direct testing
  of functions in MSVCCommon/*.py.
................
  r4019 | stevenknight | 2009-02-19 11:26:29 -0800 (Thu, 19 Feb 2009) | 3 lines

  Use consistent spelling of SystemDrive and SystemRoot for those
  environment variables.
................
  r4020 | stevenknight | 2009-02-19 13:36:05 -0800 (Thu, 19 Feb 2009) | 12 lines

  Get rid of msvs.get_msvs_install_dirs(), only used by the unit tests
  in msvsTests.py.
  Make get_vs_by_version() public.
  Update msvsTests.py with a rudimentary test for detect_msvs(),
  and get rid of the test for get_msvs_install_dirs().
  Remove MSVCCommon\findloc.py and MSVCCommon\defaults.py, no longer needed.
  Move contents of MSVCCommon\envhelpers.py to MSVCCommon\common.py to
  try to collect things, and remove MSVCCommon\envhelpers.py.
  Update QMTest\TestSConsMSVS.py to use the new vs infrastructure to find
  the appropriate executable (devenv.com, etc.).
  Update MANIFEST.in for the removed modules.
................
  r4021 | stevenknight | 2009-02-19 13:48:49 -0800 (Thu, 19 Feb 2009) | 3 lines

  Rename MSVCCommon to MSCommon so it's not tied too tightly to Visual C/C++
  (leaving the door a little more open for other Visual products).
................
  r4022 | stevenknight | 2009-02-19 13:54:55 -0800 (Thu, 19 Feb 2009) | 2 lines

  Change additional MSVCCommon references.
................

git-svn-id: http://scons.tigris.org/svn/scons/trunk@4029 fdb21ef1-2011-0410-befe-b5e4ea1792b1

33 files changed:
QMTest/TestSConsMSVS.py
doc/man/scons.1
src/CHANGES.txt
src/engine/MANIFEST-xml.in
src/engine/MANIFEST.in
src/engine/SCons/Errors.py
src/engine/SCons/Platform/PlatformTests.py
src/engine/SCons/Platform/win32.py
src/engine/SCons/Tool/MSCommon/TODO [new file with mode: 0644]
src/engine/SCons/Tool/MSCommon/__init__.py [new file with mode: 0644]
src/engine/SCons/Tool/MSCommon/common.py [new file with mode: 0644]
src/engine/SCons/Tool/MSCommon/msvc_changes.txt [new file with mode: 0644]
src/engine/SCons/Tool/MSCommon/netframework.py [new file with mode: 0644]
src/engine/SCons/Tool/MSCommon/sdk.py [new file with mode: 0644]
src/engine/SCons/Tool/MSCommon/vs.py [new file with mode: 0644]
src/engine/SCons/Tool/linkloc.py
src/engine/SCons/Tool/midl.py
src/engine/SCons/Tool/mslib.py
src/engine/SCons/Tool/mslink.py
src/engine/SCons/Tool/mssdk.py [new file with mode: 0644]
src/engine/SCons/Tool/mssdk.xml [new file with mode: 0644]
src/engine/SCons/Tool/msvc.py
src/engine/SCons/Tool/msvs.py
src/engine/SCons/Tool/msvs.xml
src/engine/SCons/Tool/msvsTests.py
src/engine/SCons/Util.py
src/setup.py
test/Delete.py
test/Install/Install.py
test/M4/M4.py
test/MSVC/PCHSTOP-errors.py
test/MSVC/msvc.py
test/MSVC/query_vcbat.py [new file with mode: 0644]

index 0408b6795858566fe179cfffa60c529a4825260b..8a85b3fb49312faa0c6022474a50879aa06c2645 100644 (file)
@@ -636,31 +636,12 @@ print "self._msvs_versions =", str(env['MSVS']['VERSIONS'])
         """Returns a full path to the executable (MSDEV or devenv)
         for the specified version of Visual Studio.
         """
-        common_msdev98_bin_msdev_com = ['Common', 'MSDev98', 'Bin', 'MSDEV.COM']
-        common7_ide_devenv_com       = ['Common7', 'IDE', 'devenv.com']
-        common7_ide_vcexpress_exe    = ['Common7', 'IDE', 'VCExpress.exe']
-        sub_paths = {
-            '6.0' : [
-                common_msdev98_bin_msdev_com,
-            ],
-            '7.0' : [
-                common7_ide_devenv_com,
-            ],
-            '7.1' : [
-                common7_ide_devenv_com,
-            ],
-            '8.0' : [
-                common7_ide_devenv_com,
-                common7_ide_vcexpress_exe,
-            ],
-        }
-        from SCons.Tool.msvs import get_msvs_install_dirs
-        vs_path = get_msvs_install_dirs(version)['VSINSTALLDIR']
-        for sp in sub_paths[version]:
-            p = apply(os.path.join, [vs_path] + sp)
-            if os.path.exists(p):
-                return p
-        return apply(os.path.join, [vs_path] + sub_paths[version][0])
+        from SCons.Tool.MSCommon import get_vs_by_version
+
+        msvs = get_vs_by_version(version)
+        if not msvs:
+            return None
+        return msvs.get_executable()
 
 # Local Variables:
 # tab-width:4
index ba515185b19e891a5af7371093d5fd1cbfbe3331..f3988f4a4de6425b50b656c71bd23be6d35140ca 100644 (file)
@@ -1776,6 +1776,7 @@ midl
 mingw
 mslib
 mslink
+mssdk
 msvc
 msvs
 mwcc
index 6d5aa37f17af151dec76e7ff10d4e6884278c5e0..cb7fe8c60540763adbadb0c2aea45ffca84558ec 100644 (file)
@@ -14,6 +14,15 @@ RELEASE X.X.X - XXX
 
     - Make suffix-matching for scanners case-insensitive on Windows.
 
+  From David Cournapeau:
+
+    - Change the way SCons finds versions of Visual C/C++ and Visual
+      Studio to find and use the Microsoft v*vars.bat files.
+
+  From Robert P. J. Day:
+
+    - User's Guide updates.
+
   From Dan Eaton:
 
     - Fix generation of Visual Studio 8 project files on x64 platforms.
@@ -42,10 +51,6 @@ RELEASE X.X.X - XXX
     - Spell the Windows environment variables consistently "SystemDrive"
       and "SystemRoot" instead of "SYSTEMDRIVE" and "SYSTEMROOT".
 
-  From Robert P. J. Day:
-
-    - User's Guide updates.
-
 
 
 RELEASE 1.2.0.d20090113 - Tue, 13 Jan 2009 02:50:30 -0800
index f852e92ec46eaa18b836d01f4d5faf057c2d8316..5a5c9b6df21dcf15bc74835805011d37f92ec2a4 100644 (file)
@@ -59,6 +59,7 @@ SCons/Tool/midl.xml
 SCons/Tool/mingw.xml
 SCons/Tool/mslib.xml
 SCons/Tool/mslink.xml
+SCons/Tool/mssdk.xml
 SCons/Tool/msvc.xml
 SCons/Tool/msvs.xml
 SCons/Tool/mwcc.xml
index 203c4d952b1eb41b8d4d25cb6db281aeeb74736f..ede98882bbbfe64e5c7788e2a360428fc8b5d3f8 100644 (file)
@@ -116,12 +116,18 @@ SCons/Tool/latex.py
 SCons/Tool/lex.py
 SCons/Tool/link.py
 SCons/Tool/linkloc.py
+SCons/Tool/MSCommon/__init__.py
+SCons/Tool/MSCommon/common.py
+SCons/Tool/MSCommon/netframework.py
+SCons/Tool/MSCommon/sdk.py
+SCons/Tool/MSCommon/vs.py
 SCons/Tool/m4.py
 SCons/Tool/masm.py
 SCons/Tool/midl.py
 SCons/Tool/mingw.py
 SCons/Tool/mslib.py
 SCons/Tool/mslink.py
+SCons/Tool/mssdk.py
 SCons/Tool/msvc.py
 SCons/Tool/msvs.py
 SCons/Tool/mwcc.py
index fc45279f4c52a3f0ce64864001ca345f4f1c784c..562cbcf9ed6edcafaa6767b8a43fb13491f921ee 100644 (file)
@@ -125,6 +125,9 @@ class StopError(Exception):
 class EnvironmentError(Exception):
     pass
 
+class MSVCError(IOError):
+    pass
+
 class ExplicitExit(Exception):
     def __init__(self, node=None, status=None, *args):
         self.node = node
index 4f2e3d93b7fd4ddcd230b654629708b192d06a8c..59d7e7154a195ffa8615fccba6aeab70af668c26 100644 (file)
@@ -33,6 +33,8 @@ import UserDict
 class Environment(UserDict.UserDict):
     def Detect(self, cmd):
         return cmd
+    def AppendENVPath(self, key, value):
+        pass
 
 class PlatformTestCase(unittest.TestCase):
     def test_Platform(self):
index 890b92583badec32ccb7cc1e481873f733b24689..fb23d5d8fcef62d04113d91329e7546501909790 100644 (file)
@@ -189,15 +189,16 @@ def escape(x):
     return '"' + x + '"'
 
 # Get the windows system directory name
+_system_root = None
+
 def get_system_root():
+    global _system_root
+    if _system_root is not None:
+        return _system_root
+
     # A resonable default if we can't read the registry
-    try:
-        val = os.environ['SystemRoot']
-    except KeyError:
-        val = "C:/WINDOWS"
-        pass
+    val = os.environ.get('SystemRoot', "C:/WINDOWS")
 
-    # First see if we can look in the registry...
     if SCons.Util.can_read_reg:
         try:
             # Look for Windows NT system root
@@ -214,6 +215,7 @@ def get_system_root():
                 raise
             except:
                 pass
+    _system_root = val
     return val
 
 # Get the location of the program files directory
@@ -267,9 +269,7 @@ def generate(env):
     # the env's PATH.  The problem with that is that it might not
     # contain an ENV and a PATH.
     if not cmd_interp:
-        systemroot = r'C:\Windows'
-        if os.environ.has_key('SystemRoot'):
-            systemroot = os.environ['SystemRoot']
+        systemroot = get_system_root()
         tmp_path = systemroot + os.pathsep + \
                    os.path.join(systemroot,'System32')
         tmp_pathext = '.com;.exe;.bat;.cmd'
@@ -302,6 +302,13 @@ def generate(env):
         if v:
             env['ENV'][var] = v
 
+    if not env['ENV'].has_key('COMSPEC'):
+        v = os.environ.get("COMSPEC")
+        if v:
+            env['ENV']['COMSPEC'] = v
+
+    env.AppendENVPath('PATH', get_system_root() + '\System32')
+
     env['ENV']['PATHEXT'] = '.COM;.EXE;.BAT;.CMD'
     env['OBJPREFIX']      = ''
     env['OBJSUFFIX']      = '.obj'
diff --git a/src/engine/SCons/Tool/MSCommon/TODO b/src/engine/SCons/Tool/MSCommon/TODO
new file mode 100644 (file)
index 0000000..be350b8
--- /dev/null
@@ -0,0 +1,5 @@
+Last Change: Fri Oct 17 04:00 PM 2008 J
+
+- Make sure VS 6 and VS 2003 .Net work (with their own SDK)
+- See whether current unit tests can be updated and need to be rewritten from
+  scratch
diff --git a/src/engine/SCons/Tool/MSCommon/__init__.py b/src/engine/SCons/Tool/MSCommon/__init__.py
new file mode 100644 (file)
index 0000000..a59bf15
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """
+Common functions for Microsoft Visual Studio and Visual C/C++.
+"""
+
+import copy
+import os
+import re
+import subprocess
+
+import SCons.Errors
+import SCons.Platform.win32
+import SCons.Util
+
+from SCons.Tool.MSCommon.vs import detect_msvs, \
+                                   get_default_version, \
+                                   get_vs_by_version, \
+                                   merge_default_version, \
+                                   query_versions
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/MSCommon/common.py b/src/engine/SCons/Tool/MSCommon/common.py
new file mode 100644 (file)
index 0000000..619b242
--- /dev/null
@@ -0,0 +1,177 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """
+Common helper functions for working with
+"""
+
+import copy
+import os
+import subprocess
+import re
+
+import SCons.Util
+
+# Uncomment to enable debug logging to your choice of file
+#import logging,os
+#os.unlink('c:/tmp/debug.log')
+#logging.basicConfig(filename='c:/tmp/debug.log', level=logging.DEBUG,)
+
+try:
+    from logging import debug
+except ImportError:
+    debug = lambda x : None
+
+#debug = lambda x : open('con', 'w').write(x + '\n')
+
+# TODO(sgk): unused
+def is_win64():
+    """Return true if running on windows 64 bits."""
+    # Unfortunately, python does not seem to have anything useful: neither
+    # sys.platform nor os.name gives something different on windows running on
+    # 32 bits or 64 bits. Note that we don't care about whether python itself
+    # is 32 or 64 bits here
+    value = "Software\Wow6432Node"
+    yo = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, value)[0]
+    if yo is None:
+        return 0
+    else:
+        return 1
+
+def read_reg(value):
+    return SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, value)[0]
+
+
+# Functions for fetching environment variable settings from batch files.
+
+def normalize_env(env, keys):
+    """Given a dictionary representing a shell environment, add the variables
+    from os.environ needed for the processing of .bat files; the keys are
+    controlled by the keys argument.
+
+    It also makes sure the environment values are correctly encoded.
+
+    Note: the environment is copied"""
+    normenv = {}
+    if env:
+        for k in env.keys():
+            normenv[k] = copy.deepcopy(env[k]).encode('mbcs')
+
+        for k in keys:
+            if os.environ.has_key(k):
+                normenv[k] = os.environ[k].encode('mbcs')
+
+    return normenv
+
+def get_output(vcbat, args = None, env = None):
+    """Parse the output of given bat file, with given args."""
+    if args:
+        debug("Calling '%s %s'" % (vcbat, args))
+        popen = subprocess.Popen('"%s" %s & set' % (vcbat, args),
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 env=env)
+    else:
+        debug("Calling '%s'" % vcbat)
+        popen = subprocess.Popen('"%s" & set' % vcbat,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 env=env)
+
+    # Use the .stdout and .stderr attributes directly because the
+    # .communicate() method uses the threading module on Windows
+    # and won't work under Pythons not built with threading.
+    stdout = popen.stdout.read()
+    if popen.wait() != 0:
+        raise IOError(popen.stderr.read().decode("mbcs"))
+
+    output = stdout.decode("mbcs")
+    return output
+
+def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")):
+    # dkeep is a dict associating key: path_list, where key is one item from
+    # keep, and pat_list the associated list of paths
+
+    # TODO(1.5):  replace with the following list comprehension:
+    #dkeep = dict([(i, []) for i in keep])
+    dkeep = dict(map(lambda i: (i, []), keep))
+
+    # rdk will  keep the regex to match the .bat file output line starts
+    rdk = {}
+    for i in keep:
+        rdk[i] = re.compile('%s=(.*)' % i, re.I)
+
+    def add_env(rmatch, key):
+        plist = rmatch.group(1).split(os.pathsep)
+        for p in plist:
+            # Do not add empty paths (when a var ends with ;)
+            if p:
+                p = p.encode('mbcs')
+                # XXX: For some reason, VC98 .bat file adds "" around the PATH
+                # values, and it screws up the environment later, so we strip
+                # it. 
+                p = p.strip('"')
+                dkeep[key].append(p)
+
+    for line in output.splitlines():
+        for k,v in rdk.items():
+            m = v.match(line)
+            if m:
+                add_env(m, k)
+
+    return dkeep
+
+# TODO(sgk): unused
+def output_to_dict(output):
+    """Given an output string, parse it to find env variables.
+
+    Return a dict where keys are variables names, and values their content"""
+    envlinem = re.compile(r'^([a-zA-z0-9]+)=([\S\s]*)$')
+    parsedenv = {}
+    for line in output.splitlines():
+        m = envlinem.match(line)
+        if m:
+            parsedenv[m.group(1)] = m.group(2)
+    return parsedenv
+
+# TODO(sgk): unused
+def get_new(l1, l2):
+    """Given two list l1 and l2, return the items in l2 which are not in l1.
+    Order is maintained."""
+
+    # We don't try to be smart: lists are small, and this is not the bottleneck
+    # is any case
+    new = []
+    for i in l2:
+        if i not in l1:
+            new.append(i)
+
+    return new
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/MSCommon/msvc_changes.txt b/src/engine/SCons/Tool/MSCommon/msvc_changes.txt
new file mode 100644 (file)
index 0000000..e6acaa8
--- /dev/null
@@ -0,0 +1,90 @@
+The Visual Studio support has been totally revamped. Instead of using registry
+magic, we use the .bat files available for each version of visual studio. This
+is simpler (does not depend on the version of the compiler), more reliable, and
+just plain better.
+
+Specification
+=============
+
+Tested versions
+---------------
+
+The following versions have been succesfully tested:
+  - VS 2008 (express), 32 bits
+  - VS 2005 (express), 32 bits
+  - VS 2003 (.Net, pro), 32 bits
+
+Detection
+---------
+
+All tools related to the ms toolchain are detected through the same method:
+  - detect the .bat configuration file (vsvarsall.bat/vsvars32.bat
+    depending on the version) from the registry
+  - if registry does not return anything useful, use the VS*COMNTOOLS env
+    variable.
+
+A version is detected only when the .bat file actually exists on the
+filesystem.  Once the .bat file is found, it is executed through a clean
+environment, and its output is parsed to get the variables
+PATH/LIB/LIBPATH/INCLUDE. Those variables are then added to env['ENV']
+
+By default, the most recent detected version is set, and can be queried in
+env['MSVS_VERSION'] *after* the tool initialization. The version can be forced
+by setting the MSVS_VERSION variable *before* initializing the tool.
+
+SDK
+---
+
+Separate SDKs are only supported for the following versions:
+        - Platform SDK 2003 R1 and R2
+        - Windows SDK. I tried the following versions: 6.0, 6.0A (SDK delivered
+          with VS 2008 express) and 6.1 (Windows SDK 2008).
+
+Previous SDKs are not available anymore on MS website, so I could not test
+them. I believe VS 6 has its own SDK included, as well as VS 2003 .Net. The SDK
+is set *after* the msvs tool.
+
+The version of the SDK can be controlled by the scons variable:
+
+    MSSDK_DIR:      If set, specifies the directory location of the
+                    SDK to be used.
+
+    MSSDK_VERSION:  If set, specifies the version of the SDK to be used.
+
+If neither of these is set, MSVS_VERSION is used to pick an appropriate
+default.
+
+Architecture
+------------
+
+env['MSVS_ARCH'] = 'x86'
+                   'amd64'
+
+If not set, the selection logic defaults to x86. Cross compiling has been
+disabled, filtering out values not included in version.SUPPORTED_ARCH.
+(No tests made with cross compiling.)
+
+Fundamental changes
+===================
+
+env["ENV"] has been expanded a bit on windows:
+  - add %SystemRoot%\system32 in the path for windows
+  - add COMSPEC (needed by the .bat file execution)
+
+Internals
+=========
+
+The code can be found in the MSVCCommon submodule:
+  - findloc: find the product dir from the registry or the shell environment
+        - versions: query the system for available versions of the VS suite on
+          the system
+        - misc: high level functions, *candidates* for the public API.
+        - sdk: specifics to the SDK detection.
+        - defaults: default values to use for the paths, to use instead of the
+          whole env parsing which can be quite slow, but less reliable. Still
+          experimental, may be removed
+  - envhelpers: functions to execute a VS .bat file, parse its output,
+    and get the variables with modified values.
+
+At this point, no function should be considered public, the exact API is not
+good yet.
diff --git a/src/engine/SCons/Tool/MSCommon/netframework.py b/src/engine/SCons/Tool/MSCommon/netframework.py
new file mode 100644 (file)
index 0000000..8fee916
--- /dev/null
@@ -0,0 +1,84 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """
+"""
+
+import os
+import re
+import string
+
+from common import read_reg, debug
+
+# Original value recorded by dcournapeau
+_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot'
+# On SGK's system
+_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\Microsoft SDKs\.NETFramework\v2.0\InstallationFolder'
+
+def find_framework_root():
+    # XXX: find it from environment (FrameworkDir)
+    try:
+        froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT)
+        debug("Found framework install root in registry: %s" % froot)
+    except WindowsError, e:
+        debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT)
+        return None
+
+    if not os.path.exists(froot):
+        debug("%s not found on fs" % froot)
+        return None
+
+    return froot
+
+def query_versions():
+    froot = find_framework_root()
+    if froot:
+        contents = os.listdir(froot)
+
+        l = re.compile('v[0-9]+.*')
+        versions = filter(lambda e, l=l: l.match(e), contents)
+
+        def versrt(a,b):
+            # since version numbers aren't really floats...
+            aa = a[1:]
+            bb = b[1:]
+            aal = string.split(aa, '.')
+            bbl = string.split(bb, '.')
+            # sequence comparison in python is lexicographical
+            # which is exactly what we want.
+            # Note we sort backwards so the highest version is first.
+            return cmp(bbl,aal)
+
+        versions.sort(versrt)
+    else:
+        versions = []
+
+    return versions
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/MSCommon/sdk.py b/src/engine/SCons/Tool/MSCommon/sdk.py
new file mode 100644 (file)
index 0000000..80e6852
--- /dev/null
@@ -0,0 +1,256 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """Module to detect the Platform/Windows SDK
+
+PSDK 2003 R1 is the earliest version detected.
+"""
+
+import os
+
+import SCons.Errors
+from SCons.Tool.MSCommon.common import debug, read_reg
+import SCons.Util
+
+# SDK Checks. This is of course a mess as everything else on MS platforms. Here
+# is what we do to detect the SDK:
+#
+# For Windows SDK >= 6.0: just look into the registry entries:
+#   HKLM\Software\Microsoft\Microsoft SDKs\Windows
+# All the keys in there are the available versions.
+#
+# For Platform SDK before 6.0 (2003 server R1 and R2, etc...), there does not
+# seem to be any sane registry key, so the precise location is hardcoded.
+#
+# For versions below 2003R1, it seems the PSDK is included with Visual Studio?
+#
+# Also, per the following:
+#     http://benjamin.smedbergs.us/blog/tag/atl/
+# VC++ Professional comes with the SDK, VC++ Express does not.
+
+# Location of the SDK (checked for 6.1 only)
+_CURINSTALLED_SDK_HKEY_ROOT = \
+        r"Software\Microsoft\Microsoft SDKs\Windows\CurrentInstallFolder"
+
+
+class SDKDefinition:
+    """
+    An abstract base class for trying to find installed SDK directories.
+    """
+    def __init__(self, version, **kw):
+        self.version = version
+        self.__dict__.update(kw)
+
+    def find_install_dir(self):
+        """Try to find the MS SDK from the registry.
+
+        Return None if failed or the directory does not exist.
+        """
+        if not SCons.Util.can_read_reg:
+            debug('SCons cannot read registry')
+            return None
+
+        hkey = self.HKEY_FMT % self.hkey_data
+
+        try:
+            install_dir = read_reg(hkey)
+            debug('Found sdk dir in registry: %s' % install_dir)
+        except WindowsError, e:
+            debug('Did not find sdk dir key %s in registry' % hkey)
+            return None
+
+        if not os.path.exists(install_dir):
+            debug('%s is not found on the filesystem' % install_dir)
+            return None
+
+        ftc = os.path.join(install_dir, self.sanity_check_file)
+        if not os.path.exists(ftc):
+            debug("File %s used for sanity check not found" % ftc)
+            return None
+
+        return install_dir
+
+    def get_install_dir(self):
+        """Return the MSSSDK given the version string."""
+        try:
+            return self._install_dir
+        except AttributeError:
+            install_dir = self.find_install_dir()
+            self._install_dir = install_dir
+            return install_dir
+
+class WindowsSDK(SDKDefinition):
+    """
+    A subclass for trying to find installed Windows SDK directories.
+    """
+    HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder'
+    def __init__(self, *args, **kw):
+        apply(SDKDefinition.__init__, (self,)+args, kw)
+        self.hkey_data = self.version
+
+class PlatformSDK(SDKDefinition):
+    """
+    A subclass for trying to find installed Platform SDK directories.
+    """
+    HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir'
+    def __init__(self, *args, **kw):
+        apply(SDKDefinition.__init__, (self,)+args, kw)
+        self.hkey_data = self.uuid
+
+# The list of support SDKs which we know how to detect.
+#
+# The first SDK found in the list is the one used by default if there
+# are multiple SDKs installed.  Barring good reasons to the contrary,
+# this means we should list SDKs with from most recent to oldest.
+#
+# If you update this list, update the documentation in Tool/mssdk.xml.
+SupportedSDKList = [
+    WindowsSDK('6.1',
+                sanity_check_file=r'include\windows.h'),
+
+    WindowsSDK('6.0A',
+               sanity_check_file=r'include\windows.h'),
+
+    WindowsSDK('6.0',
+               sanity_check_file=r'bin\gacutil.exe'),
+
+    PlatformSDK('2003R2',
+                sanity_check_file=r'SetEnv.Cmd',
+                uuid="D2FF9F89-8AA2-4373-8A31-C838BF4DBBE1"),
+
+    PlatformSDK('2003R1',
+                sanity_check_file=r'SetEnv.Cmd',
+                uuid="8F9E5EF3-A9A5-491B-A889-C58EFFECE8B3"),
+]
+
+SupportedSDKMap = {}
+for sdk in SupportedSDKList:
+    SupportedSDKMap[sdk.version] = sdk
+
+
+# Finding installed SDKs isn't cheap, because it goes not only to the
+# registry but also to the disk to sanity-check that there is, in fact,
+# an SDK installed there and that the registry entry isn't just stale.
+# Find this information once, when requested, and cache it.
+
+InstalledSDKList = None
+InstalledSDKMap = None
+
+def get_installed_sdks():
+    global InstalledSDKList
+    global InstalledSDKMap
+    if InstalledSDKList is None:
+        InstalledSDKList = []
+        InstalledSDKMap = {}
+        for sdk in SupportedSDKList:
+            if sdk.get_install_dir():
+                InstalledSDKList.append(sdk)
+                InstalledSDKMap[sdk.version] = sdk
+    return InstalledSDKList
+
+
+# We may be asked to update multiple construction environments with
+# SDK information.  When doing this, we check on-disk for whether
+# the SDK has 'mfc' and 'atl' subdirectories.  Since going to disk
+# is expensive, cache results by directory.
+
+SDKEnvironmentUpdates = {}
+
+def set_sdk_by_directory(env, sdk_dir):
+    global SDKEnvironmentUpdates
+    try:
+        env_tuple_list = SDKEnvironmentUpdates[sdk_dir]
+    except KeyError:
+        env_tuple_list = []
+        SDKEnvironmentUpdates[sdk_dir] = env_tuple_list
+
+        include_path = os.path.join(sdk_dir, 'include')
+        mfc_path = os.path.join(include_path, 'mfc')
+        atl_path = os.path.join(include_path, 'atl')
+
+        if os.path.exists(mfc_path):
+            env_tuple_list.append(('INCLUDE', mfc_path))
+        if os.path.exists(atl_path):
+            env_tuple_list.append(('INCLUDE', atl_path))
+        env_tuple_list.append(('INCLUDE', include_path))
+
+        env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib')))
+        env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib')))
+        env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin')))
+
+    for variable, directory in env_tuple_list:
+        env.PrependENVPath(variable, directory)
+
+
+# TODO(sgk):  currently unused; remove?
+def get_cur_sdk_dir_from_reg():
+    """Try to find the platform sdk directory from the registry.
+
+    Return None if failed or the directory does not exist"""
+    if not SCons.Util.can_read_reg:
+        debug('SCons cannot read registry')
+        return None
+
+    try:
+        val = read_reg(_CURINSTALLED_SDK_HKEY_ROOT)
+        debug("Found current sdk dir in registry: %s" % val)
+    except WindowsError, e:
+        debug("Did not find current sdk in registry")
+        return None
+
+    if not os.path.exists(val):
+        debug("Current sdk dir %s not on fs" % val)
+        return None
+
+    return val
+
+
+def detect_sdk():
+    return (len(get_installed_sdks()) > 0)
+
+def set_sdk_by_version(env, mssdk):
+    if not SupportedSDKMap.has_key(mssdk):
+        msg = "SDK version %s is not supported" % repr(mssdk)
+        raise SCons.Errors.UserError, msg
+    get_installed_sdks()
+    sdk = InstalledSDKMap.get(mssdk)
+    if not sdk:
+        msg = "SDK version %s is not installed" % repr(mssdk)
+        raise SCons.Errors.UserError, msg
+    set_sdk_by_directory(env, sdk.get_install_dir())
+
+def set_default_sdk(env, msver):
+    """Set up the default Platform/Windows SDK."""
+    # For MSVS < 8, use integrated windows sdk by default
+    if msver >= 8:
+        sdks = get_installed_sdks()
+        if len(sdks) > 0:
+            set_sdk_by_directory(env, sdks[0].get_install_dir())
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/MSCommon/vs.py b/src/engine/SCons/Tool/MSCommon/vs.py
new file mode 100644 (file)
index 0000000..a79d039
--- /dev/null
@@ -0,0 +1,496 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+__doc__ = """Module to detect Visual Studio and/or Visual C/C++
+"""
+
+import os
+
+import SCons.Errors
+import SCons.Util
+
+from SCons.Tool.MSCommon.common import debug, \
+                                       read_reg, \
+                                       normalize_env, \
+                                       get_output, \
+                                       parse_output
+
+class VisualStudio:
+    """
+    An abstract base class for trying to find installed versions of
+    Visual Studio.
+    """
+    def __init__(self, version, **kw):
+        self.version = version
+        self.__dict__.update(kw)
+        self._cache = {}
+
+    def batch_file_path(self):
+        pdir = self.get_vc_product_dir()
+        if not pdir:
+            return None
+        return os.path.join(pdir, self.batch_file)
+
+    def common_tools_path(self):
+        return os.environ.get(self.common_tools_var)
+
+    def vc_product_dir_path(self):
+        if not SCons.Util.can_read_reg:
+            debug('SCons can not read registry')
+            return None
+        key = self.hkey_root + '\\' + self.vc_product_dir_key
+        try:
+            comps = read_reg(key)
+        except WindowsError, e:
+            debug('Did not find product dir key %s in registry' % key)
+        else:
+            if self.batch_file_dir_reg_relpath:
+                comps = os.path.join(comps, self.batch_file_dir_reg_relpath)
+            if os.path.exists(comps):
+                return comps
+            debug('%s is not found on the file system' % comps)
+
+    #
+
+    def find_batch_file(self):
+        """Try to find the Visual Studio or Visual C/C++ batch file.
+
+        Return None if failed or the batch file does not exist.
+        """
+        pdir = self.get_vc_product_dir()
+        if not pdir:
+            debug('find_batch_file();  no pdir')
+            return None
+        batch_file = os.path.join(pdir, self.batch_file)
+        if not os.path.isfile(batch_file):
+            debug('%s file not on file system' % batch_file)
+            return None
+        return batch_file
+
+    def find_executable(self):
+        pdir = self.get_vc_product_dir()
+        if not pdir:
+            return None
+        executable = os.path.join(pdir, self.executable_path)
+        if not os.path.isfile(executable):
+            debug('%s file not on file system' % executable)
+            return None
+        return executable
+
+    def find_vc_product_dir(self):
+        if SCons.Util.can_read_reg:
+            key = self.hkey_root + '\\' + self.vc_product_dir_key
+            try:
+                comps = read_reg(key)
+            except WindowsError, e:
+                debug('Did not find product dir key %s in registry' % key)
+            else:
+                if self.batch_file_dir_reg_relpath:
+                    comps = os.path.join(comps, self.batch_file_dir_reg_relpath)
+                if os.path.exists(comps):
+                    return comps
+                debug('%s is not found on the file system' % comps)
+        else:
+            debug('SCons can not read registry')
+
+        d = os.environ.get(self.common_tools_var)
+        if d and os.path.isdir(d):
+            debug('%s found from %s' % (d, self.common_tools_var))
+            if self.batch_file_dir_env_relpath:
+                d = os.path.join(d, self.batch_file_dir_env_relpath)
+            return d
+        return None
+
+    #
+
+    def get_batch_file(self):
+        try:
+            return self._cache['batch_file']
+        except KeyError:
+            batch_file = self.find_batch_file()
+            self._cache['batch_file'] = batch_file
+            return batch_file
+
+    def get_executable(self):
+        try:
+            return self._cache['executable']
+        except KeyError:
+            executable = self.find_executable()
+            self._cache['executable'] = executable
+            return executable
+
+    def get_supported_arch(self):
+        try:
+            return self._cache['supported_arch']
+        except KeyError:
+            # RDEVE: for the time being use hardcoded lists
+            # supported_arch = self.find_supported_arch()
+            self._cache['supported_arch'] = self.supported_arch
+            return self.supported_arch
+
+    def get_vc_product_dir(self):
+        try:
+            return self._cache['vc_product_dir']
+        except KeyError:
+            vc_product_dir = self.find_vc_product_dir()
+            self._cache['vc_product_dir'] = vc_product_dir
+            return vc_product_dir
+
+    def reset(self):
+        self._cache = {}
+
+# The list of supported Visual Studio versions we know how to detect.
+#
+# How to look for .bat file ?
+#  - VS 2008 Express (x86):
+#     * from registry key productdir, gives the full path to vsvarsall.bat. In
+#     HKEY_LOCAL_MACHINE):
+#         Software\Microsoft\VCEpress\9.0\Setup\VC\productdir
+#     * from environmnent variable VS90COMNTOOLS: the path is then ..\..\VC
+#     relatively to the path given by the variable.
+#
+#  - VS 2008 Express (WoW6432: 32 bits on windows x64):
+#         Software\Wow6432Node\Microsoft\VCEpress\9.0\Setup\VC\productdir
+#
+#  - VS 2005 Express (x86):
+#     * from registry key productdir, gives the full path to vsvarsall.bat. In
+#     HKEY_LOCAL_MACHINE):
+#         Software\Microsoft\VCEpress\8.0\Setup\VC\productdir
+#     * from environmnent variable VS80COMNTOOLS: the path is then ..\..\VC
+#     relatively to the path given by the variable.
+#
+#  - VS 2005 Express (WoW6432: 32 bits on windows x64): does not seem to have a
+#  productdir ?
+#
+#  - VS 2003 .Net (pro edition ? x86):
+#     * from registry key productdir. The path is then ..\Common7\Tools\
+#     relatively to the key. The key is in HKEY_LOCAL_MACHINE):
+#         Software\Microsoft\VisualStudio\7.1\Setup\VC\productdir
+#     * from environmnent variable VS71COMNTOOLS: the path is the full path to
+#     vsvars32.bat
+#
+#  - VS 98 (VS 6):
+#     * from registry key productdir. The path is then Bin
+#     relatively to the key. The key is in HKEY_LOCAL_MACHINE):
+#         Software\Microsoft\VisualStudio\6.0\Setup\VC98\productdir
+#
+# The first version found in the list is the one used by default if
+# there are multiple versions installed.  Barring good reasons to
+# the contrary, this means we should list versions from most recent
+# to oldest.  Pro versions get listed before Express versions on the
+# assumption that, by default, you'd rather use the version you paid
+# good money for in preference to whatever Microsoft makes available
+# for free.
+#
+# If you update this list, update the documentation in Tool/msvs.xml.
+
+SupportedVSList = [
+    # Visual Studio 2010
+    # TODO: find the settings, perhaps from someone with a CTP copy?
+    #VisualStudio('TBD',
+    #             hkey_root=r'TBD',
+    #             common_tools_var='TBD',
+    #             batch_file='TBD',
+    #             vc_product_dir_key=r'TBD',
+    #             batch_file_dir_reg_relpath=None,
+    #             batch_file_dir_env_relpath=r'TBD',
+    #             executable_path=r'TBD',
+    #             default_dirname='TBD',
+    #),
+
+    # Visual Studio 2008
+    VisualStudio('9.0',
+                 hkey_root=r'Software\Microsoft\VisualStudio\9.0',
+                 common_tools_var='VS90COMNTOOLS',
+                 batch_file='vcvarsall.bat',
+                 vc_product_dir_key=r'Setup\VC\ProductDir',
+                 batch_file_dir_reg_relpath=None,
+                 batch_file_dir_env_relpath=r'..\..\VC',
+                 executable_path=r'..\Common7\IDE\devenv.com',
+                 default_dirname='Microsoft Visual Studio 9',
+                 supported_arch=['x86', 'amd64'],
+    ),
+
+    # Visual C++ 2008 Express Edition
+    VisualStudio('9.0Exp',
+                 hkey_root=r'Software\Microsoft\VisualStudio\9.0',
+                 common_tools_var='VS90COMNTOOLS',
+                 batch_file='vcvarsall.bat',
+                 vc_product_dir_key=r'Setup\VC\ProductDir',
+                 batch_file_dir_reg_relpath=None,
+                 batch_file_dir_env_relpath=r'..\..\VC',
+                 executable_path=r'..\Common7\IDE\VCExpress.exe',
+                 default_dirname='Microsoft Visual Studio 9',
+                 supported_arch=['x86'],
+    ),
+
+    # Visual Studio 2005
+    VisualStudio('8.0',
+                 hkey_root=r'Software\Microsoft\VisualStudio\8.0',
+                 common_tools_var='VS80COMNTOOLS',
+                 batch_file='vcvarsall.bat',
+                 vc_product_dir_key=r'Setup\VC\ProductDir',
+                 batch_file_dir_reg_relpath=None,
+                 batch_file_dir_env_relpath=r'..\..\VC',
+                 executable_path=r'..\Common7\IDE\devenv.com',
+                 default_dirname='Microsoft Visual Studio 8',
+                 supported_arch=['x86', 'amd64'],
+    ),
+
+    # Visual C++ 2005 Express Edition
+    VisualStudio('8.0Exp',
+                 hkey_root=r'Software\Microsoft\VCExpress\8.0',
+                 common_tools_var='VS80COMNTOOLS',
+                 batch_file='vcvarsall.bat',
+                 vc_product_dir_key=r'Setup\VC\ProductDir',
+                 batch_file_dir_reg_relpath=None,
+                 batch_file_dir_env_relpath=r'..\..\VC',
+                 executable_path=r'..\Common7\IDE\VCExpress.exe',
+                 default_dirname='Microsoft Visual Studio 8',
+                 supported_arch=['x86'],
+    ),
+
+    # Visual Studio .NET 2003
+    VisualStudio('7.1',
+                 hkey_root=r'Software\Microsoft\VisualStudio\7.1',
+                 common_tools_var='VS71COMNTOOLS',
+                 batch_file='vsvars32.bat',
+                 vc_product_dir_key=r'Setup\VC\ProductDir',
+                 batch_file_dir_reg_relpath=r'..\Common7\Tools',
+                 batch_file_dir_env_relpath=None,
+                 executable_path=r'..\Common7\IDE\devenv.com',
+                 default_dirname='Microsoft Visual Studio .NET',
+                 supported_arch=['x86'],
+    ),
+
+    # Visual Studio .NET
+    VisualStudio('7.0',
+                 hkey_root=r'Software\Microsoft\VisualStudio\7.0',
+                 common_tools_var='VS70COMNTOOLS',
+                 batch_file='vsvars32.bat',
+                 vc_product_dir_key=r'Setup\VC\ProductDir',
+                 batch_file_dir_reg_relpath=r'..\Common7\Tools',
+                 batch_file_dir_env_relpath=None,
+                 executable_path=r'..\Common7\IDE\devenv.com',
+                 default_dirname='Microsoft Visual Studio .NET',
+                 supported_arch=['x86'],
+    ),
+
+    # Visual Studio 6.0
+    VisualStudio('6.0',
+                 hkey_root=r'Software\Microsoft\VisualStudio\6.0',
+                 common_tools_var='VS60COMNTOOLS',
+                 batch_file='vcvars32.bat',
+                 vc_product_dir_key='Setup\Microsoft Visual C++\ProductDir',
+                 batch_file_dir_reg_relpath='Bin',
+                 batch_file_dir_env_relpath=None,
+                 executable_path=r'Common\MSDev98\Bin\MSDEV.COM',
+                 default_dirname='Microsoft Visual Studio',
+                 supported_arch=['x86'],
+    ),
+]
+
+SupportedVSMap = {}
+for vs in SupportedVSList:
+    SupportedVSMap[vs.version] = vs
+
+
+# Finding installed versions of Visual Studio isn't cheap, because it
+# goes not only to the registry but also to the disk to sanity-check
+# that there is, in fact, a Visual Studio directory there and that the
+# registry entry isn't just stale.  Find this information once, when
+# requested, and cache it.
+
+InstalledVSList = None
+InstalledVSMap = None
+
+def get_installed_visual_studios():
+    global InstalledVSList
+    global InstalledVSMap
+    if InstalledVSList is None:
+        InstalledVSList = []
+        InstalledVSMap = {}
+        for vs in SupportedVSList:
+            debug('trying to find %s' % vs.version)
+            if vs.get_batch_file():
+                debug('found %s' % vs.version)
+                InstalledVSList.append(vs)
+                InstalledVSMap[vs.version] = vs
+    return InstalledVSList
+
+def reset_installed_visual_studios():
+    global InstalledVSList
+    global InstalledVSMap
+    InstalledVSList = None
+    InstalledVSMap = None
+    for vs in SupportedVSList:
+        vs.reset()
+
+
+# We may be asked to update multiple construction environments with
+# SDK information.  When doing this, we check on-disk for whether
+# the SDK has 'mfc' and 'atl' subdirectories.  Since going to disk
+# is expensive, cache results by directory.
+
+#SDKEnvironmentUpdates = {}
+#
+#def set_sdk_by_directory(env, sdk_dir):
+#    global SDKEnvironmentUpdates
+#    try:
+#        env_tuple_list = SDKEnvironmentUpdates[sdk_dir]
+#    except KeyError:
+#        env_tuple_list = []
+#        SDKEnvironmentUpdates[sdk_dir] = env_tuple_list
+#
+#        include_path = os.path.join(sdk_dir, 'include')
+#        mfc_path = os.path.join(include_path, 'mfc')
+#        atl_path = os.path.join(include_path, 'atl')
+#
+#        if os.path.exists(mfc_path):
+#            env_tuple_list.append(('INCLUDE', mfc_path))
+#        if os.path.exists(atl_path):
+#            env_tuple_list.append(('INCLUDE', atl_path))
+#        env_tuple_list.append(('INCLUDE', include_path))
+#
+#        env_tuple_list.append(('LIB', os.path.join(sdk_dir, 'lib')))
+#        env_tuple_list.append(('LIBPATH', os.path.join(sdk_dir, 'lib')))
+#        env_tuple_list.append(('PATH', os.path.join(sdk_dir, 'bin')))
+#
+#    for variable, directory in env_tuple_list:
+#        env.PrependENVPath(variable, directory)
+
+def detect_msvs():
+    return (len(get_installed_visual_studios()) > 0)
+
+def get_vs_by_version(msvs):
+    if not SupportedVSMap.has_key(msvs):
+        msg = "Visual Studio version %s is not supported" % repr(msvs)
+        raise SCons.Errors.UserError, msg
+    get_installed_visual_studios()
+    vs = InstalledVSMap.get(msvs)
+    # Some check like this would let us provide a useful error message
+    # if they try to set a Visual Studio version that's not installed.
+    # However, we also want to be able to run tests (like the unit
+    # tests) on systems that don't, or won't ever, have it installed.
+    # It might be worth resurrecting this, with some configurable
+    # setting that the tests can use to bypass the check.
+    #if not vs:
+    #    msg = "Visual Studio version %s is not installed" % repr(msvs)
+    #    raise SCons.Errors.UserError, msg
+    return vs
+
+def get_default_version(env):
+    """Returns the default version string to use for MSVS.
+
+    If no version was requested by the user through the MSVS environment
+    variable, query all the available the visual studios through
+    query_versions, and take the highest one.
+
+    Return
+    ------
+    version: str
+        the default version.
+    """
+    if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
+        # TODO(1.5):
+        #versions = [vs.version for vs in get_installed_visual_studios()]
+        versions = map(lambda vs: vs.version, get_installed_visual_studios())
+        env['MSVS'] = {'VERSIONS' : versions}
+    else:
+        versions = env['MSVS'].get('VERSIONS', [])
+
+    if not env.has_key('MSVS_VERSION'):
+        if versions:
+            env['MSVS_VERSION'] = versions[0] #use highest version by default
+        else:
+            env['MSVS_VERSION'] = SupportedVSList[0].version
+
+    env['MSVS']['VERSION'] = env['MSVS_VERSION']
+
+    return env['MSVS_VERSION']
+
+def get_default_arch(env):
+    """Return the default arch to use for MSVS
+
+    if no version was requested by the user through the MSVS_ARCH environment
+    variable, select x86
+
+    Return
+    ------
+    arch: str
+    """
+    arch = env.get('MSVS_ARCH', 'x86')
+
+    msvs = InstalledVSMap.get(env['MSVS_VERSION'])
+
+    if not msvs:
+        arch = 'x86'
+    elif not arch in msvs.get_supported_arch():
+        fmt = "Visual Studio version %s does not support architecture %s"
+        raise SCons.Errors.UserError, fmt % (env['MSVS_VERSION'], arch)
+
+    return arch
+
+def merge_default_version(env):
+    version = get_default_version(env)
+    arch = get_default_arch(env)
+
+    msvs = get_vs_by_version(version)
+    if msvs is None:
+        return
+    batfilename = msvs.get_batch_file()
+
+    # XXX: I think this is broken. This will silently set a bogus tool instead
+    # of failing, but there is no other way with the current scons tool
+    # framework
+    if batfilename is not None:
+
+        vars = ('LIB', 'LIBPATH', 'PATH', 'INCLUDE')
+
+        msvs_list = get_installed_visual_studios()
+        # TODO(1.5):
+        #vscommonvarnames = [ vs.common_tools_var for vs in msvs_list ]
+        vscommonvarnames = map(lambda vs: vs.common_tools_var, msvs_list)
+        nenv = normalize_env(env['ENV'], vscommonvarnames + ['COMSPEC'])
+        output = get_output(batfilename, arch, env=nenv)
+        vars = parse_output(output, vars)
+
+        for k, v in vars.items():
+            env.PrependENVPath(k, v, delete_existing=1)
+
+def query_versions():
+    """Query the system to get available versions of VS. A version is
+    considered when a batfile is found."""
+    msvs_list = get_installed_visual_studios()
+    # TODO(1.5)
+    #versions = [ msvs.version for msvs in msvs_list ]
+    versions = map(lambda msvs:  msvs.version, msvs_list)
+    return versions
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
index 43eb953aea4497e4afc49cbc5b4582ef5ead8934..3aeb693ff8c81fc96e4042de5794affd7af11dae 100644 (file)
@@ -43,7 +43,7 @@ import SCons.Errors
 import SCons.Tool
 import SCons.Util
 
-from SCons.Tool.msvc import get_msvc_paths
+from SCons.Tool.MSCommon import detect_msvs, merge_default_version
 from SCons.Tool.PharLapCommon import addPharLapPaths
 
 _re_linker_command = re.compile(r'(\s)@\s*([^\s]+)')
@@ -94,15 +94,16 @@ def generate(env):
     env['LIBLINKPREFIX']='-lib '
     env['LIBLINKSUFFIX']='$LIBSUFFIX'
 
-    msvs_version = env.get('MSVS_VERSION')
-    include_path, lib_path, exe_path = get_msvc_paths(env, version = msvs_version)
-    env['ENV']['LIB'] = lib_path
-    env.PrependENVPath('PATH', exe_path)
+    # Set-up ms tools paths for default version
+    merge_default_version(env)
 
     addPharLapPaths(env)
 
 def exists(env):
-    return env.Detect('linkloc')
+    if detect_msvs():
+        return env.Detect('linkloc')
+    else:
+        return 0
 
 # Local Variables:
 # tab-width:4
index 8347bc1c7f2c0cb4557663b7e6977b38709f6242..441f8842bf4c3ca18821db3a4aea2adb56f788be 100644 (file)
@@ -41,6 +41,8 @@ import SCons.Defaults
 import SCons.Scanner.IDL
 import SCons.Util
 
+from MSCommon import detect_msvs
+
 def midl_emitter(target, source, env):
     """Produces a list of outputs from the MIDL compiler"""
     base, ext = SCons.Util.splitext(str(target[0]))
@@ -79,15 +81,7 @@ def generate(env):
     env['BUILDERS']['TypeLibrary'] = midl_builder
 
 def exists(env):
-    if not env['PLATFORM'] in ('win32', 'cygwin'):
-        return 0
-
-    import SCons.Tool.msvs
-    if SCons.Tool.msvs.is_msvs_installed():
-        # there's at least one version of MSVS installed, which comes with midl:
-        return 1
-    else:
-        return env.Detect('midl')
+    return detect_msvs()
 
 # Local Variables:
 # tab-width:4
index dcb57fa1e698637f48b3aefb6a02a68f00f94230..d23f63bb3b7ccb05506871ba8f074384c8a8d7f6 100644 (file)
@@ -39,23 +39,14 @@ import SCons.Tool.msvs
 import SCons.Tool.msvc
 import SCons.Util
 
+from MSCommon import detect_msvs, merge_default_version
+
 def generate(env):
     """Add Builders and construction variables for lib to an Environment."""
     SCons.Tool.createStaticLibBuilder(env)
 
-    try:
-        version = SCons.Tool.msvs.get_default_visualstudio_version(env)
-
-        if env.has_key('MSVS_IGNORE_IDE_PATHS') and env['MSVS_IGNORE_IDE_PATHS']:
-            include_path, lib_path, exe_path = SCons.Tool.msvc.get_msvc_default_paths(env,version)
-        else:
-            include_path, lib_path, exe_path = SCons.Tool.msvc.get_msvc_paths(env,version)
-
-        # since other tools can set this, we just make sure that the
-        # relevant stuff from MSVS is in there somewhere.
-        env.PrependENVPath('PATH', exe_path)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        pass
+    # Set-up ms tools paths for default version
+    merge_default_version(env)
 
     env['AR']          = 'lib'
     env['ARFLAGS']     = SCons.Util.CLVar('/nologo')
@@ -64,16 +55,7 @@ def generate(env):
     env['LIBSUFFIX']   = '.lib'
 
 def exists(env):
-    try:
-        v = SCons.Tool.msvs.get_visualstudio_versions()
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        pass
-
-    if not v:
-        return env.Detect('lib')
-    else:
-        # there's at least one version of MSVS installed.
-        return 1
+    return detect_msvs()
 
 # Local Variables:
 # tab-width:4
index 2a2ec05b39d55ce18178701aab372ad03da5ddb2..d2089d32e3761fab68d839e8d69c6b7236270464 100644 (file)
@@ -44,6 +44,8 @@ import SCons.Tool.msvc
 import SCons.Tool.msvs
 import SCons.Util
 
+from MSCommon import merge_default_version, detect_msvs
+
 def pdbGenerator(env, target, source, for_signature):
     try:
         return ['/PDB:%s' % target[0].attributes.pdb, '/DEBUG']
@@ -236,21 +238,8 @@ def generate(env):
     env['REGSVRFLAGS'] = '/s '
     env['REGSVRCOM'] = '$REGSVR $REGSVRFLAGS ${TARGET.windows}'
 
-    try:
-        version = SCons.Tool.msvs.get_default_visualstudio_version(env)
-
-        if env.has_key('MSVS_IGNORE_IDE_PATHS') and env['MSVS_IGNORE_IDE_PATHS']:
-            include_path, lib_path, exe_path = SCons.Tool.msvc.get_msvc_default_paths(env,version)
-        else:
-            include_path, lib_path, exe_path = SCons.Tool.msvc.get_msvc_paths(env,version)
-
-        # since other tools can set these, we just make sure that the
-        # relevant stuff from MSVS is in there somewhere.
-        env.PrependENVPath('INCLUDE', include_path)
-        env.PrependENVPath('LIB', lib_path)
-        env.PrependENVPath('PATH', exe_path)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        pass
+    # Set-up ms tools paths for default version
+    merge_default_version(env)
 
     # Loadable modules are on Windows the same as shared libraries, but they
     # are subject to different build parameters (LDMODULE* variables).
@@ -267,17 +256,7 @@ def generate(env):
     env['LDMODULECOM'] = compositeLdmodAction
 
 def exists(env):
-    platform = env.get('PLATFORM', '')
-    if SCons.Tool.msvs.is_msvs_installed():
-        # there's at least one version of MSVS installed.
-        return 1
-    elif platform in ('win32', 'cygwin'):
-        # Only explicitly search for a 'link' executable on Windows
-        # systems.  Some other systems (e.g. Ubuntu Linux) have an
-        # executable named 'link' and we don't want that to make SCons
-        # think Visual Studio is installed.
-        return env.Detect('link')
-    return None
+    return detect_msvs()
 
 # Local Variables:
 # tab-width:4
diff --git a/src/engine/SCons/Tool/mssdk.py b/src/engine/SCons/Tool/mssdk.py
new file mode 100644 (file)
index 0000000..652a0c2
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+"""engine.SCons.Tool.mssdk
+
+Tool-specific initialization for Microsoft SDKs, both Platform
+SDKs and Windows SDKs.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+"""
+
+from SCons.Tool.MSCommon.sdk import detect_sdk, \
+                                    set_default_sdk, \
+                                    set_sdk_by_directory, \
+                                    set_sdk_by_version
+
+def generate(env):
+    """Add construction variables for an MS SDK to an Environment."""
+    if env.has_key('MSSDK_DIR'):
+        set_sdk_by_directory(env, env.subst('$MSSDK_DIR'))
+        return
+
+    if env.has_key('MSSDK_VERSION'):
+        set_sdk_by_version(env, env.subst('$MSSDK_VERSION'))
+        return
+
+    if env.has_key('MSVS_VERSION'):
+        set_default_sdk(env, env['MSVS_VERSION'])
+
+    #print "No MSVS_VERSION: this is likely to be a bug"
+    return
+
+def exists(env):
+    return detect_sdk()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4:
diff --git a/src/engine/SCons/Tool/mssdk.xml b/src/engine/SCons/Tool/mssdk.xml
new file mode 100644 (file)
index 0000000..bdfd394
--- /dev/null
@@ -0,0 +1,50 @@
+<!--
+__COPYRIGHT__
+
+This file is processed by the bin/SConsDoc.py module.
+See its __doc__ string for a discussion of the format.
+-->
+<tool name="mssdk">
+<summary>
+Sets variables for Microsoft Platform SDK and/or Windows SDK.
+Note that unlike most other Tool modules,
+mssdk does not set construction variables,
+but sets the <emphasis>environment variables</emphasis>
+in the environment &SCons; uses to execute
+the Microsoft toolchain:
+<literal>%INCLUDE%</literal>,
+<literal>%LIB%</literal>,
+<literal>%LIBPATH%</literal> and
+<literal>%PATH%</literal>.
+</summary>
+<sets>
+</sets>
+<uses>
+MSSDK_DIR
+MSSDK_VERSION
+MSVS_VERSION
+</uses>
+</tool>
+
+<cvar name="MSSDK_DIR">
+<summary>
+The directory containing the Microsoft SDK
+(either Platform SDK or Windows SDK)
+to be used for compilation.
+</summary>
+</cvar>
+
+<cvar name="MSSDK_VERSION">
+<summary>
+The version string of the Microsoft SDK
+(either Platform SDK or Windows SDK)
+to be used for compilation.
+Supported versions include
+<literal>6.1</literal>,
+<literal>6.0A</literal>,
+<literal>6.0</literal>,
+<literal>2003R2</literal>
+and 
+<literal>2003R1</literal>.
+</summary>
+</cvar>
index 443e8b0225eec1a8201d1b7add13bd130e369236..e68f9829523c8ee743a950c4fc0da93ca2813a3f 100644 (file)
@@ -36,6 +36,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
 import os.path
 import re
 import string
+import sys
 
 import SCons.Action
 import SCons.Builder
@@ -47,567 +48,11 @@ import SCons.Util
 import SCons.Warnings
 import SCons.Scanner.RC
 
+from MSCommon import merge_default_version, detect_msvs
+
 CSuffixes = ['.c', '.C']
 CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++']
 
-def _parse_msvc7_overrides(version,platform):
-    """ Parse any overridden defaults for MSVS directory locations
-    in MSVS .NET. """
-
-    # First, we get the shell folder for this user:
-    if not SCons.Util.can_read_reg:
-        raise SCons.Errors.InternalError, "No Windows registry module was found"
-
-    comps = ""
-    try:
-        (comps, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
-                                            r'Software\Microsoft\Windows\CurrentVersion' +\
-                                            r'\Explorer\Shell Folders\Local AppData')
-    except SCons.Util.RegError:
-        raise SCons.Errors.InternalError, \
-              "The Local AppData directory was not found in the registry."
-
-    comps = comps + '\\Microsoft\\VisualStudio\\' + version + '\\VCComponents.dat'
-    dirs = {}
-
-    if os.path.exists(comps):
-        # now we parse the directories from this file, if it exists.
-        # We only look for entries after:
-        # [VC\VC_OBJECTS_PLATFORM_INFO\Win32\Directories],
-        # since this file could contain a number of things...
-        lines = None
-        try:
-            import codecs
-        except ImportError:
-            pass
-        else:
-            try:
-                f = codecs.open(comps, 'r', 'utf16')
-                encoder = codecs.getencoder('ascii')
-                lines = map(lambda l, e=encoder: e(l)[0], f.readlines())
-            except (LookupError, UnicodeError):
-                lines = codecs.open(comps, 'r', 'utf8').readlines()
-        if lines is None:
-            lines = open(comps, 'r').readlines()
-        if 'x86' == platform: platform = 'Win32'
-
-        found = 0
-        for line in lines:
-            line.strip()
-            if line.find(r'[VC\VC_OBJECTS_PLATFORM_INFO\%s\Directories]'%platform) >= 0:
-                found = 1
-            elif line == '' or line[:1] == '[':
-                found = 0
-            elif found == 1:
-                kv = line.split('=', 1)
-                if len(kv) == 2:
-                    (key, val) = kv
-                key = key.replace(' Dirs','')
-                dirs[key.upper()] = val
-        f.close()
-    else:
-        # since the file didn't exist, we have only the defaults in
-        # the registry to work with.
-
-        if 'x86' == platform: platform = 'Win32'
-
-        try:
-            K = 'SOFTWARE\\Microsoft\\VisualStudio\\' + version
-            K = K + r'\VC\VC_OBJECTS_PLATFORM_INFO\%s\Directories'%platform
-            k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,K)
-            i = 0
-            while 1:
-                try:
-                    (key,val,t) = SCons.Util.RegEnumValue(k,i)
-                    key = key.replace(' Dirs','')
-                    dirs[key.upper()] = val
-                    i = i + 1
-                except SCons.Util.RegError:
-                    break
-        except SCons.Util.RegError:
-            # if we got here, then we didn't find the registry entries:
-            raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
-    return dirs
-
-def _parse_msvc8_overrides(version,platform,suite):
-    """ Parse any overridden defaults for MSVC directory locations
-    in MSVC 2005. """
-
-    # In VS8 the user can change the location of the settings file that
-    # contains the include, lib and binary paths. Try to get the location
-    # from registry
-    if not SCons.Util.can_read_reg:
-        raise SCons.Errors.InternalError, "No Windows registry module was found"
-
-    # XXX This code assumes anything that isn't EXPRESS uses the default
-    # registry key string.  Is this really true for all VS suites?
-    if suite == 'EXPRESS':
-        s = '\\VCExpress\\'
-    else:
-        s = '\\VisualStudio\\'
-
-    settings_path = ""
-    try:
-        (settings_path, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
-                                                    r'Software\Microsoft' + s + version +\
-                                                    r'\Profile\AutoSaveFile')
-        settings_path = settings_path.upper()
-    except SCons.Util.RegError:
-        raise SCons.Errors.InternalError, \
-              "The VS8 settings file location was not found in the registry."
-
-    # Look for potential environment variables in the settings path
-    if settings_path.find('%VSSPV_VISUALSTUDIO_DIR%') >= 0:
-        # First replace a special variable named %vsspv_visualstudio_dir%
-        # that is not found in the OSs environment variables...
-        try:
-            (value, t) = SCons.Util.RegGetValue(SCons.Util.HKEY_CURRENT_USER,
-                                                r'Software\Microsoft' + s + version +\
-                                                r'\VisualStudioLocation')
-            settings_path = settings_path.replace('%VSSPV_VISUALSTUDIO_DIR%', value)
-        except SCons.Util.RegError:
-            raise SCons.Errors.InternalError, "The VS8 settings file location was not found in the registry."
-
-    if settings_path.find('%') >= 0:
-        # Collect global environment variables
-        env_vars = {}
-
-        # Read all the global environment variables of the current user
-        k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_CURRENT_USER, r'Environment')
-        i = 0
-        while 1:
-            try:
-                (key,val,t) = SCons.Util.RegEnumValue(k,i)
-                env_vars[key.upper()] = val.upper()
-                i = i + 1
-            except SCons.Util.RegError:
-                break
-
-        # And some more variables that are not found in the registry
-        env_vars['USERPROFILE'] = os.getenv('USERPROFILE')
-        env_vars['SystemDrive'] = os.getenv('SystemDrive')
-
-        found_var = 1
-        while found_var:
-            found_var = 0
-            for env_var in env_vars:
-                if settings_path.find(r'%' + env_var + r'%') >= 0:
-                    settings_path = settings_path.replace(r'%' + env_var + r'%', env_vars[env_var])
-                    found_var = 1
-
-    dirs = {}
-
-    if os.path.exists(settings_path):
-        # now we parse the directories from this file, if it exists.
-        import xml.dom.minidom
-        doc = xml.dom.minidom.parse(settings_path)
-        user_settings = doc.getElementsByTagName('UserSettings')[0]
-        tool_options = user_settings.getElementsByTagName('ToolsOptions')[0]
-        tool_options_categories = tool_options.getElementsByTagName('ToolsOptionsCategory')
-        environment_var_map = {
-            'IncludeDirectories' : 'INCLUDE',
-            'LibraryDirectories' : 'LIBRARY',
-            'ExecutableDirectories' : 'PATH',
-        }
-        for category in tool_options_categories:
-            category_name = category.attributes.get('name')
-            if category_name is not None and category_name.value == 'Projects':
-                subcategories = category.getElementsByTagName('ToolsOptionsSubCategory')
-                for subcategory in subcategories:
-                    subcategory_name = subcategory.attributes.get('name')
-                    if subcategory_name is not None and subcategory_name.value == 'VCDirectories':
-                        properties = subcategory.getElementsByTagName('PropertyValue')
-                        for property in properties:
-                            property_name = property.attributes.get('name')
-                            if property_name is None:
-                                continue
-                            var_name = environment_var_map.get(property_name)
-                            if var_name:
-                                data = property.childNodes[0].data
-                                value_list = string.split(data, '|')
-                                if len(value_list) == 1:
-                                    dirs[var_name] = value_list[0]
-                                else:
-                                    while value_list:
-                                        dest, value = value_list[:2]
-                                        del value_list[:2]
-                                        # ToDo: Support for destinations
-                                        # other than Win32
-                                        if dest == 'Win32':
-                                            dirs[var_name] = value
-                                            break
-    else:
-        # There are no default directories in the registry for VS8 Express :(
-        raise SCons.Errors.InternalError, "Unable to find MSVC paths in the registry."
-    return dirs
-
-def _get_msvc7_path(path, version, platform):
-    """
-    Get Visual Studio directories from version 7 (MSVS .NET)
-    (it has a different registry structure than versions before it)
-    """
-    # first, look for a customization of the default values in the
-    # registry: These are sometimes stored in the Local Settings area
-    # for Visual Studio, in a file, so we have to parse it.
-    dirs = _parse_msvc7_overrides(version,platform)
-
-    if dirs.has_key(path):
-        p = dirs[path]
-    else:
-        raise SCons.Errors.InternalError, \
-              "Unable to retrieve the %s path from MS VC++."%path
-
-    # collect some useful information for later expansions...
-    paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
-
-    # expand the directory path variables that we support.  If there
-    # is a variable we don't support, then replace that entry with
-    # "---Unknown Location VSInstallDir---" or something similar, to clue
-    # people in that we didn't find something, and so env expansion doesn't
-    # do weird things with the $(xxx)'s
-    s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
-
-    def repl(match, paths=paths):
-        key = string.upper(match.group(1))
-        if paths.has_key(key):
-            return paths[key]
-        else:
-            # Now look in the global environment variables
-            envresult = os.getenv(key)
-            if not envresult is None:
-                return envresult + '\\'
-            else:
-                return '---Unknown Location %s---' % match.group()
-
-    rv = []
-    for entry in p.split(os.pathsep):
-        entry = s.sub(repl,entry).rstrip('\n\r')
-        rv.append(entry)
-
-    return string.join(rv,os.pathsep)
-
-def _get_msvc8_path(path, version, platform, suite):
-    """
-    Get Visual Studio directories from version 8 (MSVS 2005)
-    (it has a different registry structure than versions before it)
-    """
-    # first, look for a customization of the default values in the
-    # registry: These are sometimes stored in the Local Settings area
-    # for Visual Studio, in a file, so we have to parse it.
-    dirs = _parse_msvc8_overrides(version, platform, suite)
-
-    if dirs.has_key(path):
-        p = dirs[path]
-    else:
-        raise SCons.Errors.InternalError, \
-              "Unable to retrieve the %s path from MS VC++."%path
-
-    # collect some useful information for later expansions...
-    paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
-
-    # expand the directory path variables that we support.  If there
-    # is a variable we don't support, then replace that entry with
-    # "---Unknown Location VSInstallDir---" or something similar, to clue
-    # people in that we didn't find something, and so env expansion doesn't
-    # do weird things with the $(xxx)'s
-    s = re.compile('\$\(([a-zA-Z0-9_]+?)\)')
-
-    def repl(match, paths=paths):
-        key = string.upper(match.group(1))
-        if paths.has_key(key):
-            return paths[key]
-        else:
-            return '---Unknown Location %s---' % match.group()
-
-    rv = []
-    for entry in p.split(os.pathsep):
-        entry = s.sub(repl,entry).rstrip('\n\r')
-        rv.append(entry)
-
-    return string.join(rv,os.pathsep)
-
-def get_msvc_path(env, path, version):
-    """
-    Get a list of visualstudio directories (include, lib or path).
-    Return a string delimited by the os.pathsep separator (';'). An
-    exception will be raised if unable to access the registry or
-    appropriate registry keys not found.
-    """
-
-    if not SCons.Util.can_read_reg:
-        raise SCons.Errors.InternalError, "No Windows registry module was found"
-
-    # normalize the case for comparisons (since the registry is case
-    # insensitive)
-    path = string.upper(path)
-
-    if path=='LIB':
-        path= 'LIBRARY'
-
-    version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
-    if version_num >= 8.0:
-        platform = env.get('MSVS8_PLATFORM', 'x86')
-        suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
-    else:
-        platform = 'x86'
-
-    if version_num >= 8.0:
-        return _get_msvc8_path(path, str(version_num), platform, suite)
-    elif version_num >= 7.0:
-        return _get_msvc7_path(path, str(version_num), platform)
-
-    path = string.upper(path + ' Dirs')
-    K = ('Software\\Microsoft\\Devstudio\\%s\\' +
-         'Build System\\Components\\Platforms\\Win32 (x86)\\Directories') % \
-        (version)
-    for base in (SCons.Util.HKEY_CURRENT_USER,
-                 SCons.Util.HKEY_LOCAL_MACHINE):
-        try:
-            k = SCons.Util.RegOpenKeyEx(base,K)
-            i = 0
-            while 1:
-                try:
-                    (p,v,t) = SCons.Util.RegEnumValue(k,i)
-                    if string.upper(p) == path:
-                        return v
-                    i = i + 1
-                except SCons.Util.RegError:
-                    break
-        except SCons.Util.RegError:
-            pass
-
-    # if we got here, then we didn't find the registry entries:
-    raise SCons.Errors.InternalError, "The %s path was not found in the registry."%path
-
-def _get_msvc6_default_paths(version, use_mfc_dirs):
-    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
-    three environment variables that should be set in order to execute
-    the MSVC 6.0 tools properly, if the information wasn't available
-    from the registry."""
-    MVSdir = None
-    paths = {}
-    exe_path = ''
-    lib_path = ''
-    include_path = ''
-    try:
-        paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
-        MVSdir = paths['VSINSTALLDIR']
-    except (SCons.Util.RegError, SCons.Errors.InternalError, KeyError):
-        if os.environ.has_key('MSDEVDIR'):
-            MVSdir = os.path.normpath(os.path.join(os.environ['MSDEVDIR'],'..','..'))
-        else:
-            MVSdir = r'C:\Program Files\Microsoft Visual Studio'
-    if MVSdir:
-        if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
-            MVSVCdir = paths['VCINSTALLDIR']
-        else:
-            MVSVCdir = os.path.join(MVSdir,'VC98')
-
-        MVSCommondir = r'%s\Common' % MVSdir
-        if use_mfc_dirs:
-            mfc_include_ = r'%s\ATL\include;%s\MFC\include;' % (MVSVCdir, MVSVCdir)
-            mfc_lib_ = r'%s\MFC\lib;' % MVSVCdir
-        else:
-            mfc_include_ = ''
-            mfc_lib_ = ''
-        include_path = r'%s%s\include' % (mfc_include_, MVSVCdir)
-        lib_path = r'%s%s\lib' % (mfc_lib_, MVSVCdir)
-
-        if os.environ.has_key('OS') and os.environ['OS'] == "Windows_NT":
-            osdir = 'WINNT'
-        else:
-            osdir = 'WIN95'
-
-        exe_path = r'%s\tools\%s;%s\MSDev98\bin;%s\tools;%s\bin' % (MVSCommondir, osdir, MVSCommondir,  MVSCommondir, MVSVCdir)
-    return (include_path, lib_path, exe_path)
-
-def _get_msvc7_default_paths(env, version, use_mfc_dirs):
-    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
-    three environment variables that should be set in order to execute
-    the MSVC .NET tools properly, if the information wasn't available
-    from the registry."""
-
-    MVSdir = None
-    paths = {}
-    exe_path = ''
-    lib_path = ''
-    include_path = ''
-    try:
-        paths = SCons.Tool.msvs.get_msvs_install_dirs(version)
-        MVSdir = paths['VSINSTALLDIR']
-    except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
-        if os.environ.has_key('VSCOMNTOOLS'):
-            MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
-        else:
-            # last resort -- default install location
-            MVSdir = r'C:\Program Files\Microsoft Visual Studio .NET'
-
-    if MVSdir:
-        if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
-            MVSVCdir = paths['VCINSTALLDIR']
-        else:
-            MVSVCdir = os.path.join(MVSdir,'Vc7')
-
-        MVSCommondir = r'%s\Common7' % MVSdir
-        if use_mfc_dirs:
-            mfc_include_ = r'%s\atlmfc\include;' % MVSVCdir
-            mfc_lib_ = r'%s\atlmfc\lib;' % MVSVCdir
-        else:
-            mfc_include_ = ''
-            mfc_lib_ = ''
-        include_path = r'%s%s\include;%s\PlatformSDK\include' % (mfc_include_, MVSVCdir, MVSVCdir)
-        lib_path = r'%s%s\lib;%s\PlatformSDK\lib' % (mfc_lib_, MVSVCdir, MVSVCdir)
-        exe_path = r'%s\IDE;%s\bin;%s\Tools;%s\Tools\bin' % (MVSCommondir,MVSVCdir, MVSCommondir, MVSCommondir )
-
-        if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
-            include_path = include_path + r';%s\include'%paths['FRAMEWORKSDKDIR']
-            lib_path = lib_path + r';%s\lib'%paths['FRAMEWORKSDKDIR']
-            exe_path = exe_path + r';%s\bin'%paths['FRAMEWORKSDKDIR']
-
-        if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
-            exe_path = exe_path + r';%s\%s'%(paths['FRAMEWORKDIR'],paths['FRAMEWORKVERSION'])
-
-    return (include_path, lib_path, exe_path)
-
-def _get_msvc8_default_paths(env, version, suite, use_mfc_dirs):
-    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
-    three environment variables that should be set in order to execute
-    the MSVC 8 tools properly, if the information wasn't available
-    from the registry."""
-
-    MVSdir = None
-    paths = {}
-    exe_paths = []
-    lib_paths = []
-    include_paths = []
-    try:
-        paths = SCons.Tool.msvs.get_msvs_install_dirs(version, suite)
-        MVSdir = paths['VSINSTALLDIR']
-    except (KeyError, SCons.Util.RegError, SCons.Errors.InternalError):
-        if os.environ.has_key('VSCOMNTOOLS'):
-            MVSdir = os.path.normpath(os.path.join(os.environ['VSCOMNTOOLS'],'..','..'))
-        else:
-            # last resort -- default install location
-            MVSdir = os.getenv('ProgramFiles') + r'\Microsoft Visual Studio 8'
-
-    if MVSdir:
-        if SCons.Util.can_read_reg and paths.has_key('VCINSTALLDIR'):
-            MVSVCdir = paths['VCINSTALLDIR']
-        else:
-            MVSVCdir = os.path.join(MVSdir,'VC')
-
-        MVSCommondir = os.path.join(MVSdir, 'Common7')
-        include_paths.append( os.path.join(MVSVCdir, 'include') )
-        lib_paths.append( os.path.join(MVSVCdir, 'lib') )
-        for base, subdir in [(MVSCommondir,'IDE'), (MVSVCdir,'bin'),
-                             (MVSCommondir,'Tools'), (MVSCommondir,r'Tools\bin')]:
-            exe_paths.append( os.path.join( base, subdir) )
-
-        if paths.has_key('PLATFORMSDKDIR'):
-            PlatformSdkDir = paths['PLATFORMSDKDIR']
-        else:
-            PlatformSdkDir = os.path.join(MVSVCdir,'PlatformSDK')
-        platform_include_path = os.path.join( PlatformSdkDir, 'Include' )
-        include_paths.append( platform_include_path )
-        lib_paths.append( os.path.join( PlatformSdkDir, 'Lib' ) )
-        if use_mfc_dirs:
-            if paths.has_key('PLATFORMSDKDIR'):
-                include_paths.append( os.path.join( platform_include_path, 'mfc' ) )
-                include_paths.append( os.path.join( platform_include_path, 'atl' ) )
-            else:
-                atlmfc_path = os.path.join( MVSVCdir, 'atlmfc' )
-                include_paths.append( os.path.join( atlmfc_path, 'include' ) )
-                lib_paths.append( os.path.join( atlmfc_path, 'lib' ) )
-
-        if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKSDKDIR'):
-            fwdir = paths['FRAMEWORKSDKDIR']
-            include_paths.append( os.path.join( fwdir, 'include' ) )
-            lib_paths.append( os.path.join( fwdir, 'lib' ) )
-            exe_paths.append( os.path.join( fwdir, 'bin' ) )
-
-        if SCons.Util.can_read_reg and paths.has_key('FRAMEWORKDIR') and paths.has_key('FRAMEWORKVERSION'):
-            exe_paths.append( os.path.join( paths['FRAMEWORKDIR'], paths['FRAMEWORKVERSION'] ) )
-
-    include_path = string.join( include_paths, os.pathsep )
-    lib_path = string.join(lib_paths, os.pathsep )
-    exe_path = string.join(exe_paths, os.pathsep )
-    return (include_path, lib_path, exe_path)
-
-def get_msvc_paths(env, version=None, use_mfc_dirs=0):
-    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values
-    of those three environment variables that should be set
-    in order to execute the MSVC tools properly."""
-    exe_path = ''
-    lib_path = ''
-    include_path = ''
-
-    if not version:
-        versions = SCons.Tool.msvs.get_visualstudio_versions()
-        if versions:
-            version = versions[0] #use highest version by default
-        else:
-            version = '6.0'
-
-    # Some of the configured directories only
-    # appear if the user changes them from the default.
-    # Therefore, we'll see if we can get the path to the MSDev
-    # base installation from the registry and deduce the default
-    # directories.
-    version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
-    if version_num >= 8.0:
-        suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
-        defpaths = _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
-    elif version_num >= 7.0:
-        defpaths = _get_msvc7_default_paths(env, version, use_mfc_dirs)
-    else:
-        defpaths = _get_msvc6_default_paths(version, use_mfc_dirs)
-
-    try:
-        include_path = get_msvc_path(env, "include", version)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        include_path = defpaths[0]
-
-    try:
-        lib_path = get_msvc_path(env, "lib", version)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        lib_path = defpaths[1]
-
-    try:
-        exe_path = get_msvc_path(env, "path", version)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        exe_path = defpaths[2]
-
-    return (include_path, lib_path, exe_path)
-
-def get_msvc_default_paths(env, version=None, use_mfc_dirs=0):
-    """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values of those
-    three environment variables that should be set in order to execute
-    the MSVC tools properly.  This will only return the default
-    locations for the tools, not the values used by MSVS in their
-    directory setup area.  This can help avoid problems with different
-    developers having different settings, and should allow the tools
-    to run in most cases."""
-
-    if not version and not SCons.Util.can_read_reg:
-        version = '6.0'
-
-    try:
-        if not version:
-            version = SCons.Tool.msvs.get_visualstudio_versions()[0] #use highest version
-    except KeyboardInterrupt:
-        raise
-    except:
-        pass
-
-    version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
-    if version_num >= 8.0:
-        suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
-        return _get_msvc8_default_paths(env, version, suite, use_mfc_dirs)
-    elif version_num >= 7.0:
-        return _get_msvc7_default_paths(env, version, use_mfc_dirs)
-    else:
-        return _get_msvc6_default_paths(version, use_mfc_dirs)
-
 def validate_vars(env):
     """Validate the PCH and PCHSTOP construction variables."""
     if env.has_key('PCH') and env['PCH']:
@@ -787,26 +232,11 @@ def generate(env):
     env['SHOBJPREFIX']    = '$OBJPREFIX'
     env['SHOBJSUFFIX']    = '$OBJSUFFIX'
 
-    try:
-        version = SCons.Tool.msvs.get_default_visualstudio_version(env)
-        version_num, suite = SCons.Tool.msvs.msvs_parse_version(version)
-        if version_num == 8.0:
-            suite = SCons.Tool.msvs.get_default_visualstudio8_suite(env)
-
-        use_mfc_dirs = env.get('MSVS_USE_MFC_DIRS', 0)
-        if env.get('MSVS_IGNORE_IDE_PATHS', 0):
-            _get_paths = get_msvc_default_paths
-        else:
-            _get_paths = get_msvc_paths
-        include_path, lib_path, exe_path = _get_paths(env, version, use_mfc_dirs)
-
-        # since other tools can set these, we just make sure that the
-        # relevant stuff from MSVS is in there somewhere.
-        env.PrependENVPath('INCLUDE', include_path)
-        env.PrependENVPath('LIB', lib_path)
-        env.PrependENVPath('PATH', exe_path)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        pass
+    # Set-up ms tools paths for default version
+    merge_default_version(env)
+
+    import mssdk
+    mssdk.generate(env)
 
     env['CFILESUFFIX'] = '.c'
     env['CXXFILESUFFIX'] = '.cc'
@@ -821,11 +251,7 @@ def generate(env):
         env['ENV']['SystemRoot'] = SCons.Platform.win32.get_system_root()
 
 def exists(env):
-    if SCons.Tool.msvs.is_msvs_installed():
-        # there's at least one version of MSVS installed.
-        return 1
-    else:
-        return env.Detect('cl')
+    return detect_msvs()
 
 # Local Variables:
 # tab-width:4
index f80564baaaa66900607e84445d86a1accbf8065d..4d40d8c53751ce1d4326ffc5e4d97f1ca1cd89ab 100644 (file)
@@ -49,6 +49,8 @@ import SCons.Script.SConscript
 import SCons.Util
 import SCons.Warnings
 
+from MSCommon import detect_msvs, merge_default_version
+
 ##############################################################################
 # Below here are the classes and functions for generation of
 # DSP/DSW/SLN/VCPROJ files.
@@ -1155,375 +1157,6 @@ def GenerateDSW(dswfile, source, env):
 # DSP/DSW/SLN/VCPROJ files.
 ##############################################################################
 
-def get_default_visualstudio_version(env):
-    """Returns the version set in the env, or the latest version
-    installed, if it can find it, or '6.0' if all else fails.  Also
-    updates the environment with what it found."""
-
-    versions = ['6.0']
-
-    if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
-        v = get_visualstudio_versions()
-        if v:
-            versions = v
-        env['MSVS'] = {'VERSIONS' : versions}
-    else:
-        versions = env['MSVS'].get('VERSIONS', versions)
-
-    if not env.has_key('MSVS_VERSION'):
-        env['MSVS_VERSION'] = versions[0] #use highest version by default
-
-    env['MSVS']['VERSION'] = env['MSVS_VERSION']
-
-    return env['MSVS_VERSION']
-
-def get_visualstudio_versions():
-    """
-    Get list of visualstudio versions from the Windows registry.
-    Returns a list of strings containing version numbers.  An empty list
-    is returned if we were unable to accees the register (for example,
-    we couldn't import the registry-access module) or the appropriate
-    registry keys weren't found.
-    """
-
-    if not SCons.Util.can_read_reg:
-        return []
-
-    HLM = SCons.Util.HKEY_LOCAL_MACHINE
-    KEYS = {
-        r'Software\Microsoft\VisualStudio'      : '',
-        r'Software\Microsoft\VCExpress'         : 'Exp',
-    }
-    L = []
-    for K, suite_suffix in KEYS.items():
-        try:
-            k = SCons.Util.RegOpenKeyEx(HLM, K)
-            i = 0
-            while 1:
-                try:
-                    p = SCons.Util.RegEnumKey(k,i)
-                except SCons.Util.RegError:
-                    break
-                i = i + 1
-                if not p[0] in '123456789' or p in L:
-                    continue
-                # Only add this version number if there is a valid
-                # registry structure (includes the "Setup" key),
-                # and at least some of the correct directories
-                # exist.  Sometimes VS uninstall leaves around
-                # some registry/filesystem turds that we don't
-                # want to trip over.  Also, some valid registry
-                # entries are MSDN entries, not MSVS ('7.1',
-                # notably), and we want to skip those too.
-                try:
-                    SCons.Util.RegOpenKeyEx(HLM, K + '\\' + p + '\\Setup')
-                except SCons.Util.RegError:
-                    continue
-
-                id = []
-                idk = SCons.Util.RegOpenKeyEx(HLM, K + '\\' + p)
-                # This is not always here -- it only exists if the
-                # user installed into a non-standard location (at
-                # least in VS6 it works that way -- VS7 seems to
-                # always write it)
-                try:
-                    id = SCons.Util.RegQueryValueEx(idk, 'InstallDir')
-                except SCons.Util.RegError:
-                    pass
-
-                # If the InstallDir key doesn't exist,
-                # then we check the default locations.
-                # Note: The IDE's executable is not devenv.exe for VS8 Express.
-                if not id or not id[0]:
-                    files_dir = SCons.Platform.win32.get_program_files_dir()
-                    version_num, suite = msvs_parse_version(p)
-                    if version_num < 7.0:
-                        vs = r'Microsoft Visual Studio\Common\MSDev98'
-                    elif version_num < 8.0:
-                        vs = r'Microsoft Visual Studio .NET\Common7\IDE'
-                    else:
-                        vs = r'Microsoft Visual Studio 8\Common7\IDE'
-                    id = [ os.path.join(files_dir, vs) ]
-                if os.path.exists(id[0]):
-                    L.append(p + suite_suffix)
-        except SCons.Util.RegError:
-            pass
-
-    if not L:
-        return []
-
-    # This is a hack to get around the fact that certain Visual Studio
-    # patches place a "6.1" version in the registry, which does not have
-    # any of the keys we need to find include paths, install directories,
-    # etc.  Therefore we ignore it if it is there, since it throws all
-    # other logic off.
-    try:
-        L.remove("6.1")
-    except ValueError:
-        pass
-
-    L.sort()
-    L.reverse()
-
-    return L
-
-def get_default_visualstudio8_suite(env):
-    """
-    Returns the Visual Studio 2005 suite identifier set in the env, or the
-    highest suite installed.
-    """
-    if not env.has_key('MSVS') or not SCons.Util.is_Dict(env['MSVS']):
-        env['MSVS'] = {}
-
-    if env.has_key('MSVS_SUITE'):
-        # TODO(1.5)
-        #suite = env['MSVS_SUITE'].upper()
-        suite = string.upper(env['MSVS_SUITE'])
-        suites = [suite]
-    else:
-        suite = 'EXPRESS'
-        suites = [suite]
-        if SCons.Util.can_read_reg:
-            suites = get_visualstudio8_suites()
-            if suites:
-                suite = suites[0] #use best suite by default
-
-    env['MSVS_SUITE'] = suite
-    env['MSVS']['SUITES'] = suites
-    env['MSVS']['SUITE'] = suite
-
-    return suite
-
-def get_visualstudio8_suites():
-    """
-    Returns a sorted list of all installed Visual Studio 2005 suites found
-    in the registry. The highest version should be the first entry in the list.
-    """
-
-    suites = []
-
-    # Detect Standard, Professional and Team edition
-    try:
-        idk = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
-            r'Software\Microsoft\VisualStudio\8.0')
-        SCons.Util.RegQueryValueEx(idk, 'InstallDir')
-        editions = { 'PRO': r'Setup\VS\Pro' }       # ToDo: add standard and team editions
-        edition_name = 'STD'
-        for name, key_suffix in editions.items():
-            try:
-                idk = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
-                    r'Software\Microsoft\VisualStudio\8.0' + '\\' + key_suffix )
-                edition_name = name
-            except SCons.Util.RegError:
-                pass
-            suites.append(edition_name)
-    except SCons.Util.RegError:
-        pass
-
-    # Detect Express edition
-    try:
-        idk = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,
-            r'Software\Microsoft\VCExpress\8.0')
-        SCons.Util.RegQueryValueEx(idk, 'InstallDir')
-        suites.append('EXPRESS')
-    except SCons.Util.RegError:
-        pass
-
-    return suites
-
-def is_msvs_installed():
-    """
-    Check the registry for an installed visual studio.
-    """
-    try:
-        v = SCons.Tool.msvs.get_visualstudio_versions()
-        return v
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        return 0
-
-def get_msvs_install_dirs(version = None, vs8suite = None):
-    """
-    Get installed locations for various msvc-related products, like the .NET SDK
-    and the Platform SDK.
-    """
-
-    if not SCons.Util.can_read_reg:
-        return {}
-
-    if not version:
-        versions = get_visualstudio_versions()
-        if versions:
-            version = versions[0] #use highest version by default
-        else:
-            return {}
-
-    version_num, suite = msvs_parse_version(version)
-
-    K = 'Software\\Microsoft\\VisualStudio\\' + str(version_num)
-    if (version_num >= 8.0):
-        if vs8suite == None:
-            # We've been given no guidance about which Visual Studio 8
-            # suite to use, so attempt to autodetect.
-            suites = get_visualstudio8_suites()
-            if suites:
-                vs8suite = suites[0]
-
-        if vs8suite == 'EXPRESS':
-            K = 'Software\\Microsoft\\VCExpress\\' + str(version_num)
-
-    # vc++ install dir
-    rv = {}
-    if (version_num < 7.0):
-        key = K + r'\Setup\Microsoft Visual C++\ProductDir'
-    else:
-        key = K + r'\Setup\VC\ProductDir'
-    try:
-        (rv['VCINSTALLDIR'], t) = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE, key)
-    except SCons.Util.RegError:
-        pass
-
-    # visual studio install dir
-    if (version_num < 7.0):
-        try:
-            (rv['VSINSTALLDIR'], t) = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE,
-                                                             K + r'\Setup\Microsoft Visual Studio\ProductDir')
-        except SCons.Util.RegError:
-            pass
-
-        if not rv.has_key('VSINSTALLDIR') or not rv['VSINSTALLDIR']:
-            if rv.has_key('VCINSTALLDIR') and rv['VCINSTALLDIR']:
-                rv['VSINSTALLDIR'] = os.path.dirname(rv['VCINSTALLDIR'])
-            else:
-                rv['VSINSTALLDIR'] = os.path.join(SCons.Platform.win32.get_program_files_dir(),'Microsoft Visual Studio')
-    else:
-        try:
-            (rv['VSINSTALLDIR'], t) = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE,
-                                                             K + r'\Setup\VS\ProductDir')
-        except SCons.Util.RegError:
-            pass
-
-    # .NET framework install dir
-    try:
-        (rv['FRAMEWORKDIR'], t) = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE,
-            r'Software\Microsoft\.NETFramework\InstallRoot')
-    except SCons.Util.RegError:
-        pass
-
-    if rv.has_key('FRAMEWORKDIR'):
-        # try and enumerate the installed versions of the .NET framework.
-        contents = os.listdir(rv['FRAMEWORKDIR'])
-        l = re.compile('v[0-9]+.*')
-        installed_framework_versions = filter(lambda e, l=l: l.match(e), contents)
-
-        def versrt(a,b):
-            # since version numbers aren't really floats...
-            aa = a[1:]
-            bb = b[1:]
-            aal = string.split(aa, '.')
-            bbl = string.split(bb, '.')
-            # sequence comparison in python is lexicographical
-            # which is exactly what we want.
-            # Note we sort backwards so the highest version is first.
-            return cmp(bbl,aal)
-
-        installed_framework_versions.sort(versrt)
-
-        rv['FRAMEWORKVERSIONS'] = installed_framework_versions
-
-        # TODO: allow a specific framework version to be set
-
-        # Choose a default framework version based on the Visual
-        # Studio version.
-        DefaultFrameworkVersionMap = {
-            '7.0'   : 'v1.0',
-            '7.1'   : 'v1.1',
-            '8.0'   : 'v2.0',
-            # TODO: Does .NET 3.0 need to be worked into here somewhere?
-        }
-        try:
-            default_framework_version = DefaultFrameworkVersionMap[version[:3]]
-        except (KeyError, TypeError):
-            pass
-        else:
-            # Look for the first installed directory in FRAMEWORKDIR that
-            # begins with the framework version string that's appropriate
-            # for the Visual Studio version we're using.
-            for v in installed_framework_versions:
-                if v[:4] == default_framework_version:
-                    rv['FRAMEWORKVERSION'] = v
-                    break
-
-        # If the framework version couldn't be worked out by the previous
-        # code then fall back to using the latest version of the .NET
-        # framework
-        if not rv.has_key('FRAMEWORKVERSION'):
-            rv['FRAMEWORKVERSION'] = installed_framework_versions[0]
-
-    # .NET framework SDK install dir
-    if rv.has_key('FRAMEWORKVERSION'):
-        # The .NET SDK version used must match the .NET version used,
-        # so we deliberately don't fall back to other .NET framework SDK
-        # versions that might be present.
-        ver = rv['FRAMEWORKVERSION'][:4]
-        key = r'Software\Microsoft\.NETFramework\sdkInstallRoot' + ver
-        try:
-            (rv['FRAMEWORKSDKDIR'], t) = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE,
-                key)
-        except SCons.Util.RegError:
-            pass
-
-    # MS Platform SDK dir
-    try:
-        (rv['PLATFORMSDKDIR'], t) = SCons.Util.RegGetValue(SCons.Util.HKEY_LOCAL_MACHINE,
-            r'Software\Microsoft\MicrosoftSDK\Directories\Install Dir')
-    except SCons.Util.RegError:
-        pass
-
-    if rv.has_key('PLATFORMSDKDIR'):
-        # if we have a platform SDK, try and get some info on it.
-        vers = {}
-        try:
-            loc = r'Software\Microsoft\MicrosoftSDK\InstalledSDKs'
-            k = SCons.Util.RegOpenKeyEx(SCons.Util.HKEY_LOCAL_MACHINE,loc)
-            i = 0
-            while 1:
-                try:
-                    key = SCons.Util.RegEnumKey(k,i)
-                    sdk = SCons.Util.RegOpenKeyEx(k,key)
-                    j = 0
-                    name = ''
-                    date = ''
-                    version = ''
-                    while 1:
-                        try:
-                            (vk,vv,t) = SCons.Util.RegEnumValue(sdk,j)
-                            # TODO(1.5):
-                            #if vk.lower() == 'keyword':
-                            #    name = vv
-                            #if vk.lower() == 'propagation_date':
-                            #    date = vv
-                            #if vk.lower() == 'version':
-                            #    version = vv
-                            if string.lower(vk) == 'keyword':
-                                name = vv
-                            if string.lower(vk) == 'propagation_date':
-                                date = vv
-                            if string.lower(vk) == 'version':
-                                version = vv
-                            j = j + 1
-                        except SCons.Util.RegError:
-                            break
-                    if name:
-                        vers[name] = (date, version)
-                    i = i + 1
-                except SCons.Util.RegError:
-                    break
-            rv['PLATFORMSDK_MODULES'] = vers
-        except SCons.Util.RegError:
-            pass
-
-    return rv
-
 def GetMSVSProjectSuffix(target, source, env, for_signature):
      return env['MSVS']['PROJECTSUFFIX']
 
@@ -1767,17 +1400,8 @@ def generate(env):
     env['MSVSCLEANCOM'] = '$MSVSSCONSCOM -c "$MSVSBUILDTARGET"'
     env['MSVSENCODING'] = 'Windows-1252'
 
-    try:
-        version = get_default_visualstudio_version(env)
-        # keep a record of some of the MSVS info so the user can use it.
-        dirs = get_msvs_install_dirs(version)
-        env['MSVS'].update(dirs)
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        # we don't care if we can't do this -- if we can't, it's
-        # because we don't have access to the registry, or because the
-        # tools aren't installed.  In either case, the user will have to
-        # find them on their own.
-        pass
+    # Set-up ms tools paths for default version
+    merge_default_version(env)
 
     version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
     if (version_num < 7.0):
@@ -1794,29 +1418,7 @@ def generate(env):
     env['SCONS_HOME'] = os.environ.get('SCONS_HOME')
 
 def exists(env):
-    if not env['PLATFORM'] in ('win32', 'cygwin'):
-        return 0
-
-    try:
-        v = SCons.Tool.msvs.get_visualstudio_versions()
-    except (SCons.Util.RegError, SCons.Errors.InternalError):
-        pass
-
-    if not v:
-        version_num = 6.0
-        if env.has_key('MSVS_VERSION'):
-            version_num, suite = msvs_parse_version(env['MSVS_VERSION'])
-        if version_num >= 7.0:
-            # The executable is 'devenv' in Visual Studio Pro,
-            # Team System and others.  Express Editions have different
-            # executable names.  Right now we're only going to worry
-            # about Visual C++ 2005 Express Edition.
-            return env.Detect('devenv') or env.Detect('vcexpress')
-        else:
-            return env.Detect('msdev')
-    else:
-        # there's at least one version of MSVS installed.
-        return 1
+    return detect_msvs()
 
 # Local Variables:
 # tab-width:4
index 91a196b533dc9f09976b4d535acece1366ee3cb1..821bbcae57ab81ae3c8038b79bfd971147c28c34 100644 (file)
@@ -238,7 +238,7 @@ this dictionary with the following keys:
 
 <envar>VERSION</envar>:
 the version of MSVS being used (can be set via
-MSVS_VERSION)
+&cv-link-MSVS_VERSION;)
 
 <envar>VERSIONS</envar>:
 the available versions of MSVS installed
@@ -274,6 +274,19 @@ If a value isn't set, it wasn't available in the registry.
 </summary>
 </cvar>
 
+<cvar name="MSVS_ARCH">
+<summary>
+Sets the architecture for which the generated project(s) should build.
+
+The default value is <literal>x86</literal>.
+<literal>amd64</literal> is also supported
+by &SCons; for some Visual Studio versions.
+Trying to set &cv-MSVS_ARCH; to an architecture that's not
+supported for a given Visual Studio version
+will generate an error.
+</summary>
+</cvar>
+
 <cvar name="MSVS_IGNORE_IDE_PATHS">
 <summary>
 Tells the MS Visual Studio tools to use minimal INCLUDE, LIB, and PATH settings,
index 40c6af6016be7527852f145a4cfb222b2d62a8d6..1fb1e75996cae78037249688cf3577d74b7d7d7d 100644 (file)
@@ -28,11 +28,17 @@ import string
 import sys
 import TestCmd
 import unittest
+import copy
 
 from SCons.Tool.msvs import *
 import SCons.Util
 import SCons.Warnings
 
+from SCons.Tool.MSCommon.common import debug
+
+from SCons.Tool.MSCommon import get_default_version, \
+                                query_versions
+
 regdata_6a = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio]
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0]
 [HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0\ServicePacks]
@@ -280,12 +286,75 @@ regdata_8exp = string.split(r'''
 "VCXDCMakeTool"="*.xdc"
 ''','\n')
 
+regdata_80 = string.split(r'''
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0]
+"CLR Version"="v2.0.50727"
+"ApplicationID"="VisualStudio"
+"ThisVersionDTECLSID"="{BA018599-1DB3-44f9-83B4-461454C84BF8}"
+"ThisVersionSolutionCLSID"="{1B2EEDD6-C203-4d04-BD59-78906E3E8AAB}"
+"SecurityAppID"="{DF99D4F5-9F04-4CEF-9D39-095821B49C77}"
+"InstallDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\"
+"EnablePreloadCLR"=dword:00000001
+"RestoreAppPath"=dword:00000001
+"Source Directories"="C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\;C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\mfc\;C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\src\atl\;C:\Program Files\Microsoft Visual Studio 8\VC\atlmfc\include\"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\InstalledProducts]
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\InstalledProducts\Microsoft Visual C++]
+"UseInterface"=dword:00000001
+"Package"="{F1C25864-3097-11D2-A5C5-00C04F7968B4}"
+"DefaultProductAttribute"="VC"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup]
+"Dbghelp_path"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\EF]
+"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\EnterpriseFrameworks\"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\Microsoft Visual Studio 2005 Professional Edition - ENU]
+"SrcPath"="d:\vs\"
+"InstallSuccess"=dword:00000001
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VC]
+"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\VC\"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VS]
+"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\"
+"VS7EnvironmentLocation"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe"
+"EnvironmentPath"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.exe"
+"EnvironmentDirectory"="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\"
+"VS7CommonDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\"
+"VS7CommonBinDir"="C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VS\BuildNumber]
+"1033"="8.0.50727.42"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\Setup\VS\Pro]
+"ProductDir"="C:\Program Files\Microsoft Visual Studio 8\"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC]
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC\VC_OBJECTS_PLATFORM_INFO]
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32]
+@="{72f11281-2429-11d7-8bf6-00b0d03daa06}"
+[HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\8.0\VC\VC_OBJECTS_PLATFORM_INFO\Win32\ToolDefaultExtensionLists]
+"VCCLCompilerTool"="*.cpp;*.cxx;*.cc;*.c"
+"VCLinkerTool"="*.obj;*.res;*.lib;*.rsc;*.licenses"
+"VCLibrarianTool"="*.obj;*.res;*.lib;*.rsc"
+"VCMIDLTool"="*.idl;*.odl"
+"VCCustomBuildTool"="*.bat"
+"VCResourceCompilerTool"="*.rc"
+"VCPreBuildEventTool"="*.bat"
+"VCPreLinkEventTool"="*.bat"
+"VCPostBuildEventTool"="*.bat"
+"VCBscMakeTool"="*.sbr"
+"VCFxCopTool"="*.dll;*.exe"
+"VCNMakeTool"=""
+"VCWebServiceProxyGeneratorTool"="*.discomap"
+"VCWebDeploymentTool"=""
+"VCALinkTool"="*.resources"
+"VCManagedResourceCompilerTool"="*.resx"
+"VCXMLDataGeneratorTool"="*.xsd"
+"VCManifestTool"="*.manifest"
+"VCXDCMakeTool"="*.xdc"
+''','\n')
+
 regdata_cv = string.split(r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion]
 "ProgramFilesDir"="C:\Program Files"
 "CommonFilesDir"="C:\Program Files\Common Files"
 "MediaPath"="C:\WINDOWS\Media"
 ''','\n')
 
+
 regdata_none = []
 
 class DummyEnv:
@@ -314,6 +383,8 @@ class RegKey:
     def __init__(self,key):
         self.key = key
 
+# Warning: this is NOT case-insensitive, unlike the Windows registry.
+# So e.g. HKLM\Software is NOT the same key as HKLM\SOFTWARE.
 class RegNode:
     """node in the dummy registry"""
     def __init__(self,name):
@@ -453,50 +524,60 @@ def DummyExists(path):
     return 1
 
 class msvsTestCase(unittest.TestCase):
+    """This test case is run several times with different defaults.
+    See its subclasses below."""
     def setUp(self):
         global registry
         registry = self.registry
+        from SCons.Tool.MSCommon.vs import reset_installed_visual_studios
+        reset_installed_visual_studios()
+
+    def test_detect_msvs(self):
+        """Test the detect_msvs() function"""
+        r = detect_msvs()
+        assert r == (self.number_of_versions > 0), r
 
-    def test_get_default_visual_studio_version(self):
+    def test_get_default_version(self):
         """Test retrieval of the default visual studio version"""
+        
+        debug("Testing for default version %s"%self.default_version)
         env = DummyEnv()
-        v1 = get_default_visualstudio_version(env)
-        assert env['MSVS_VERSION'] == self.default_version, env['MSVS_VERSION']
-        assert env['MSVS']['VERSION'] == self.default_version, env['MSVS']['VERSION']
-        assert v1 == self.default_version, v1
+        v1 = get_default_version(env)
+        assert env['MSVS_VERSION'] == self.default_version, \
+               (self.default_version, env['MSVS_VERSION'])
+        assert env['MSVS']['VERSION'] == self.default_version, \
+               (self.default_version, env['MSVS']['VERSION'])
+        assert v1 == self.default_version, (self.default_version, v1)
 
         env = DummyEnv({'MSVS_VERSION':'7.0'})
-        v2 = get_default_visualstudio_version(env)
+        v2 = get_default_version(env)
         assert env['MSVS_VERSION'] == '7.0', env['MSVS_VERSION']
         assert env['MSVS']['VERSION'] == '7.0', env['MSVS']['VERSION']
         assert v2 == '7.0', v2
 
         env = DummyEnv()
-        v3 = get_default_visualstudio_version(env)
+        v3 = get_default_version(env)
         if v3 == '7.1':
             override = '7.0'
         else:
             override = '7.1'
         env['MSVS_VERSION'] = override
-        v3 = get_default_visualstudio_version(env)
+        v3 = get_default_version(env)
         assert env['MSVS_VERSION'] == override, env['MSVS_VERSION']
         assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION']
         assert v3 == override, v3
 
-    def test_get_visual_studio_versions(self):
+    def _TODO_test_merge_default_version(self):
+        """Test the merge_default_version() function"""
+        pass
+
+    def test_query_versions(self):
         """Test retrieval of the list of visual studio versions"""
-        v1 = get_visualstudio_versions()
-        assert not v1 or v1[0] == self.highest_version, v1
+        v1 = query_versions()
+        assert not v1 or str(v1[0]) == self.highest_version, \
+               (v1, self.highest_version)
         assert len(v1) == self.number_of_versions, v1
 
-    def test_get_msvs_install_dirs(self):
-        """Test retrieval of the list of visual studio installed locations"""
-        v1 = get_msvs_install_dirs()
-        assert v1 == self.default_install_loc, v1
-        for key, loc in self.install_locs.items():
-            v2 = get_msvs_install_dirs(key)
-            assert v2 == loc, key + ': ' + str(v2)
-
 class msvs6aTestCase(msvsTestCase):
     """Test MSVS 6 Registry"""
     registry = DummyRegistry(regdata_6a + regdata_cv)
@@ -504,7 +585,7 @@ class msvs6aTestCase(msvsTestCase):
     highest_version = '6.0'
     number_of_versions = 1
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio\\VC98'},
+        '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio\\VC98', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio\\VC98\\Bin'},
         '7.0' : {},
         '7.1' : {},
         '8.0' : {},
@@ -519,7 +600,7 @@ class msvs6bTestCase(msvsTestCase):
     highest_version = '6.0'
     number_of_versions = 1
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\VS6', 'VCINSTALLDIR': 'C:\\VS6\\VC98'},
+        '6.0' : {'VSINSTALLDIR': 'C:\\VS6\\VC98', 'VCINSTALLDIR': 'C:\\VS6\\VC98\\Bin'},
         '7.0' : {},
         '7.1' : {},
         '8.0' : {},
@@ -534,8 +615,8 @@ class msvs6and7TestCase(msvsTestCase):
     highest_version = '7.0'
     number_of_versions = 2
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\VS6', 'VCINSTALLDIR': 'C:\\VS6\\VC98'},
-        '7.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Vc7\\'},
+        '6.0' : {'VSINSTALLDIR': 'C:\\VS6\\VC98', 'VCINSTALLDIR': 'C:\\VS6\\VC98\\Bin'},
+        '7.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7\\Tools'},
         '7.1' : {},
         '8.0' : {},
         '8.0Exp' : {},
@@ -549,8 +630,8 @@ class msvs7TestCase(msvsTestCase):
     highest_version = '7.0'
     number_of_versions = 1
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio'},
-        '7.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Vc7\\'},
+        '6.0' : {},
+        '7.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET\\Common7\\Tools'},
         '7.1' : {},
         '8.0' : {},
         '8.0Exp' : {},
@@ -564,37 +645,52 @@ class msvs71TestCase(msvsTestCase):
     highest_version = '7.1'
     number_of_versions = 1
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio'},
+        '6.0' : {},
         '7.0' : {},
-        '7.1' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET 2003\\', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Vc7\\'},
+        '7.1' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7\\Tools'},
         '8.0' : {},
         '8.0Exp' : {},
     }
     default_install_loc = install_locs['7.1']
 
-class msvs8ExpTestCase(msvsTestCase):
+class msvs8ExpTestCase(msvsTestCase): # XXX: only one still not working
     """Test MSVS 8 Express Registry"""
     registry = DummyRegistry(regdata_8exp + regdata_cv)
     default_version = '8.0Exp'
     highest_version = '8.0Exp'
     number_of_versions = 1
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio'},
+        '6.0' : {},
         '7.0' : {},
         '7.1' : {},
-        '8.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\VC\\'},
-        '8.0Exp' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\VC\\'},
+        '8.0' : {},
+        '8.0Exp' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\VC'},
     }
     default_install_loc = install_locs['8.0Exp']
 
+class msvs80TestCase(msvsTestCase):
+    """Test MSVS 8 Registry"""
+    registry = DummyRegistry(regdata_80 + regdata_cv)
+    default_version = '8.0'
+    highest_version = '8.0'
+    number_of_versions = 1
+    install_locs = {
+        '6.0' : {},
+        '7.0' : {},
+        '7.1' : {},
+        '8.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8', 'VCINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio 8\\VC'},
+        '8.0Exp' : {},
+    }
+    default_install_loc = install_locs['8.0']
+
 class msvsEmptyTestCase(msvsTestCase):
     """Test Empty Registry"""
     registry = DummyRegistry(regdata_none)
-    default_version = '6.0'
+    default_version = '9.0'
     highest_version = None
     number_of_versions = 0
     install_locs = {
-        '6.0' : {'VSINSTALLDIR': 'C:\\Program Files\\Microsoft Visual Studio'},
+        '6.0' : {},
         '7.0' : {},
         '7.1' : {},
         '8.0' : {},
@@ -614,6 +710,8 @@ if __name__ == "__main__":
     SCons.Util.RegEnumValue = DummyEnumValue
     SCons.Util.RegQueryValueEx = DummyQueryValue
     os.path.exists = DummyExists # make sure all files exist :-)
+    os.path.isfile = DummyExists # make sure all files are files :-)
+    os.path.isdir  = DummyExists # make sure all dirs are dirs :-)
 
     exit_val = 0
 
@@ -624,14 +722,28 @@ if __name__ == "__main__":
         msvs7TestCase,
         msvs71TestCase,
         msvs8ExpTestCase,
+        msvs80TestCase,
         msvsEmptyTestCase,
     ]
 
     for test_class in test_classes:
-        print test_class.__doc__
-        suite = unittest.makeSuite(test_class, 'test_')
-        if not unittest.TextTestRunner().run(suite).wasSuccessful():
-            exit_val = 1
+        print "TEST: ", test_class.__doc__
+        back_osenv = copy.deepcopy(os.environ)
+        try:
+            # XXX: overriding the os.environ is bad, but doing it
+            # correctly is too complicated for now. Those tests should
+            # be fixed
+            for k in ['VS71COMNTOOLS',
+                      'VS80COMNTOOLS',
+                      'VS90COMNTOOLS']:
+                if os.environ.has_key(k):
+                    del os.environ[k]
+
+            suite = unittest.makeSuite(test_class, 'test_')
+            if not unittest.TextTestRunner().run(suite).wasSuccessful():
+                exit_val = 1
+        finally:
+            os.env = back_osenv
 
     sys.exit(exit_val)
 
index d0f08a696a407b16bc57f9e418954d12ede33f2d..c77ee495dd7f41b84f2df91de482f23d91748805 100644 (file)
@@ -727,10 +727,32 @@ if can_read_reg:
         # I would use os.path.split here, but it's not a filesystem
         # path...
         p = key.rfind('\\') + 1
-        keyp = key[:p]
+        keyp = key[:p-1]          # -1 to omit trailing slash
         val = key[p:]
         k = RegOpenKeyEx(root, keyp)
         return RegQueryValueEx(k,val)
+else:
+    try:
+        e = WindowsError
+    except NameError:
+        # Make sure we have a definition of WindowsError so we can
+        # run platform-independent tests of Windows functionality on
+        # platforms other than Windows.  (WindowsError is, in fact, an
+        # OSError subclass on Windows.)
+        class WindowsError(OSError):
+            pass
+        import __builtin__
+        __builtin__.WindowsError = WindowsError
+    else:
+        del e
+        
+    HKEY_CLASSES_ROOT = None
+    HKEY_LOCAL_MACHINE = None
+    HKEY_CURRENT_USER = None
+    HKEY_USERS = None
+
+    def RegGetValue(root, key):
+        raise WindowsError
 
 if sys.platform == 'win32':
 
index b494b7c51dc7287142207a452a06c3274d39deb0..93787704335ce2fa12593596b85cb840815261c0 100644 (file)
@@ -401,6 +401,7 @@ arguments = {
                           "SCons.Scanner",
                           "SCons.Script",
                           "SCons.Tool",
+                          "SCons.Tool.MSCommon",
                           "SCons.Tool.packaging",
                           "SCons.Variables",
                          ],
index a7a30622f34de97fb2ff411d3a1f32e988bd4d08..20dc88944d1958b90fe15700ff8ae4bd9fe5c311 100644 (file)
@@ -181,6 +181,7 @@ test.run(status=2, stderr=None)
 
 fail_strings = [
     "No such file or directory",
+    "The system cannot find the file specified",
     "The system cannot find the path specified",
 ]
 
index 8c461a74a5ce648f2b1cd74b99a4182e5c2afeed..ac84398400491836cec96ed6eae75de8c8473ac7 100644 (file)
@@ -134,15 +134,15 @@ test.write(['work', 'f1.in'], "f1.in again again\n")
 os.chmod(test.workpath('work', 'export'), 0555)
 f = open(f1_out, 'rb')
 
-expect = """\
-scons: *** [%s] %s: Permission denied
-""" % (os.path.join('export', 'f1.out'),
-       test.workpath('work', 'export', 'f1.out'))
-
-test.run(chdir = 'work',
-         arguments = f1_out,
-         stderr=expect,
-         status=2)
+
+expect =  [
+    "Permission denied",
+    "The process cannot access the file because it is being used by another process",
+]
+
+test.run(chdir = 'work', arguments = f1_out, stderr=None, status=2)
+
+test.must_contain_any_line(test.stderr(), expect)
 
 f.close()
 
index d12bb2863c0e4a32ed0dfcda6220a99de0ca4fa9..44cda7c65a7c3e8a5979559e456c9ab7b996430c 100644 (file)
@@ -48,7 +48,8 @@ sys.exit(0)
 """)
 
 test.write('SConstruct', """
-env = Environment(M4 = r'%(_python_)s mym4.py', tools=['default', 'm4'])
+env = Environment(tools=['default', 'm4'],
+                  M4 = r'%(_python_)s mym4.py')
 env.M4(target = 'aaa.x', source = 'aaa.x.m4')
 """ % locals())
 
@@ -77,9 +78,11 @@ os.system(string.join(sys.argv[1:], " "))
 """ % string.replace(test.workpath('wrapper.out'), '\\', '\\\\'))
 
     test.write('SConstruct', """
-foo = Environment(M4=r'%(m4)s', M4FLAGS='-DFFF=fff')
+foo = Environment(tools=['default', 'm4'],
+                  M4=r'%(m4)s', M4FLAGS='-DFFF=fff')
 m4 = foo.Dictionary('M4')
-bar = Environment(M4 = r'%(_python_)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb')
+bar = Environment(tools=['default', 'm4'],
+                  M4 = r'%(_python_)s wrapper.py ' + m4, M4FLAGS='-DBBB=bbb')
 foo.M4(target = 'foo.x', source = 'foo.x.m4')
 bar.M4(target = 'bar', source = 'bar.m4')
 """ % locals())
index 6ffd11aecc76beeeb32fdac952aacf8b4f5302d1..a46028329353dee4166c5b2209c434da7eaf19bc 100644 (file)
@@ -56,8 +56,7 @@ env.Program('test', 'test.cpp')
 
 expect_stderr = r'''
 scons: \*\*\* The PCHSTOP construction must be defined if PCH is defined.
-File "%s", line \d+, in \?
-''' % re.escape(SConstruct_path)
+''' + TestSCons.file_expr
 
 test.run(arguments='SET_PCHSTOP=0', status=2, stderr=expect_stderr)
 
@@ -65,8 +64,7 @@ test.run(arguments='SET_PCHSTOP=0', status=2, stderr=expect_stderr)
 
 expect_stderr = r'''
 scons: \*\*\* The PCHSTOP construction variable must be a string: .+
-File "%s", line \d+, in \?
-''' % re.escape(SConstruct_path)
+''' + TestSCons.file_expr
 
 test.run(arguments='SET_PCHSTOP=1', status=2, stderr=expect_stderr)
 
index c8fa8dcbacb57b2bd4522d3158d130ff6690d9e0..e28a87f7fa75ca5b707a1334568d9c496484f3e6 100644 (file)
@@ -180,7 +180,7 @@ test.run(arguments='slow.obj', stderr=None)
 slow = time.time() - start
 
 # using precompiled headers should be faster
-limit = slow*0.85
+limit = slow*0.90
 if fast >= limit:
     print "Using precompiled headers was not fast enough:"
     print "slow.obj:  %.3fs" % slow
diff --git a/test/MSVC/query_vcbat.py b/test/MSVC/query_vcbat.py
new file mode 100644 (file)
index 0000000..a662008
--- /dev/null
@@ -0,0 +1,66 @@
+#
+# __COPYRIGHT__
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+
+import TestSCons
+
+test = TestSCons.TestSCons(match = TestSCons.match_re)
+
+if sys.platform != 'win32':
+    msg = "Skipping Visual C/C++ test on non-Windows platform '%s'\n" % sys.platform
+    test.skip_test(msg)
+
+#####
+# Test the basics
+
+test.write('SConstruct', """
+#from SCons.Tool.MSCommon.misc import FindMSVSBatFile, \\
+#                                       ParseBatFile, \\
+#                                       MergeMSVSBatFile
+from SCons.Tool.MSCommon import query_versions
+#env = Environment(tools = ['mingw'])
+DefaultEnvironment(tools = [])
+#for v in [9, 8, 7.1, 7]:
+#    print " ==== Testing for version %s ==== " % str(v)
+#    bat = FindMSVSBatFile(v)
+#    print bat
+#    if bat:
+#        d = ParseBatFile(bat)
+#        for k, v in d.items():
+#            print k, v
+#MergeMSVSBatFile(env, 9.0)
+#print env['ENV']['PATH']
+print query_versions()
+""")
+
+test.run(stderr = None)
+test.pass_test()
+
+# Local Variables:
+# tab-width:4
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=4 shiftwidth=4: