about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorjyn <github@jyn.dev>2023-04-29 01:43:20 -0500
committerjyn <github@jyn.dev>2023-04-29 03:21:51 -0500
commit500c19c8ee2ed864fc21ac98d152e0ed19e849ea (patch)
treed90b4cffbef50293ceff4ad685837b53cc64d8ee /src/bootstrap
parent572c0d553f2bd1b934b08fe240310112369a5c76 (diff)
downloadrust-500c19c8ee2ed864fc21ac98d152e0ed19e849ea.tar.gz
rust-500c19c8ee2ed864fc21ac98d152e0ed19e849ea.zip
windows: kill rust-analyzer-proc-macro-srv before deleting stage0 directory
This fixes the following recurring error on windows:
```
Traceback (most recent call last):
  File "C:\Users\jyn\src\rust\x.py", line 29, in <module>
    bootstrap.main()
  File "C:\Users\jyn\src\rust\src\bootstrap\bootstrap.py", line 963, in main
    bootstrap(args)
  File "C:\Users\jyn\src\rust\src\bootstrap\bootstrap.py", line 927, in bootstrap
    build.download_toolchain()
  File "C:\Users\jyn\src\rust\src\bootstrap\bootstrap.py", line 437, in download_toolchain
    shutil.rmtree(bin_root)
  File "C:\Users\jyn\AppData\Local\Programs\Python\Python311\Lib\shutil.py", line 759, in rmtree
    return _rmtree_unsafe(path, onerror)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\jyn\AppData\Local\Programs\Python\Python311\Lib\shutil.py", line 617, in _rmtree_unsafe
    _rmtree_unsafe(fullname, onerror)
  File "C:\Users\jyn\AppData\Local\Programs\Python\Python311\Lib\shutil.py", line 622, in _rmtree_unsafe
    onerror(os.unlink, fullname, sys.exc_info())
  File "C:\Users\jyn\AppData\Local\Programs\Python\Python311\Lib\shutil.py", line 620, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 5] Access is denied: 'C:\\Users\\jyn\\src\\rust\\build\\x86_64-pc-windows-msvc\\stage0\\bin\\rust-analyzer-proc-macro-srv.exe'
```
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/bootstrap.py35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 9c6c917ac4a..ff261ab9832 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -19,7 +19,10 @@ try:
 except ImportError:
     lzma = None
 
-if sys.platform == 'win32':
+def platform_is_win32():
+    return sys.platform == 'win32'
+
+if platform_is_win32():
     EXE_SUFFIX = ".exe"
 else:
     EXE_SUFFIX = ""
@@ -78,7 +81,6 @@ def _download(path, url, probably_big, verbose, exception):
     if probably_big or verbose:
         print("downloading {}".format(url))
 
-    platform_is_win32 = sys.platform == 'win32'
     try:
         if probably_big or verbose:
             option = "-#"
@@ -86,7 +88,7 @@ def _download(path, url, probably_big, verbose, exception):
             option = "-s"
         # If curl is not present on Win32, we should not sys.exit
         #   but raise `CalledProcessError` or `OSError` instead
-        require(["curl", "--version"], exception=platform_is_win32)
+        require(["curl", "--version"], exception=platform_is_win32())
         with open(path, "wb") as outfile:
             run(["curl", option,
                 "-L", # Follow redirect.
@@ -99,8 +101,8 @@ def _download(path, url, probably_big, verbose, exception):
             )
     except (subprocess.CalledProcessError, OSError, RuntimeError):
         # see http://serverfault.com/questions/301128/how-to-download
-        if platform_is_win32:
-            run(["PowerShell.exe", "/nologo", "-Command",
+        if platform_is_win32():
+            run_powershell([
                  "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;",
                  "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')".format(url, path)],
                 verbose=verbose,
@@ -174,6 +176,10 @@ def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs):
         else:
             sys.exit(err)
 
+def run_powershell(script, *args, **kwargs):
+    """Run a powershell script"""
+    run(["PowerShell.exe", "/nologo", "-Command"] + script, *args, **kwargs)
+
 
 def require(cmd, exit=True, exception=False):
     '''Run a command, returning its output.
@@ -229,7 +235,7 @@ def default_build_triple(verbose):
                 print("pre-installed rustc not detected: {}".format(e))
                 print("falling back to auto-detect")
 
-    required = sys.platform != 'win32'
+    required = not platform_is_win32()
     ostype = require(["uname", "-s"], exit=required)
     cputype = require(['uname', '-m'], exit=required)
 
@@ -434,6 +440,23 @@ class RustBuild(object):
                 (not os.path.exists(self.rustc()) or
                  self.program_out_of_date(self.rustc_stamp(), key)):
             if os.path.exists(bin_root):
+                # HACK: On Windows, we can't delete rust-analyzer-proc-macro-server while it's
+                # running. Kill it.
+                if platform_is_win32():
+                    print("Killing rust-analyzer-proc-macro-srv before deleting stage0 toolchain")
+                    regex =  '{}\\\\(host|{})\\\\stage0\\\\libexec'.format(
+                        os.path.basename(self.build_dir),
+                        self.build
+                    )
+                    script = (
+                        # NOTE: can't use `taskkill` or `Get-Process -Name` because they error if
+                        # the server isn't running.
+                        'Get-Process | ' +
+                        'Where-Object {$_.Name -eq "rust-analyzer-proc-macro-srv"} |' +
+                        'Where-Object {{$_.Path -match "{}"}} |'.format(regex) +
+                        'Stop-Process'
+                    )
+                    run_powershell([script])
                 shutil.rmtree(bin_root)
             tarball_suffix = '.tar.gz' if lzma is None else '.tar.xz'
             filename = "rust-std-{}-{}{}".format(