From 016e60d1e038c972066e1f5b9d3738f6aa094272 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Tue, 23 Jun 2026 15:16:08 +1100 Subject: [PATCH 1/4] add msvr --- .github/setup-rust-windows/action.yml | 4 ++-- .github/workflows/build.yml | 8 ++++---- .github/workflows/reusable-wasi.yml | 4 ++-- Cargo.toml | 4 ++++ Modules/_base64/Cargo.toml | 1 + Modules/cpython-build-helper/Cargo.toml | 1 + Modules/cpython-rust-staticlib/Cargo.toml | 1 + Modules/cpython-sys/Cargo.toml | 1 + rust-toolchain.toml | 3 --- 9 files changed, 16 insertions(+), 11 deletions(-) delete mode 100644 rust-toolchain.toml diff --git a/.github/setup-rust-windows/action.yml b/.github/setup-rust-windows/action.yml index 2e130094282270f..1ad913e4e9b9216 100644 --- a/.github/setup-rust-windows/action.yml +++ b/.github/setup-rust-windows/action.yml @@ -11,9 +11,9 @@ inputs: runs: using: composite steps: - - uses: dtolnay/rust-toolchain@ab40b01f54fe82bdf65693ea090a1e4942c136e7 # 1.91.1 + - uses: dtolnay/rust-toolchain@f133eefe930d61f0d9371efd474daf0125ed3dd1 # 1.95.0 with: - toolchain: 1.91.1 + toolchain: 1.95.0 targets: i686-pc-windows-msvc,x86_64-pc-windows-msvc,aarch64-pc-windows-msvc # LIBCLANG_PATH must be set explicitly so the vcxproj uses the LLVM we # install here rather than the VS-bundled LLVM whose clang headers have diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4704f061899acf2..90ae3a5ec16076e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -353,9 +353,9 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: dtolnay/rust-toolchain@ab40b01f54fe82bdf65693ea090a1e4942c136e7 # 1.91.1 + - uses: dtolnay/rust-toolchain@f133eefe930d61f0d9371efd474daf0125ed3dd1 # 1.95.0 with: - toolchain: 1.91.1 + toolchain: 1.95.0 targets: ${{ matrix.arch }}-linux-android - name: Build and test run: JAVA_HOME="${JAVA_HOME_21_X64:-$JAVA_HOME_21_arm64}" python3 Platforms/Android ci --fast-ci ${{ matrix.arch }}-linux-android @@ -370,9 +370,9 @@ jobs: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false - - uses: dtolnay/rust-toolchain@ab40b01f54fe82bdf65693ea090a1e4942c136e7 # 1.91.1 + - uses: dtolnay/rust-toolchain@f133eefe930d61f0d9371efd474daf0125ed3dd1 # 1.95.0 with: - toolchain: 1.91.1 + toolchain: 1.95.0 targets: aarch64-apple-ios-sim # GitHub recommends explicitly selecting the desired Xcode version: # https://github.com/actions/runner-images/issues/12541#issuecomment-3083850140 diff --git a/.github/workflows/reusable-wasi.yml b/.github/workflows/reusable-wasi.yml index 935ca8fb5379490..431c52fc49cbffc 100644 --- a/.github/workflows/reusable-wasi.yml +++ b/.github/workflows/reusable-wasi.yml @@ -47,9 +47,9 @@ jobs: uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: '3.x' - - uses: dtolnay/rust-toolchain@ab40b01f54fe82bdf65693ea090a1e4942c136e7 # 1.91.1 + - uses: dtolnay/rust-toolchain@f133eefe930d61f0d9371efd474daf0125ed3dd1 # 1.95.0 with: - toolchain: 1.91.1 + toolchain: 1.95.0 targets: wasm32-wasip1 - name: "Runner image version" run: echo "IMAGE_OS_VERSION=${ImageOS}-${ImageVersion}" >> "$GITHUB_ENV" diff --git a/Cargo.toml b/Cargo.toml index 768d289fd77653e..0eecc3f7643a67b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,3 +4,7 @@ members = [ "Modules/_base64", "Modules/cpython-build-helper", "Modules/cpython-rust-staticlib", "Modules/cpython-sys" ] + +[workspace.package] +# Make sure to also update the Rust toolchains in GitHub Actions whenever this version is modified +rust-version = "1.95" diff --git a/Modules/_base64/Cargo.toml b/Modules/_base64/Cargo.toml index f90350624729d65..dbe739fa7a19b46 100644 --- a/Modules/_base64/Cargo.toml +++ b/Modules/_base64/Cargo.toml @@ -2,6 +2,7 @@ name = "_base64" version = "0.1.0" edition = "2024" +rust-version.workspace = true [dependencies] cpython-sys ={ path = "../cpython-sys" } diff --git a/Modules/cpython-build-helper/Cargo.toml b/Modules/cpython-build-helper/Cargo.toml index 1369020965012a2..193808546be285d 100644 --- a/Modules/cpython-build-helper/Cargo.toml +++ b/Modules/cpython-build-helper/Cargo.toml @@ -2,6 +2,7 @@ name = "cpython-build-helper" version = "0.1.0" edition = "2024" +rust-version.workspace = true [dependencies] shlex = "1.3" diff --git a/Modules/cpython-rust-staticlib/Cargo.toml b/Modules/cpython-rust-staticlib/Cargo.toml index d7f52b0f3e96026..2b21ab576a09c31 100644 --- a/Modules/cpython-rust-staticlib/Cargo.toml +++ b/Modules/cpython-rust-staticlib/Cargo.toml @@ -2,6 +2,7 @@ name = "cpython-rust-staticlib" version = "0.1.0" edition = "2024" +rust-version.workspace = true [dependencies] _base64 ={ path = "../_base64" } diff --git a/Modules/cpython-sys/Cargo.toml b/Modules/cpython-sys/Cargo.toml index a12556c6e305a17..7553282217dc74e 100644 --- a/Modules/cpython-sys/Cargo.toml +++ b/Modules/cpython-sys/Cargo.toml @@ -2,6 +2,7 @@ name = "cpython-sys" version = "0.1.0" edition = "2024" +rust-version.workspace = true [dependencies] diff --git a/rust-toolchain.toml b/rust-toolchain.toml deleted file mode 100644 index 4f2204701d79036..000000000000000 --- a/rust-toolchain.toml +++ /dev/null @@ -1,3 +0,0 @@ -[toolchain] -channel = "1.91.1" -components = ["rustfmt", "clippy"] From fa8b0354904a14bdf9db1d0ef9b168a7817e5655 Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Sun, 9 Aug 2026 19:50:39 -0700 Subject: [PATCH 2/4] Debug Windows CI --- .github/workflows/reusable-windows.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.github/workflows/reusable-windows.yml b/.github/workflows/reusable-windows.yml index 953de57986f5837..c261d069977aee6 100644 --- a/.github/workflows/reusable-windows.yml +++ b/.github/workflows/reusable-windows.yml @@ -41,6 +41,7 @@ jobs: if: inputs.arch != 'Win32' run: echo "::add-matcher::.github/problem-matchers/msvc.json" - name: Build CPython + id: build_cpython # msvc::musttail is not supported for debug builds, so we have to # switch to release. run: >- @@ -50,6 +51,20 @@ jobs: -p "${ARCH}" ${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }} shell: bash + - name: Upload Rust linker diagnostics + if: failure() && steps.build_cpython.outcome == 'failure' + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: windows-rust-link-diagnostics-${{ inputs.arch }}-${{ inputs.interpreter }}-${{ inputs.free-threading }} + if-no-files-found: warn + path: | + PCbuild/obj/**/_base64/cargo/**/build/cpython-sys-*/out/c_api.rs + PCbuild/obj/**/_base64/cargo/**/build/*/output + PCbuild/obj/**/_base64/cargo/**/.fingerprint/*/run-build-script-*.json + PCbuild/obj/**/_base64/cargo/**/deps/rustc*/ + PCbuild/obj/**/pythoncore/pythoncore.tlog/link.*.tlog + PCbuild/**/python*.dll + PCbuild/**/python*.lib - name: Display build info run: .\\python.bat -m test.pythoninfo - name: Tests From 2ed828b37dbad994d4b97ea53d1758db2f3d7e0c Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Sun, 9 Aug 2026 21:05:24 -0700 Subject: [PATCH 3/4] Use syn to add link attribute for Windows dllimport of globals --- Cargo.lock | 66 +++++++++++++++++----------------- Modules/cpython-sys/Cargo.toml | 2 ++ Modules/cpython-sys/build.rs | 58 +++++++++--------------------- 3 files changed, 52 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 132b913b06d5e5f..14e6791704c1963 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12,9 +12,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -41,9 +41,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.10.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "cexpr" @@ -62,9 +62,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "clang-sys" -version = "1.8.1" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +checksum = "157a8ba7b480713b56f4c09fd13fc3e0a22a5dfab8097ba61cbc5feef950788a" dependencies = [ "glob", "libc", @@ -90,20 +90,22 @@ name = "cpython-sys" version = "0.1.0" dependencies = [ "bindgen", + "prettyplease", "shlex", + "syn", ] [[package]] name = "either" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "itertools" @@ -116,9 +118,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.177" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libloading" @@ -132,15 +134,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "minimal-lexical" @@ -170,27 +172,27 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] [[package]] name = "regex" -version = "1.12.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -200,9 +202,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.13" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -211,15 +213,15 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.8" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "shlex" @@ -229,9 +231,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "syn" -version = "2.0.110" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -240,9 +242,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "windows-link" diff --git a/Modules/cpython-sys/Cargo.toml b/Modules/cpython-sys/Cargo.toml index 7553282217dc74e..4f0dc4cbaca684c 100644 --- a/Modules/cpython-sys/Cargo.toml +++ b/Modules/cpython-sys/Cargo.toml @@ -8,4 +8,6 @@ rust-version.workspace = true [build-dependencies] bindgen = "0.72.1" +prettyplease = "0.2.37" shlex = "1.3" +syn = { version = "2.0.110", features = ["full", "parsing"] } diff --git a/Modules/cpython-sys/build.rs b/Modules/cpython-sys/build.rs index 03335128e9fbe55..0de3ad43f9efdcb 100644 --- a/Modules/cpython-sys/build.rs +++ b/Modules/cpython-sys/build.rs @@ -324,52 +324,26 @@ fn patch_windows_imported_pointer_globals(bindings: String, dll_name: &str) -> S // The fix: annotate pointer-valued extern statics with `raw-dylib` on // Windows so Rust generates the import thunk itself and handles the IAT // indirection correctly — two loads, matching `__declspec(dllimport)`. - let lines: Vec<_> = bindings.lines().collect(); - let mut patched = String::with_capacity(bindings.len()); - let mut index = 0; - - while index < lines.len() { - if lines[index] == "unsafe extern \"C\" {" - && lines - .get(index + 1) - .and_then(|l| parse_pointer_static_decl(l)) - .is_some() - && lines.get(index + 2).is_some_and(|l| l.trim() == "}") - { - patched.push_str(&format!( - "#[cfg_attr(windows, link(name = \"{dll_name}\", kind = \"raw-dylib\"))]\n" - )); - // Keep the original extern block unchanged. - for i in index..index + 3 { - patched.push_str(lines[i]); - patched.push('\n'); - } - index += 3; + let mut file = syn::parse_file(&bindings).expect("bindgen emitted invalid Rust"); + + for item in &mut file.items { + let syn::Item::ForeignMod(foreign_mod) = item else { + continue; + }; + let [syn::ForeignItem::Static(static_item)] = foreign_mod.items.as_slice() else { + continue; + }; + if !matches!(*static_item.ty, syn::Type::Ptr(_)) { continue; } - - patched.push_str(lines[index]); - patched.push('\n'); - index += 1; - } - - patched -} - -fn parse_pointer_static_decl(line: &str) -> Option<(&str, bool, &str)> { - let mut decl = line.trim().strip_prefix("pub static ")?; - let is_mut = decl.starts_with("mut "); - if is_mut { - decl = decl.strip_prefix("mut ")?; - } - - let (name, ty) = decl.split_once(':')?; - let ty = ty.trim().strip_suffix(';')?; - if !ty.starts_with('*') { - return None; + foreign_mod + .attrs + .push(syn::parse_quote!( + #[cfg_attr(windows, link(name = #dll_name, kind = "raw-dylib"))] + )); } - Some((name.trim(), is_mut, ty)) + prettyplease::unparse(&file) } fn add_target_clang_args( From f9c372135a179a3a41646f80eb066311a2f8b445 Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Sun, 9 Aug 2026 21:07:36 -0700 Subject: [PATCH 4/4] Format cpython-sys/build.rs --- Modules/cpython-sys/build.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Modules/cpython-sys/build.rs b/Modules/cpython-sys/build.rs index 0de3ad43f9efdcb..0918ffd0b83da4b 100644 --- a/Modules/cpython-sys/build.rs +++ b/Modules/cpython-sys/build.rs @@ -336,11 +336,9 @@ fn patch_windows_imported_pointer_globals(bindings: String, dll_name: &str) -> S if !matches!(*static_item.ty, syn::Type::Ptr(_)) { continue; } - foreign_mod - .attrs - .push(syn::parse_quote!( - #[cfg_attr(windows, link(name = #dll_name, kind = "raw-dylib"))] - )); + foreign_mod.attrs.push(syn::parse_quote!( + #[cfg_attr(windows, link(name = #dll_name, kind = "raw-dylib"))] + )); } prettyplease::unparse(&file)