Skip to content

Commit 0ecbd06

Browse files
committed
Auto merge of #121182 - majaha:mingw_ci_new, r=Mark-Simulacrum
Improvements to building and CI for mingw/msys I was getting error messages when trying to follow the build instructions the mingw build for Rust, and managed to track the issue down to an incomparability of Rust's bootstrap program with MSYS2's version of git. Essentially, the problem is that MSYS2's git works in emulated unix-y paths, but bootstrap expects a Windows path. I found a workaround for this by using relative paths instead of absolute paths. Along with that fix, this PR also updates the build instructions for MinGW to be compatible with modern versions of MSYS2, and some changes to CI to make sure that MSYS2's version of git is tested. In particular, I'm suggesting using the [MSYS2 github action](https://github.com/marketplace/actions/setup-msys2) specially made for this purpose, which is much less hacky than the old approach and gives us more control of what packages are installed. I also cleaned up as many alternate versions of key tools as I could find from PATH, to avoid accidental usage, and cleaned up some abuses of the `CUSTOM_MINGW` environment variable. This fixes #105696 and fixes #117567
2 parents b0d3e04 + e27c472 commit 0ecbd06

File tree

9 files changed

+132
-32
lines changed

9 files changed

+132
-32
lines changed

.github/workflows/ci.yml

+33
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,20 @@ jobs:
6565
- name: x86_64-gnu-tools
6666
os: ubuntu-20.04-16core-64gb
6767
env: {}
68+
defaults:
69+
run:
70+
shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
6871
timeout-minutes: 600
6972
runs-on: "${{ matrix.os }}"
7073
steps:
74+
- if: "contains(matrix.os, 'windows')"
75+
uses: msys2/[email protected]
76+
with:
77+
msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}"
78+
update: false
79+
release: true
80+
path-type: inherit
81+
install: "make dos2unix diffutils\n"
7182
- name: disable git crlf conversion
7283
run: git config --global core.autocrlf false
7384
- name: checkout the source code
@@ -461,9 +472,20 @@ jobs:
461472
RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --enable-extended --enable-profiler"
462473
SCRIPT: python x.py dist bootstrap --include-default-paths
463474
os: windows-2019-8core-32gb
475+
defaults:
476+
run:
477+
shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
464478
timeout-minutes: 600
465479
runs-on: "${{ matrix.os }}"
466480
steps:
481+
- if: "contains(matrix.os, 'windows')"
482+
uses: msys2/[email protected]
483+
with:
484+
msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}"
485+
update: false
486+
release: true
487+
path-type: inherit
488+
install: "make dos2unix diffutils\n"
467489
- name: disable git crlf conversion
468490
run: git config --global core.autocrlf false
469491
- name: checkout the source code
@@ -589,9 +611,20 @@ jobs:
589611
env:
590612
CODEGEN_BACKENDS: "llvm,cranelift"
591613
os: ubuntu-20.04-16core-64gb
614+
defaults:
615+
run:
616+
shell: "${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}"
592617
timeout-minutes: 600
593618
runs-on: "${{ matrix.os }}"
594619
steps:
620+
- if: "contains(matrix.os, 'windows')"
621+
uses: msys2/[email protected]
622+
with:
623+
msystem: "${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}"
624+
update: false
625+
release: true
626+
path-type: inherit
627+
install: "make dos2unix diffutils\n"
595628
- name: disable git crlf conversion
596629
run: git config --global core.autocrlf false
597630
- name: checkout the source code

INSTALL.md

+17-7
Original file line numberDiff line numberDiff line change
@@ -145,10 +145,9 @@ toolchain.
145145

146146
1. Download the latest [MSYS2 installer][msys2] and go through the installer.
147147

148-
2. Run `mingw32_shell.bat` or `mingw64_shell.bat` from the MSYS2 installation
149-
directory (e.g. `C:\msys64`), depending on whether you want 32-bit or 64-bit
150-
Rust. (As of the latest version of MSYS2 you have to run `msys2_shell.cmd
151-
-mingw32` or `msys2_shell.cmd -mingw64` from the command line instead.)
148+
2. Start a MINGW64 or MINGW32 shell (depending on whether you want 32-bit
149+
or 64-bit Rust) either from your start menu, or by running `mingw64.exe`
150+
or `mingw32.exe` from your MSYS2 installation directory (e.g. `C:\msys64`).
152151

153152
3. From this terminal, install the required tools:
154153

@@ -157,8 +156,7 @@ toolchain.
157156
pacman -Sy pacman-mirrors
158157

159158
# Install build tools needed for Rust. If you're building a 32-bit compiler,
160-
# then replace "x86_64" below with "i686". If you've already got Git, Python,
161-
# or CMake installed and in PATH you can remove them from this list.
159+
# then replace "x86_64" below with "i686".
162160
# Note that it is important that you do **not** use the 'python2', 'cmake',
163161
# and 'ninja' packages from the 'msys2' subsystem.
164162
# The build has historically been known to fail with these packages.
@@ -175,9 +173,21 @@ toolchain.
175173
4. Navigate to Rust's source code (or clone it), then build it:
176174

177175
```sh
178-
python x.py setup user && python x.py build && python x.py install
176+
python x.py setup dist && python x.py build && python x.py install
179177
```
180178

179+
If you want to use the native versions of Git, Python, or CMake you can remove
180+
them from the above pacman command and install them from another source. Make
181+
sure that they're in your Windows PATH, and edit the relevant `mingw[32|64].ini`
182+
file in your MSYS2 installation directory by uncommenting the line
183+
`MSYS2_PATH_TYPE=inherit` to include them in your MSYS2 PATH.
184+
185+
Using Windows native Python can be helpful if you get errors when building LLVM.
186+
You may also want to use Git for Windows, as it is often *much* faster. Turning
187+
off real-time protection in the Windows Virus & Threat protections settings can
188+
also help with long run times (although note that it will automatically turn
189+
itself back on after some time).
190+
181191
### MSVC
182192

183193
MSVC builds of Rust additionally require an installation of Visual Studio 2017

src/bootstrap/src/core/config/config.rs

+19-10
Original file line numberDiff line numberDiff line change
@@ -1235,26 +1235,35 @@ impl Config {
12351235
// Infer the rest of the configuration.
12361236

12371237
// Infer the source directory. This is non-trivial because we want to support a downloaded bootstrap binary,
1238-
// running on a completely machine from where it was compiled.
1238+
// running on a completely different machine from where it was compiled.
12391239
let mut cmd = Command::new("git");
1240-
// NOTE: we cannot support running from outside the repository because the only path we have available
1241-
// is set at compile time, which can be wrong if bootstrap was downloaded from source.
1240+
// NOTE: we cannot support running from outside the repository because the only other path we have available
1241+
// is set at compile time, which can be wrong if bootstrap was downloaded rather than compiled locally.
12421242
// We still support running outside the repository if we find we aren't in a git directory.
1243-
cmd.arg("rev-parse").arg("--show-toplevel");
1243+
1244+
// NOTE: We get a relative path from git to work around an issue on MSYS/mingw. If we used an absolute path,
1245+
// and end up using MSYS's git rather than git-for-windows, we would get a unix-y MSYS path. But as bootstrap
1246+
// has already been (kinda-cross-)compiled to Windows land, we require a normal Windows path.
1247+
cmd.arg("rev-parse").arg("--show-cdup");
12441248
// Discard stderr because we expect this to fail when building from a tarball.
12451249
let output = cmd
12461250
.stderr(std::process::Stdio::null())
12471251
.output()
12481252
.ok()
12491253
.and_then(|output| if output.status.success() { Some(output) } else { None });
12501254
if let Some(output) = output {
1251-
let git_root = String::from_utf8(output.stdout).unwrap();
1252-
// We need to canonicalize this path to make sure it uses backslashes instead of forward slashes.
1253-
let git_root = PathBuf::from(git_root.trim()).canonicalize().unwrap();
1255+
let git_root_relative = String::from_utf8(output.stdout).unwrap();
1256+
// We need to canonicalize this path to make sure it uses backslashes instead of forward slashes,
1257+
// and to resolve any relative components.
1258+
let git_root = env::current_dir()
1259+
.unwrap()
1260+
.join(PathBuf::from(git_root_relative.trim()))
1261+
.canonicalize()
1262+
.unwrap();
12541263
let s = git_root.to_str().unwrap();
12551264

12561265
// Bootstrap is quite bad at handling /? in front of paths
1257-
let src = match s.strip_prefix("\\\\?\\") {
1266+
let git_root = match s.strip_prefix("\\\\?\\") {
12581267
Some(p) => PathBuf::from(p),
12591268
None => git_root,
12601269
};
@@ -1264,8 +1273,8 @@ impl Config {
12641273
//
12651274
// NOTE: this implies that downloadable bootstrap isn't supported when the build directory is outside
12661275
// the source directory. We could fix that by setting a variable from all three of python, ./x, and x.ps1.
1267-
if src.join("src").join("stage0.json").exists() {
1268-
config.src = src;
1276+
if git_root.join("src").join("stage0.json").exists() {
1277+
config.src = git_root;
12691278
}
12701279
} else {
12711280
// We're building from a tarball, not git sources.

src/ci/github-actions/ci.yml

+21
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,31 @@ x--expand-yaml-anchors--remove:
111111
if: success() && !env.SKIP_JOB
112112

113113
- &base-ci-job
114+
defaults:
115+
run:
116+
shell: ${{ contains(matrix.os, 'windows') && 'msys2 {0}' || 'bash' }}
114117
timeout-minutes: 600
115118
runs-on: "${{ matrix.os }}"
116119
env: *shared-ci-variables
117120
steps:
121+
- if: contains(matrix.os, 'windows')
122+
uses: msys2/[email protected]
123+
with:
124+
# i686 jobs use mingw32. x86_64 and cross-compile jobs use mingw64.
125+
msystem: ${{ contains(matrix.name, 'i686') && 'mingw32' || 'mingw64' }}
126+
# don't try to download updates for already installed packages
127+
update: false
128+
# don't try to use the msys that comes built-in to the github runner,
129+
# so we can control what is installed (i.e. not python)
130+
release: true
131+
# Inherit the full path from the Windows environment, with MSYS2's */bin/
132+
# dirs placed in front. This lets us run Windows-native Python etc.
133+
path-type: inherit
134+
install: >
135+
make
136+
dos2unix
137+
diffutils
138+
118139
- name: disable git crlf conversion
119140
run: git config --global core.autocrlf false
120141

src/ci/run.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=balance
7676
# the LLVM build, as not to run out of memory.
7777
# This is an attempt to fix the spurious build error tracked by
7878
# https://github.com/rust-lang/rust/issues/108227.
79-
if isWindows && [[ ${CUSTOM_MINGW-0} -eq 1 ]]; then
79+
if isKnownToBeMingwBuild; then
8080
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.link-jobs=1"
8181
fi
8282

src/ci/scripts/install-clang.sh

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ if isMacOS; then
3737
# Configure `AR` specifically so rustbuild doesn't try to infer it as
3838
# `clang-ar` by accident.
3939
ciCommandSetEnv AR "ar"
40-
elif isWindows && [[ ${CUSTOM_MINGW-0} -ne 1 ]]; then
41-
40+
elif isWindows && ! isKnownToBeMingwBuild; then
4241
# If we're compiling for MSVC then we, like most other distribution builders,
4342
# switch to clang as the compiler. This'll allow us eventually to enable LTO
4443
# amongst LLVM and rustc. Note that we only do this on MSVC as I don't think

src/ci/scripts/install-mingw.sh

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@ if isWindows; then
3838
;;
3939
esac
4040

41-
if [[ "${CUSTOM_MINGW-0}" -ne 1 ]]; then
42-
pacman -S --noconfirm --needed mingw-w64-$arch-toolchain mingw-w64-$arch-cmake \
43-
mingw-w64-$arch-gcc \
44-
mingw-w64-$arch-python # the python package is actually for python3
45-
ciCommandAddPath "$(ciCheckoutPath)/msys2/mingw${bits}/bin"
41+
if [[ "${CUSTOM_MINGW:-0}" == 0 ]]; then
42+
pacboy -S --noconfirm toolchain:p
43+
# According to the comment in the Windows part of install-clang.sh, in the future we might
44+
# want to do this instead:
45+
# pacboy -S --noconfirm clang:p ...
4646
else
4747
mingw_dir="mingw${bits}"
4848

src/ci/scripts/install-msys2.sh

+31-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
#!/bin/bash
2-
# Download and install MSYS2, needed primarily for the test suite (run-make) but
3-
# also used by the MinGW toolchain for assembling things.
2+
# Clean up and prepare the MSYS2 installation. MSYS2 is needed primarily for
3+
# the test suite (run-make), but is also used by the MinGW toolchain for assembling things.
44

55
set -euo pipefail
66
IFS=$'\n\t'
77

88
source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
9-
109
if isWindows; then
11-
msys2Path="c:/msys64"
12-
mkdir -p "${msys2Path}/home/${USERNAME}"
13-
ciCommandAddPath "${msys2Path}/usr/bin"
14-
1510
# Detect the native Python version installed on the agent. On GitHub
1611
# Actions, the C:\hostedtoolcache\windows\Python directory contains a
1712
# subdirectory for each installed Python version.
@@ -29,4 +24,33 @@ if isWindows; then
2924
fi
3025
ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64"
3126
ciCommandAddPath "C:\\hostedtoolcache\\windows\\Python\\${native_python_version}\\x64\\Scripts"
27+
28+
# Install pacboy for easily installing packages
29+
pacman -S --noconfirm pactoys
30+
31+
# Delete these pre-installed tools so we can't accidentally use them, because we are using the
32+
# MSYS2 setup action versions instead.
33+
# Delete pre-installed version of MSYS2
34+
rm -r "/c/msys64/"
35+
# Delete Strawberry Perl, which contains a version of mingw
36+
rm -r "/c/Strawberry/"
37+
# Delete these other copies of mingw, I don't even know where they come from.
38+
rm -r "/c/mingw64/"
39+
rm -r "/c/mingw32/"
40+
41+
if isKnownToBeMingwBuild; then
42+
# Use the mingw version of CMake for mingw builds.
43+
# However, the MSVC build needs native CMake, as it fails with the mingw one.
44+
# Delete native CMake
45+
rm -r "/c/Program Files/CMake/"
46+
# Install mingw-w64-$arch-cmake
47+
pacboy -S --noconfirm cmake:p
48+
49+
# We use Git-for-Windows for MSVC builds, and MSYS2 Git for mingw builds,
50+
# so that both are tested.
51+
# Delete Windows-Git
52+
rm -r "/c/Program Files/Git/"
53+
# Install MSYS2 git
54+
pacman -S --noconfirm git
55+
fi
3256
fi

src/ci/shared.sh

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ function isLinux {
5252
[[ "${OSTYPE}" = "linux-gnu" ]]
5353
}
5454

55+
function isKnownToBeMingwBuild {
56+
isGitHubActions && [[ "${CI_JOB_NAME}" == *mingw ]]
57+
}
58+
5559
function isCiBranch {
5660
if [[ $# -ne 1 ]]; then
5761
echo "usage: $0 <branch-name>"

0 commit comments

Comments
 (0)