Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error about missing SYSTEMROOT environment variable with MSVC2013 Express #471

Open
GoogleCodeExporter opened this issue Apr 3, 2015 · 1 comment

Comments

@GoogleCodeExporter
Copy link

When I run gyp, I get an error about an invalid SYSTEMROOT environment 
variable.  Here's the command-line output:

    C:\...\atom\atom-shell>..\..\gyp-read-only\gyp.bat -f ninja --depth . atom.gyp -Icommon.gypi -Ivendor/brightray/brightray.gypi -Dlinux_clang=0 -Dtarget_arch=ia32 -Dlibrary=static_library
    Traceback (most recent call last):
      File "C:\...\gyp-read-only\gyp_main.py", line 18, in <module>
        sys.exit(gyp.script_main())
      File "C:\...\gyp-read-only\pylib\gyp\__init__.py", line 532, in script_main
        return main(sys.argv[1:])
      File "C:\...\gyp-read-only\pylib\gyp\__init__.py", line 525, in main
        return gyp_main(args)
      File "C:\...\gyp-read-only\pylib\gyp\__init__.py", line 510, in gyp_main
        generator.GenerateOutput(flat_list, targets, data, params)
      File "C:\...\gyp-read-only\pylib\gyp\generator\ninja.py", line 2376, in GenerateOutput
        pool.map(CallGenerateOutputForConfig, arglists)
      File "C:\Python27\lib\multiprocessing\pool.py", line 251, in map
        return self.map_async(func, iterable, chunksize).get()
      File "C:\Python27\lib\multiprocessing\pool.py", line 558, in get
        raise self._value
    Exception: Environment variable "SYSTEMROOT" required to be set to valid path

The error is misleading; the problem isn't really SYSTEMROOT.

The problem only happens when I run gyp in a VC command prompt, which defines 
WindowsSDKDir.  _DetectVisualStudioVersions decides that I have a single Visual 
Studio install:

   name: 2013e
   path: C:\msvs12\VC\..
   sdk_based: True

This is correct.  My machine has Visual Studio 2013 Express installed, and no 
other copies of Visual Studio or any Windows SDKs.

The root problem is that MSVSVersion.SetupScript returns a path to a 
non-existent file:

      def SetupScript(self, target_arch):
        """Returns a command (with arguments) to be used to set up the
        environment."""
        # Check if we are running in the SDK command line environment and use
        # the setup script from the SDK if so. |target_arch| should be either
        # 'x86' or 'x64'.
        assert target_arch in ('x86', 'x64')
        sdk_dir = os.environ.get('WindowsSDKDir')
        if self.sdk_based and sdk_dir:
          return [os.path.normpath(os.path.join(sdk_dir, 'Bin/SetEnv.Cmd')),
                  '/' + target_arch]
        ...

Because I have the VC vars set, WindowsSDKDir is set.  Its value is:

    C:\Program Files\Windows Kits\8.1\

MSVSVersion.SetupScript therefore returns:

    ['C:\\Program Files\\Windows Kits\\8.1\\Bin\\SetEnv.Cmd', '/x86']

My Windows Kits directory has 8.0 and 8.1 subdirectories.  There is no 
SetEnv.Cmd (or anything similar) in any of them.  (Looking just at 8.1, there 
is a Bin directory, and it has arm, x86, and x64 subdirectories.)

The lack of error handling makes things worse.  In GenerateEnvironmentFiles, we 
have this code:

    # Extract environment variables for subprocesses.
    args = vs.SetupScript(arch)
    args.extend(('&&', 'set'))
    popen = subprocess.Popen(
        args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    variables, _ = popen.communicate()
    env = _ExtractImportantEnvironment(variables)

We're running the command:

    ['C:\\Program Files\\Windows Kits\\8.1\\Bin\\SetEnv.Cmd', '/x86', '&&', 'set']

The command finishes with return code 1 (indicating error, even in Windows, 
AFAIK).  We combine stdout and stderr, so we don't print cmd's failure output:

    '"C:\Program Files\Windows Kits\8.1\Bin\SetEnv.Cmd"' is not recognized as an internal or external command,
    operable program or batch file.

gyp doesn't check the error code, so it calls _ExtractImportantEnvironment, 
which decides that SYSTEMROOT isn't set.  This makes sense, because SET didn't 
run.

I'd suggest replacing these lines with subprocess.check_output, which is 
simpler, but that function tries to raise a subprocess.CalledProcessError, and 
something goes horribly wrong with the threading/processes, and instead of a 
meaningful error message, we get a complaint that CalledProcessError is 
constructed with the wrong number of arguments.  (I tried raising a 
locally-defined exception class, and I got a pickling error.)  check_output 
also requires Python 2.7; not sure what gyp's requirements are.

Instead, I'd suggest this patch.  It works for me (once I unset WindowsSDKDir), 
but perhaps some other VC installs print noise to stderr, so maybe we want to 
suppress stderr instead.  stderr=subprocess.STDOUT is always wrong, though, 
unless we're expecting _ExtractImportantEnvironment to examine the setup script 
output.  To suppress stderr, I think we'd use stderr=subprocess.PIPE.  (We 
already discard popen.communicate()'s error output.)

Index: pylib/gyp/msvs_emulation.py
===================================================================
--- pylib/gyp/msvs_emulation.py (revision 2012)
+++ pylib/gyp/msvs_emulation.py (working copy)
@@ -1002,8 +1002,10 @@
     args = vs.SetupScript(arch)
     args.extend(('&&', 'set'))
     popen = subprocess.Popen(
-        args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+        args, shell=True, stdout=subprocess.PIPE)
     variables, _ = popen.communicate()
+    if popen.returncode != 0:
+      raise Exception('Error invoking setup script: ' + repr(args))
     env = _ExtractImportantEnvironment(variables)

     # Inject system includes from gyp files into INCLUDE.

FWIW, my machine is a 32-bit Windows 7 Ultimate SP1 VM.

I hit this problem while building atom-shell, which uses gyp.  I reproduced it 
using the latest SVN source for gyp.

Original issue reported on code.google.com by ryan.pri...@gmail.com on 4 Dec 2014 at 12:28

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant