From 88c7995942cbf4af6a26f42ede8e940ff59c23e5 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Sat, 21 Feb 2009 16:58:07 +0000 Subject: Merged revisions 3088-3319,3321-3322,3324-3349,3351-3481,3483-3484,3486-3520,3522-3565,3567-3595,3597-3684,3686-3694,3696-3711,3713-3830,3832-3857,3859-3931,3933-3967,3969-3982,3984-3998,4000-4005,4007-4010,4012-4023 via svnmerge from 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 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. ................ --- QMTest/TestSConsMSVS.py | 31 +- doc/man/scons.1 | 1 + src/CHANGES.txt | 13 +- src/engine/MANIFEST-xml.in | 1 + src/engine/MANIFEST.in | 6 + src/engine/SCons/Errors.py | 3 + src/engine/SCons/Platform/PlatformTests.py | 2 + src/engine/SCons/Platform/win32.py | 25 +- src/engine/SCons/Tool/MSCommon/TODO | 5 + src/engine/SCons/Tool/MSCommon/__init__.py | 49 ++ src/engine/SCons/Tool/MSCommon/common.py | 177 +++++++ src/engine/SCons/Tool/MSCommon/msvc_changes.txt | 90 ++++ src/engine/SCons/Tool/MSCommon/netframework.py | 84 ++++ src/engine/SCons/Tool/MSCommon/sdk.py | 256 ++++++++++ src/engine/SCons/Tool/MSCommon/vs.py | 496 ++++++++++++++++++++ src/engine/SCons/Tool/linkloc.py | 13 +- src/engine/SCons/Tool/midl.py | 12 +- src/engine/SCons/Tool/mslib.py | 28 +- src/engine/SCons/Tool/mslink.py | 31 +- src/engine/SCons/Tool/mssdk.py | 64 +++ src/engine/SCons/Tool/mssdk.xml | 50 ++ src/engine/SCons/Tool/msvc.py | 592 +----------------------- src/engine/SCons/Tool/msvs.py | 408 +--------------- src/engine/SCons/Tool/msvs.xml | 15 +- src/engine/SCons/Tool/msvsTests.py | 186 ++++++-- src/engine/SCons/Util.py | 24 +- src/setup.py | 1 + test/Delete.py | 1 + test/Install/Install.py | 18 +- test/M4/M4.py | 9 +- test/MSVC/PCHSTOP-errors.py | 6 +- test/MSVC/msvc.py | 2 +- test/MSVC/query_vcbat.py | 66 +++ 33 files changed, 1621 insertions(+), 1144 deletions(-) create mode 100644 src/engine/SCons/Tool/MSCommon/TODO create mode 100644 src/engine/SCons/Tool/MSCommon/__init__.py create mode 100644 src/engine/SCons/Tool/MSCommon/common.py create mode 100644 src/engine/SCons/Tool/MSCommon/msvc_changes.txt create mode 100644 src/engine/SCons/Tool/MSCommon/netframework.py create mode 100644 src/engine/SCons/Tool/MSCommon/sdk.py create mode 100644 src/engine/SCons/Tool/MSCommon/vs.py create mode 100644 src/engine/SCons/Tool/mssdk.py create mode 100644 src/engine/SCons/Tool/mssdk.xml create mode 100644 test/MSVC/query_vcbat.py diff --git a/QMTest/TestSConsMSVS.py b/QMTest/TestSConsMSVS.py index 0408b67..8a85b3f 100644 --- a/QMTest/TestSConsMSVS.py +++ b/QMTest/TestSConsMSVS.py @@ -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 diff --git a/doc/man/scons.1 b/doc/man/scons.1 index ba51518..f3988f4 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -1776,6 +1776,7 @@ midl mingw mslib mslink +mssdk msvc msvs mwcc diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 6d5aa37..cb7fe8c 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -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 diff --git a/src/engine/MANIFEST-xml.in b/src/engine/MANIFEST-xml.in index f852e92..5a5c9b6 100644 --- a/src/engine/MANIFEST-xml.in +++ b/src/engine/MANIFEST-xml.in @@ -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 diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 203c4d9..ede9888 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -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 diff --git a/src/engine/SCons/Errors.py b/src/engine/SCons/Errors.py index fc45279..562cbcf 100644 --- a/src/engine/SCons/Errors.py +++ b/src/engine/SCons/Errors.py @@ -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 diff --git a/src/engine/SCons/Platform/PlatformTests.py b/src/engine/SCons/Platform/PlatformTests.py index 4f2e3d9..59d7e71 100644 --- a/src/engine/SCons/Platform/PlatformTests.py +++ b/src/engine/SCons/Platform/PlatformTests.py @@ -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): diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index 890b925..fb23d5d 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -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 index 0000000..be350b8 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/TODO @@ -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 index 0000000..a59bf15 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/__init__.py @@ -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 index 0000000..619b242 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/common.py @@ -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 index 0000000..e6acaa8 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/msvc_changes.txt @@ -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 index 0000000..8fee916 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/netframework.py @@ -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 index 0000000..80e6852 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/sdk.py @@ -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 index 0000000..a79d039 --- /dev/null +++ b/src/engine/SCons/Tool/MSCommon/vs.py @@ -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: diff --git a/src/engine/SCons/Tool/linkloc.py b/src/engine/SCons/Tool/linkloc.py index 43eb953..3aeb693 100644 --- a/src/engine/SCons/Tool/linkloc.py +++ b/src/engine/SCons/Tool/linkloc.py @@ -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 diff --git a/src/engine/SCons/Tool/midl.py b/src/engine/SCons/Tool/midl.py index 8347bc1..441f884 100644 --- a/src/engine/SCons/Tool/midl.py +++ b/src/engine/SCons/Tool/midl.py @@ -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 diff --git a/src/engine/SCons/Tool/mslib.py b/src/engine/SCons/Tool/mslib.py index dcb57fa..d23f63b 100644 --- a/src/engine/SCons/Tool/mslib.py +++ b/src/engine/SCons/Tool/mslib.py @@ -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 diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py index 2a2ec05..d2089d3 100644 --- a/src/engine/SCons/Tool/mslink.py +++ b/src/engine/SCons/Tool/mslink.py @@ -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 index 0000000..652a0c2 --- /dev/null +++ b/src/engine/SCons/Tool/mssdk.py @@ -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 index 0000000..bdfd394 --- /dev/null +++ b/src/engine/SCons/Tool/mssdk.xml @@ -0,0 +1,50 @@ + + + +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 environment variables +in the environment &SCons; uses to execute +the Microsoft toolchain: +%INCLUDE%, +%LIB%, +%LIBPATH% and +%PATH%. + + + + +MSSDK_DIR +MSSDK_VERSION +MSVS_VERSION + + + + + +The directory containing the Microsoft SDK +(either Platform SDK or Windows SDK) +to be used for compilation. + + + + + +The version string of the Microsoft SDK +(either Platform SDK or Windows SDK) +to be used for compilation. +Supported versions include +6.1, +6.0A, +6.0, +2003R2 +and +2003R1. + + diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py index 443e8b0..e68f982 100644 --- a/src/engine/SCons/Tool/msvc.py +++ b/src/engine/SCons/Tool/msvc.py @@ -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 diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py index f80564b..4d40d8c 100644 --- a/src/engine/SCons/Tool/msvs.py +++ b/src/engine/SCons/Tool/msvs.py @@ -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 diff --git a/src/engine/SCons/Tool/msvs.xml b/src/engine/SCons/Tool/msvs.xml index 91a196b..821bbca 100644 --- a/src/engine/SCons/Tool/msvs.xml +++ b/src/engine/SCons/Tool/msvs.xml @@ -238,7 +238,7 @@ this dictionary with the following keys: VERSION: the version of MSVS being used (can be set via -MSVS_VERSION) +&cv-link-MSVS_VERSION;) VERSIONS: the available versions of MSVS installed @@ -274,6 +274,19 @@ If a value isn't set, it wasn't available in the registry. + + +Sets the architecture for which the generated project(s) should build. + +The default value is x86. +amd64 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. + + + Tells the MS Visual Studio tools to use minimal INCLUDE, LIB, and PATH settings, diff --git a/src/engine/SCons/Tool/msvsTests.py b/src/engine/SCons/Tool/msvsTests.py index 40c6af6..1fb1e75 100644 --- a/src/engine/SCons/Tool/msvsTests.py +++ b/src/engine/SCons/Tool/msvsTests.py @@ -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) diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index d0f08a6..c77ee49 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -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': diff --git a/src/setup.py b/src/setup.py index b494b7c..9378770 100644 --- a/src/setup.py +++ b/src/setup.py @@ -401,6 +401,7 @@ arguments = { "SCons.Scanner", "SCons.Script", "SCons.Tool", + "SCons.Tool.MSCommon", "SCons.Tool.packaging", "SCons.Variables", ], diff --git a/test/Delete.py b/test/Delete.py index a7a3062..20dc889 100644 --- a/test/Delete.py +++ b/test/Delete.py @@ -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", ] diff --git a/test/Install/Install.py b/test/Install/Install.py index 8c461a7..ac84398 100644 --- a/test/Install/Install.py +++ b/test/Install/Install.py @@ -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() diff --git a/test/M4/M4.py b/test/M4/M4.py index d12bb28..44cda7c 100644 --- a/test/M4/M4.py +++ b/test/M4/M4.py @@ -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()) diff --git a/test/MSVC/PCHSTOP-errors.py b/test/MSVC/PCHSTOP-errors.py index 6ffd11a..a460283 100644 --- a/test/MSVC/PCHSTOP-errors.py +++ b/test/MSVC/PCHSTOP-errors.py @@ -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) diff --git a/test/MSVC/msvc.py b/test/MSVC/msvc.py index c8fa8dc..e28a87f 100644 --- a/test/MSVC/msvc.py +++ b/test/MSVC/msvc.py @@ -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 index 0000000..a662008 --- /dev/null +++ b/test/MSVC/query_vcbat.py @@ -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: -- cgit v0.12