diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f95551d679b..8b0a33841ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,9 +65,20 @@ jobs: - name: x86_64-gnu-tools os: ubuntu-20.04-16core-64gb env: {} + defaults: + run: + shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}" timeout-minutes: 600 runs-on: "${{ matrix.os }}" steps: + - if: "contains(matrix.os, 'windows')" + uses: msys2/setup-msys2@v2.22.0 + with: + msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}" + update: false + release: true + path-type: inherit + install: "make dos2unix diffutils\n" - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code @@ -461,9 +472,20 @@ jobs: RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-extended --enable-profiler" SCRIPT: python x.py dist bootstrap --include-default-paths os: windows-2019-8core-32gb + defaults: + run: + shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}" timeout-minutes: 600 runs-on: "${{ matrix.os }}" steps: + - if: "contains(matrix.os, 'windows')" + uses: msys2/setup-msys2@v2.22.0 + with: + msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}" + update: false + release: true + path-type: inherit + install: "make dos2unix diffutils\n" - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code @@ -589,9 +611,20 @@ jobs: env: CODEGEN_BACKENDS: "llvm,cranelift" os: ubuntu-20.04-16core-64gb + defaults: + run: + shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}" timeout-minutes: 600 runs-on: "${{ matrix.os }}" steps: + - if: "contains(matrix.os, 'windows')" + uses: msys2/setup-msys2@v2.22.0 + with: + msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}" + update: false + release: true + path-type: inherit + install: "make dos2unix diffutils\n" - name: disable git crlf conversion run: git config --global core.autocrlf false - name: checkout the source code diff --git a/INSTALL.md b/INSTALL.md index b872d317e36..d7e0fd72044 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -145,10 +145,9 @@ toolchain. 1. Download the latest [MSYS2 installer][msys2] and go through the installer. -2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from the MSYS2 installation - directory (e.g. `C:\msys64`), depending on whether you want 32-bit or 64-bit - Rust. (As of the latest version of MSYS2 you have to run `msys2_shell.cmd - -mingw32` or `msys2_shell.cmd -mingw64` from the command line instead.) +2. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit + or 64-bit Rust) either from your start menu, or by running `mingw64.exe` + or `mingw32.exe` from your MSYS2 installation directory (e.g. `C:\msys64`). 3. From this terminal, install the required tools: @@ -157,8 +156,7 @@ toolchain. pacman -Sy pacman-mirrors # Install build tools needed for Rust. If you're building a 32-bit compiler, - # then replace "x86_64" below with "i686". If you've already got Git, Python, - # or CMake installed and in PATH you can remove them from this list. + # then replace "x86_64" below with "i686". # Note that it is important that you do **not** use the 'python2', 'cmake', # and 'ninja' packages from the 'msys2' subsystem. # The build has historically been known to fail with these packages. @@ -175,9 +173,21 @@ toolchain. 4. Navigate to Rust's source code (or clone it), then build it: ```sh - python x.py setup user && python x.py build && python x.py install + python x.py setup dist && python x.py build && python x.py install ``` +If you want to use the native versions of Git, Python, or CMake you can remove +them from the above pacman command and install them from another source. Make +sure that they're in your Windows PATH, and edit the relevant `mingw[32|64].ini` +file in your MSYS2 installation directory by uncommenting the line +`MSYS2_PATH_TYPE=inherit` to include them in your MSYS2 PATH. + +Using Windows native Python can be helpful if you get errors when building LLVM. +You may also want to use Git for Windows, as it is often *much* faster. Turning +off real-time protection in the Windows Virus & Threat protections settings can +also help with long run times (although note that it will automatically turn +itself back on after some time). + ### MSVC MSVC builds of Rust additionally require an installation of Visual Studio 2017 diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 834025c8188..875a4efae02 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1235,12 +1235,16 @@ pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfi // Infer the rest of the configuration. // Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary, - // running on a completely machine from where it was compiled. + // running on a completely different machine from where it was compiled. let mut cmd = Command::new("git"); - // NOTE: we cannot support running from outside the repository because the only path we have available - // is set at compile time, which can be wrong if bootstrap was downloaded from source. + // NOTE: we cannot support running from outside the repository because the only other path we have available + // is set at compile time, which can be wrong if bootstrap was downloaded rather than compiled locally. // We still support running outside the repository if we find we aren't in a git directory. - cmd.arg("rev-parse").arg("--show-toplevel"); + + // NOTE: We get a relative path from git to work around an issue on MSYS/mingw. If we used an absolute path, + // and end up using MSYS's git rather than git-for-windows, we would get a unix-y MSYS path. But as bootstrap + // has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path. + cmd.arg("rev-parse").arg("--show-cdup"); // Discard stderr because we expect this to fail when building from a tarball. let output = cmd .stderr(std::process::Stdio::null()) @@ -1248,13 +1252,18 @@ pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfi .ok() .and_then(|output| if output.status.success() { Some(output) } else { None }); if let Some(output) = output { - let git_root = String::from_utf8(output.stdout).unwrap(); - // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes. - let git_root = PathBuf::from(git_root.trim()).canonicalize().unwrap(); + let git_root_relative = String::from_utf8(output.stdout).unwrap(); + // We need to canonicalize this path to make sure it uses backslashes instead of forward slashes, + // and to resolve any relative components. + let git_root = env::current_dir() + .unwrap() + .join(PathBuf::from(git_root_relative.trim())) + .canonicalize() + .unwrap(); let s = git_root.to_str().unwrap(); // Bootstrap is quite bad at handling /? in front of paths - let src = match s.strip_prefix("\\\\?\\") { + let git_root = match s.strip_prefix("\\\\?\\") { Some(p) => PathBuf::from(p), None => git_root, }; @@ -1264,8 +1273,8 @@ pub(crate) fn parse_inner(args: &[String], get_toml: impl Fn(&Path) -> TomlConfi // // NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside // the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1. - if src.join("src").join("stage0.json").exists() { - config.src = src; + if git_root.join("src").join("stage0.json").exists() { + config.src = git_root; } } else { // We're building from a tarball, not git sources. diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 9b0f477409a..58d5dec9ba5 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -111,10 +111,31 @@ x--expand-yaml-anchors--remove: if: success() && !env.SKIP_JOB - &base-ci-job + defaults: + run: + shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }} timeout-minutes: 600 runs-on: "${{ matrix.os }}" env: *shared-ci-variables steps: + - if: contains(matrix.os, 'windows') + uses: msys2/setup-msys2@v2.22.0 + with: + # i686 jobs use mingw32. x86_64 and cross-compile jobs use mingw64. + msystem: ${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }} + # don't try to download updates for already installed packages + update: false + # don't try to use the msys that comes built-in to the github runner, + # so we can control what is installed (i.e. not python) + release: true + # Inherit the full path from the Windows environment, with MSYS2's */bin/ + # dirs placed in front. This lets us run Windows-native Python etc. + path-type: inherit + install: > + make + dos2unix + diffutils + - name: disable git crlf conversion run: git config --global core.autocrlf false diff --git a/src/ci/run.sh b/src/ci/run.sh index 1cdcffc1a75..3ad04c73d3d 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -76,7 +76,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=balance # the LLVM build, as not to run out of memory. # This is an attempt to fix the spurious build error tracked by # https://github.com/rust-lang/rust/issues/108227. -if isWindows && [[ ${CUSTOM_MINGW-0} -eq 1 ]]; then +if isKnownToBeMingwBuild; then RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.link-jobs=1" fi diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index 77164ed4117..aa7ff813f51 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -37,8 +37,7 @@ if isMacOS; then # Configure `AR` specifically so rustbuild doesn't try to infer it as # `clang-ar` by accident. ciCommandSetEnv AR "ar" -elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then - +elif isWindows && ! isKnownToBeMingwBuild; then # If we're compiling for MSVC then we, like most other distribution builders, # switch to clang as the compiler. This'll allow us eventually to enable LTO # amongst LLVM and rustc. Note that we only do this on MSVC as I don't think diff --git a/src/ci/scripts/install-mingw.sh b/src/ci/scripts/install-mingw.sh index 7eccb9b8650..87b835b63db 100755 --- a/src/ci/scripts/install-mingw.sh +++ b/src/ci/scripts/install-mingw.sh @@ -38,11 +38,11 @@ if isWindows; then ;; esac - if [[ "${CUSTOM_MINGW-0}" -ne 1 ]]; then - pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake \ - mingw-w64-$arch-gcc \ - mingw-w64-$arch-python # the python package is actually for python3 - ciCommandAddPath "$(ciCheckoutPath)/msys2/mingw${bits}/bin" + if [[ "${CUSTOM_MINGW:-0}" == 0 ]]; then + pacboy -S --noconfirm toolchain:p + # According to the comment in the Windows part of install-clang.sh, in the future we might + # want to do this instead: + # pacboy -S --noconfirm clang:p ... else mingw_dir="mingw${bits}" diff --git a/src/ci/scripts/install-msys2.sh b/src/ci/scripts/install-msys2.sh index 0aa4b42a6a8..905edf38a09 100755 --- a/src/ci/scripts/install-msys2.sh +++ b/src/ci/scripts/install-msys2.sh @@ -1,17 +1,12 @@ #!/bin/bash -# Download and install MSYS2, needed primarily for the test suite (run-make) but -# also used by the MinGW toolchain for assembling things. +# Clean up and prepare the MSYS2 installation. MSYS2 is needed primarily for +# the test suite (run-make), but is also used by the MinGW toolchain for assembling things. set -euo pipefail IFS=$'\n\t' source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" - if isWindows; then - msys2Path="c:/msys64" - mkdir -p "${msys2Path}/home/${USERNAME}" - ciCommandAddPath "${msys2Path}/usr/bin" - # Detect the native Python version installed on the agent. On GitHub # Actions, the C:\hostedtoolcache\windows\Python directory contains a # subdirectory for each installed Python version. @@ -29,4 +24,33 @@ if isWindows; then fi ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64" ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64\\Scripts" + + # Install pacboy for easily installing packages + pacman -S --noconfirm pactoys + + # Delete these pre-installed tools so we can't accidentally use them, because we are using the + # MSYS2 setup action versions instead. + # Delete pre-installed version of MSYS2 + rm -r "/c/msys64/" + # Delete Strawberry Perl, which contains a version of mingw + rm -r "/c/Strawberry/" + # Delete these other copies of mingw, I don't even know where they come from. + rm -r "/c/mingw64/" + rm -r "/c/mingw32/" + + if isKnownToBeMingwBuild; then + # Use the mingw version of CMake for mingw builds. + # However, the MSVC build needs native CMake, as it fails with the mingw one. + # Delete native CMake + rm -r "/c/Program Files/CMake/" + # Install mingw-w64-$arch-cmake + pacboy -S --noconfirm cmake:p + + # We use Git-for-Windows for MSVC builds, and MSYS2 Git for mingw builds, + # so that both are tested. + # Delete Windows-Git + rm -r "/c/Program Files/Git/" + # Install MSYS2 git + pacman -S --noconfirm git + fi fi diff --git a/src/ci/shared.sh b/src/ci/shared.sh index 720394af249..2b0a10e4d08 100644 --- a/src/ci/shared.sh +++ b/src/ci/shared.sh @@ -52,6 +52,10 @@ function isLinux { [[ "${OSTYPE}" = "linux-gnu" ]] } +function isKnownToBeMingwBuild { + isGitHubActions && [[ "${CI_JOB_NAME}" == *mingw ]] +} + function isCiBranch { if [[ $# -ne 1 ]]; then echo "usage: $0 "