├── .codespellrc ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ ├── CI.yml │ └── Release.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── README.md ├── clippy.toml ├── pyproject.toml ├── src ├── bin │ └── cargo-xwin.rs ├── compiler │ ├── clang.rs │ ├── clang_cl.rs │ ├── common.rs │ ├── mod.rs │ └── override.cmake ├── env.rs ├── lib.rs ├── macros.rs ├── options.rs ├── run.rs └── test.rs └── tests ├── hello-rustls ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── hello-tls ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── hello-windows ├── .cargo │ └── config.toml ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs └── libhello ├── Cargo.lock ├── Cargo.toml └── src └── lib.rs /.codespellrc: -------------------------------------------------------------------------------- 1 | [codespell] 2 | ignore-words-list = crate 3 | skip = ./.git,./target 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: messense 2 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | -------------------------------------------------------------------------------- /.github/workflows/CI.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request: 6 | workflow_dispatch: 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref_name }}-${{ github.event.pull_request.number || github.sha }} 10 | cancel-in-progress: true 11 | 12 | name: CI 13 | 14 | jobs: 15 | check: 16 | name: Check 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - uses: dtolnay/rust-toolchain@stable 21 | - run: cargo check --all 22 | 23 | test: 24 | name: Test Suite 25 | runs-on: ${{ matrix.os }} 26 | strategy: 27 | matrix: 28 | os: [ubuntu-24.04, macos-latest, windows-latest] 29 | toolchain: [stable, nightly] 30 | cross-compiler: [clang-cl, clang] 31 | env: 32 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 33 | XWIN_CROSS_COMPILER: ${{ matrix.cross-compiler }} 34 | steps: 35 | - uses: actions/checkout@v4 36 | - uses: actions/checkout@v4 37 | with: 38 | repository: messense/crfsuite-rs 39 | path: tests/crfsuite-rs 40 | submodules: true 41 | - uses: seanmiddleditch/gha-setup-ninja@master 42 | - name: Install dependencies 43 | if: startsWith(matrix.os, 'macos') 44 | run: | 45 | brew install gnu-tar llvm 46 | echo "/usr/local/opt/gnu-tar/libexec/gnubin" >> $GITHUB_PATH 47 | - name: Install dependencies 48 | if: startsWith(matrix.os, 'ubuntu') 49 | run: | 50 | sudo apt-get update 51 | sudo apt-get install --quiet -y clang wine-stable 52 | - name: Install Clang 53 | if: startsWith(matrix.os, 'windows') 54 | run: choco install -y llvm 55 | - uses: dtolnay/rust-toolchain@master 56 | id: rustup 57 | with: 58 | toolchain: ${{ matrix.toolchain }} 59 | components: llvm-tools 60 | - name: Cache cargo build 61 | uses: Swatinem/rust-cache@v2 62 | - name: Cache test crates cargo build 63 | uses: actions/cache@v4 64 | with: 65 | path: | 66 | tests/hello-tls/target 67 | tests/hello-windows/target 68 | tests/libhello/target 69 | key: test-crates-${{ runner.os }}-${{ steps.rustup.outputs.cachekey }}-${{ hashFiles('tests/*/Cargo.lock') }} 70 | - run: cargo build --release 71 | - name: xwin build - x86_64 72 | run: | 73 | rustup target add x86_64-pc-windows-msvc 74 | 75 | cargo run --release xwin build --target x86_64-pc-windows-msvc --manifest-path tests/libhello/Cargo.toml 76 | cargo run --release xwin build --target x86_64-pc-windows-msvc --manifest-path tests/hello-tls/Cargo.toml 77 | cargo run --release xwin build --target x86_64-pc-windows-msvc --manifest-path tests/hello-rustls/Cargo.toml 78 | # Test using default build target from config 79 | cargo run --release xwin build --manifest-path tests/hello-windows/Cargo.toml 80 | # Test CMake support 81 | cargo run --release xwin build --target x86_64-pc-windows-msvc --manifest-path tests/crfsuite-rs/Cargo.toml 82 | - name: xwin run - x86_64 83 | if: startsWith(matrix.os, 'ubuntu') 84 | run: | 85 | cargo run --release xwin run --target x86_64-pc-windows-msvc --manifest-path tests/hello-windows/Cargo.toml 86 | - name: xwin test - x86_64 87 | if: startsWith(matrix.os, 'ubuntu') 88 | run: | 89 | cargo run --release xwin test --target x86_64-pc-windows-msvc --manifest-path tests/hello-windows/Cargo.toml 90 | - name: xwin build - aarch64 91 | run: | 92 | rustup target add aarch64-pc-windows-msvc 93 | 94 | cargo run --release xwin build --target aarch64-pc-windows-msvc --manifest-path tests/libhello/Cargo.toml 95 | cargo run --release xwin build --target aarch64-pc-windows-msvc --manifest-path tests/hello-windows/Cargo.toml 96 | cargo run --release xwin build --target aarch64-pc-windows-msvc --manifest-path tests/hello-tls/Cargo.toml 97 | # Test CMake support 98 | cargo run --release xwin build --target aarch64-pc-windows-msvc --manifest-path tests/crfsuite-rs/Cargo.toml 99 | 100 | msrv: 101 | name: MSRV 102 | runs-on: ubuntu-latest 103 | steps: 104 | - uses: actions/checkout@v4 105 | - uses: dtolnay/rust-toolchain@1.74.0 106 | - run: cargo check 107 | 108 | fmt: 109 | name: Rustfmt 110 | runs-on: ubuntu-latest 111 | steps: 112 | - uses: actions/checkout@v4 113 | - uses: dtolnay/rust-toolchain@stable 114 | with: 115 | components: rustfmt 116 | - run: cargo fmt --all -- --check 117 | 118 | clippy: 119 | name: Clippy 120 | runs-on: ubuntu-latest 121 | steps: 122 | - uses: actions/checkout@v4 123 | - uses: dtolnay/rust-toolchain@stable 124 | with: 125 | components: clippy 126 | - run: cargo clippy --all-features 127 | 128 | spellcheck: 129 | name: spellcheck 130 | runs-on: ubuntu-latest 131 | 132 | steps: 133 | - uses: actions/checkout@v4 134 | - uses: codespell-project/actions-codespell@master 135 | -------------------------------------------------------------------------------- /.github/workflows/Release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | tags: [ 'v*' ] 7 | pull_request: 8 | 9 | jobs: 10 | macos: 11 | runs-on: macos-latest 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: dtolnay/rust-toolchain@stable 15 | with: 16 | targets: aarch64-apple-darwin 17 | - name: Build 18 | uses: PyO3/maturin-action@v1 19 | with: 20 | args: --release --out dist --universal2 21 | sccache: 'true' 22 | - name: Upload wheels 23 | uses: actions/upload-artifact@v4 24 | with: 25 | name: wheels-macos-universal2 26 | path: dist 27 | - name: Upload binary artifacts 28 | uses: actions/upload-artifact@v4 29 | with: 30 | name: apple-darwin-bin 31 | path: target/release/cargo-xwin 32 | if-no-files-found: error 33 | - name: Get tag 34 | if: "startsWith(github.ref, 'refs/tags/')" 35 | id: tag 36 | uses: dawidd6/action-get-tag@v1 37 | - name: Archive binary 38 | if: "startsWith(github.ref, 'refs/tags/')" 39 | run: | 40 | cd target/release 41 | tar czvf cargo-xwin-${{ steps.tag.outputs.tag }}.universal2-apple-darwin.tar.gz cargo-xwin 42 | shasum -a 256 cargo-xwin-${{ steps.tag.outputs.tag }}.universal2-apple-darwin.tar.gz > cargo-xwin-${{ steps.tag.outputs.tag }}.universal2-apple-darwin.tar.gz.sha256 43 | cd - 44 | - name: Upload binary to GitHub Release 45 | uses: svenstaro/upload-release-action@v2 46 | if: "startsWith(github.ref, 'refs/tags/')" 47 | with: 48 | repo_token: ${{ secrets.GITHUB_TOKEN }} 49 | file: target/release/cargo-xwin*.tar.gz 50 | file_glob: true 51 | overwrite: true 52 | tag: ${{ github.ref }} 53 | prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }} 54 | 55 | windows: 56 | runs-on: windows-latest 57 | strategy: 58 | matrix: 59 | platform: 60 | - arch: x64 61 | target: x86_64-pc-windows-msvc 62 | - arch: x86 63 | target: i686-pc-windows-msvc 64 | steps: 65 | - uses: actions/checkout@v4 66 | - uses: actions/setup-python@v5 67 | - uses: dtolnay/rust-toolchain@stable 68 | - name: Build 69 | uses: PyO3/maturin-action@v1 70 | with: 71 | target: ${{ matrix.platform.target }} 72 | args: --release --out dist 73 | sccache: 'true' 74 | - name: Upload wheels 75 | uses: actions/upload-artifact@v4 76 | with: 77 | name: wheels-${{ matrix.platform.arch }} 78 | path: dist 79 | - name: Upload binary artifacts 80 | uses: actions/upload-artifact@v4 81 | with: 82 | name: windows-${{ matrix.platform.arch }}-bin 83 | path: target/${{ matrix.platform.target }}/release/cargo-xwin.exe 84 | if-no-files-found: error 85 | - name: Get tag 86 | if: "startsWith(github.ref, 'refs/tags/')" 87 | id: tag 88 | uses: dawidd6/action-get-tag@v1 89 | - name: Archive binary 90 | if: "startsWith(github.ref, 'refs/tags/')" 91 | run: | 92 | cd target/${{ matrix.platform.target }}/release 93 | 7z a cargo-xwin.zip cargo-xwin.exe 94 | cd - 95 | - name: Upload binary to GitHub Release 96 | uses: svenstaro/upload-release-action@v2 97 | if: "startsWith(github.ref, 'refs/tags/')" 98 | with: 99 | repo_token: ${{ secrets.GITHUB_TOKEN }} 100 | asset_name: cargo-xwin-${{ steps.tag.outputs.tag }}.windows-${{ matrix.platform.arch }}.zip 101 | file: target/${{ matrix.platform.target }}/release/cargo-xwin.zip 102 | overwrite: true 103 | tag: ${{ github.ref }} 104 | prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }} 105 | 106 | linux: 107 | runs-on: ubuntu-latest 108 | strategy: 109 | matrix: 110 | platform: [ 111 | { target: "x86_64-unknown-linux-musl", image_tag: "x86_64-musl" }, 112 | { target: "i686-unknown-linux-musl", image_tag: "i686-musl" }, 113 | { target: "aarch64-unknown-linux-musl", image_tag: "aarch64-musl" }, 114 | { target: "armv7-unknown-linux-musleabihf", image_tag: "armv7-musleabihf" }, 115 | { target: "armv7-unknown-linux-musleabi", image_tag: "armv7-musleabi" }, 116 | ] 117 | container: 118 | image: docker://ghcr.io/rust-cross/rust-musl-cross:${{ matrix.platform.image_tag }} 119 | env: 120 | CFLAGS_armv7_unknown_linux_musleabihf: '-mfpu=vfpv3-d16' 121 | steps: 122 | - uses: actions/checkout@v4 123 | - name: Build 124 | uses: PyO3/maturin-action@main 125 | with: 126 | target: ${{ matrix.platform.target }} 127 | manylinux: auto 128 | container: off 129 | args: --release -o dist 130 | sccache: 'true' 131 | - name: Upload wheels 132 | uses: actions/upload-artifact@v4 133 | with: 134 | name: wheels-${{ matrix.platform.target }} 135 | path: dist 136 | - name: Upload binary artifacts 137 | uses: actions/upload-artifact@v4 138 | with: 139 | name: ${{ matrix.platform.target }}-bin 140 | path: target/${{ matrix.platform.target }}/release/cargo-xwin 141 | if-no-files-found: error 142 | - name: Get tag 143 | if: "startsWith(github.ref, 'refs/tags/')" 144 | id: tag 145 | uses: dawidd6/action-get-tag@v1 146 | - name: Archive binary 147 | if: "startsWith(github.ref, 'refs/tags/')" 148 | run: | 149 | cd target/${{ matrix.platform.target }}/release 150 | tar czvf cargo-xwin-${{ steps.tag.outputs.tag }}.${{ matrix.platform.target }}.tar.gz cargo-xwin 151 | shasum -a 256 cargo-xwin-${{ steps.tag.outputs.tag }}.${{ matrix.platform.target }}.tar.gz > cargo-xwin-${{ steps.tag.outputs.tag }}.${{ matrix.platform.target }}.tar.gz.sha256 152 | cd - 153 | - name: Upload binary to GitHub Release 154 | uses: svenstaro/upload-release-action@v2 155 | if: "startsWith(github.ref, 'refs/tags/')" 156 | with: 157 | repo_token: ${{ secrets.GITHUB_TOKEN }} 158 | file: target/${{ matrix.platform.target }}/release/cargo-xwin*.tar.gz* 159 | file_glob: true 160 | overwrite: true 161 | tag: ${{ github.ref }} 162 | prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') }} 163 | 164 | docker: 165 | name: Build Docker Image 166 | runs-on: ubuntu-latest 167 | environment: Docker Hub 168 | if: ${{ github.event_name != 'pull_request' }} 169 | steps: 170 | - uses: actions/checkout@v4 171 | - name: Docker meta 172 | id: meta 173 | uses: docker/metadata-action@v5 174 | with: 175 | images: | 176 | ${{ secrets.DOCKER_USERNAME }}/cargo-xwin 177 | ghcr.io/${{ github.repository_owner }}/cargo-xwin 178 | tags: | 179 | type=schedule 180 | type=ref,event=branch 181 | type=ref,event=pr 182 | type=semver,pattern={{version}} 183 | type=semver,pattern={{major}}.{{minor}} 184 | type=semver,pattern={{major}} 185 | type=sha 186 | - name: Setup QEMU 187 | uses: dbhi/qus/action@main 188 | - name: Setup Docker Buildx 189 | uses: docker/setup-buildx-action@v3 190 | - name: Login to DockerHub 191 | if: github.event_name != 'pull_request' 192 | uses: docker/login-action@v3 193 | with: 194 | username: ${{ secrets.DOCKER_USERNAME }} 195 | password: ${{ secrets.DOCKER_TOKEN }} 196 | - name: Login to GitHub Container Registry 197 | if: github.event_name != 'pull_request' 198 | uses: docker/login-action@v3 199 | with: 200 | registry: ghcr.io 201 | username: ${{ github.repository_owner }} 202 | password: ${{ secrets.GITHUB_TOKEN }} 203 | - name: docker build 204 | uses: docker/build-push-action@v6 205 | with: 206 | context: . 207 | platforms: linux/amd64,linux/arm64 208 | push: ${{ github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/')) }} 209 | tags: ${{ steps.meta.outputs.tags }} 210 | labels: ${{ steps.meta.outputs.labels }} 211 | cache-from: type=gha 212 | cache-to: type=gha,mode=max 213 | - name: Docker Hub Description 214 | if: github.event_name != 'pull_request' 215 | uses: peter-evans/dockerhub-description@v4 216 | with: 217 | username: ${{ secrets.DOCKER_USERNAME }} 218 | password: ${{ secrets.DOCKER_TOKEN }} 219 | repository: ${{ secrets.DOCKER_USERNAME }}/cargo-xwin 220 | 221 | release: 222 | name: Release 223 | runs-on: ubuntu-latest 224 | if: "startsWith(github.ref, 'refs/tags/')" 225 | needs: [ macos, windows, linux ] 226 | steps: 227 | - uses: actions/download-artifact@v4 228 | with: 229 | pattern: wheels-* 230 | merge-multiple: true 231 | - name: Publish to PyPI 232 | env: 233 | MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_PASSWORD }} 234 | uses: PyO3/maturin-action@v1 235 | with: 236 | command: upload 237 | args: --skip-existing * 238 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cargo-xwin" 3 | version = "0.18.5" 4 | edition = "2021" 5 | description = "Cross compile Cargo project to Windows MSVC target with ease" 6 | license = "MIT" 7 | keywords = ["windows", "cargo", "msvc"] 8 | readme = "README.md" 9 | repository = "https://github.com/rust-cross/cargo-xwin" 10 | rust-version = "1.74" 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | 14 | [package.metadata.binstall] 15 | pkg-url = "{ repo }/releases/download/v{ version }/{ name }-v{ version }.{ target }.{ archive-format }" 16 | 17 | [dependencies] 18 | anyhow = "1.0.53" 19 | cargo-config2 = "0.1.4" 20 | cargo-options = "0.7.1" 21 | clap = { version = "4.3.0", features = [ 22 | "derive", 23 | "env", 24 | "wrap_help", 25 | "unstable-styles", 26 | ] } 27 | dirs = "5.0.0" 28 | fs-err = "3.0.0" 29 | humantime = "2.1.0" 30 | indicatif = "0.17.2" 31 | native-tls-crate = { package = "native-tls", version = "0.2.11", optional = true } 32 | paste = "1.0.12" 33 | path-slash = "0.2.0" 34 | rustls = { version = "0.23.10", default-features = false, features = [ 35 | "std", 36 | "tls12", 37 | "logging", 38 | "ring", 39 | ], optional = true } 40 | rustls-pemfile = { version = "2.0.0", optional = true } 41 | serde = { version = "1.0.216", features = ["derive"] } 42 | serde_json = "1.0.133" 43 | tar = "0.4.43" 44 | tracing-subscriber = { version = "0.3.17", features = ["fmt"] } 45 | ureq = { version = "2.11.0", default-features = false, features = [ 46 | "gzip", 47 | "json", 48 | "socks-proxy", 49 | ] } 50 | which = "7.0.0" 51 | xwin = { version = "0.6.3", default-features = false } 52 | xz2 = "0.1.7" 53 | 54 | [features] 55 | # By default we use rustls for TLS 56 | default = ["rustls-tls", "xz2/static"] 57 | rustls-tls = ["ureq/tls", "rustls", "rustls-pemfile"] 58 | # If this feature is enabled we instead use the native TLS implementation for the 59 | # target platform 60 | native-tls = ["ureq/native-tls", "rustls-pemfile", "native-tls-crate"] 61 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG RUST_VERSION=1.87.0 2 | 3 | FROM rust:$RUST_VERSION as builder 4 | 5 | ENV CARGO_NET_GIT_FETCH_WITH_CLI=true 6 | 7 | # Compile dependencies only for build caching 8 | ADD Cargo.toml /cargo-xwin/Cargo.toml 9 | ADD Cargo.lock /cargo-xwin/Cargo.lock 10 | RUN mkdir /cargo-xwin/src && \ 11 | touch /cargo-xwin/src/lib.rs && \ 12 | cargo build --manifest-path /cargo-xwin/Cargo.toml --release 13 | 14 | # Build cargo-xwin 15 | ADD . /cargo-xwin/ 16 | # Manually update the timestamps as ADD keeps the local timestamps and cargo would then believe the cache is fresh 17 | RUN touch /cargo-xwin/src/lib.rs /cargo-xwin/src/bin/cargo-xwin.rs 18 | RUN cargo build --manifest-path /cargo-xwin/Cargo.toml --release 19 | 20 | FROM rust:$RUST_VERSION 21 | 22 | RUN set -eux; \ 23 | curl --fail https://dl.winehq.org/wine-builds/winehq.key | gpg --dearmor > /usr/share/keyrings/winehq.gpg; \ 24 | echo "deb [signed-by=/usr/share/keyrings/winehq.gpg] https://dl.winehq.org/wine-builds/debian/ bookworm main" > /etc/apt/sources.list.d/winehq.list; \ 25 | # The way the debian package works requires that we add x86 support, even 26 | # though we are only going be running x86_64 executables. We could also 27 | # build from source, but that is out of scope. 28 | dpkg --add-architecture i386; \ 29 | apt-get update && apt-get install --no-install-recommends -y clang llvm winehq-staging cmake ninja-build; \ 30 | apt-get remove -y --auto-remove; \ 31 | rm -rf /var/lib/apt/lists/*; 32 | 33 | # Install Rust targets 34 | RUN rustup target add x86_64-pc-windows-msvc aarch64-pc-windows-msvc && \ 35 | rustup component add llvm-tools-preview 36 | 37 | COPY --from=builder /cargo-xwin/target/release/cargo-xwin /usr/local/cargo/bin/ 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 messense 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------- 24 | 25 | This software is based on xwin, provided under the following license: 26 | 27 | Copyright (c) 2021 Jake Shadle 28 | 29 | Permission is hereby granted, free of charge, to any 30 | person obtaining a copy of this software and associated 31 | documentation files (the "Software"), to deal in the 32 | Software without restriction, including without 33 | limitation the rights to use, copy, modify, merge, 34 | publish, distribute, sublicense, and/or sell copies of 35 | the Software, and to permit persons to whom the Software 36 | is furnished to do so, subject to the following 37 | conditions: 38 | 39 | The above copyright notice and this permission notice 40 | shall be included in all copies or substantial portions 41 | of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 44 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 45 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 46 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 47 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 48 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 49 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 50 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 51 | DEALINGS IN THE SOFTWARE. 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cargo-xwin 2 | 3 | _formerly cargo-xwinbuild_ 4 | 5 | [![CI](https://github.com/rust-cross/cargo-xwin/workflows/CI/badge.svg)](https://github.com/rust-cross/cargo-xwin/actions?query=workflow%3ACI) 6 | [![Crates.io](https://img.shields.io/crates/v/cargo-xwin.svg)](https://crates.io/crates/cargo-xwin) 7 | [![docs.rs](https://docs.rs/cargo-xwin/badge.svg)](https://docs.rs/cargo-xwin/) 8 | [![PyPI](https://img.shields.io/pypi/v/cargo-xwin.svg)](https://pypi.org/project/cargo-xwin) 9 | [![Docker Image](https://img.shields.io/docker/pulls/messense/cargo-xwin.svg?maxAge=2592000)](https://hub.docker.com/r/messense/cargo-xwin/) 10 | 11 | > 🚀 Help me to become a full-time open-source developer by [sponsoring me on GitHub](https://github.com/sponsors/messense) 12 | 13 | Cross compile Cargo project to Windows msvc target with ease using [xwin](https://github.com/Jake-Shadle/xwin) or [windows-msvc-sysroot](https://github.com/trcrsired/windows-msvc-sysroot). 14 | 15 | **By using this software you are consented to accept the license at [https://go.microsoft.com/fwlink/?LinkId=2086102](https://go.microsoft.com/fwlink/?LinkId=2086102)** 16 | 17 | ## Prerequisite 18 | 19 | 1. Install [clang](https://clang.llvm.org/) (On macOS run `brew install llvm` and you're good to go). 20 | 2. For assembly dependencies, install `llvm-tools` component via `rustup component add llvm-tools` or install [llvm](https://llvm.org). 21 | 22 | A full LLVM installation is recommended to avoid possible issues. 23 | 24 | ## Installation 25 | 26 | ```bash 27 | cargo install --locked cargo-xwin 28 | ``` 29 | 30 | You can also install it using pip: 31 | 32 | ```bash 33 | pip install cargo-xwin 34 | ``` 35 | 36 | We also provide a [Docker image](https://hub.docker.com/r/messense/cargo-xwin) which has wine pre-installed in addition to cargo-xwin and Rust, 37 | for example to build for x86_64 Windows: 38 | 39 | ```bash 40 | docker run --rm -it -v $(pwd):/io -w /io messense/cargo-xwin \ 41 | cargo xwin build --release --target x86_64-pc-windows-msvc 42 | ``` 43 | 44 | ## Usage 45 | 46 | 1. Install Rust Windows msvc target via rustup, for example, `rustup target add x86_64-pc-windows-msvc` 47 | 2. Run `cargo xwin build`, for example, `cargo xwin build --target x86_64-pc-windows-msvc` 48 | 49 | ### Run tests with wine 50 | 51 | With wine installed, you can run tests with the `cargo xwin test` command, 52 | for example, `cargo xwin test --target x86_64-pc-windows-msvc` 53 | 54 | ### Customization 55 | 56 | The Microsoft CRT and Windows SDK can be customized using the following environment variables or CLI options. 57 | 58 | | Environment Variable | CLI option | Description | 59 | | ---------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ | 60 | | `XWIN_CROSS_COMPILER` | `--cross-compiler` | The cross compiler to use, defaults to `clang-cl`, possible values: `clang-cl`, `clang` | 61 | | `XWIN_ARCH` | `--xwin-arch` | The architectures to include, defaults to `x86_64,aarch64`, possible values: x86, x86_64, aarch, aarch64 | 62 | | `XWIN_VARIANT` | `--xwin-variant` | The variants to include, defaults to `desktop`, possible values: desktop, onecore, spectre | 63 | | `XWIN_VERSION` | `--xwin-version` | The version to retrieve, defaults to 16, can either be a major version of 15 or 16, or a `.` version | 64 | | `XWIN_CACHE_DIR` | `--xwin-cache-dir` | xwin cache directory to put CRT and SDK files | 65 | | `XWIN_INCLUDE_DEBUG_LIBS` | `--xwin-include-debug-libs` | Whether or not to include debug libs in installation (default false). | 66 | | `XWIN_INCLUDE_DEBUG_SYMBOLS` | `--xwin-include-debug-symbols` | Whether or not to include debug symbols (PDBs) in installation (default false). | 67 | 68 | ### CMake Support 69 | 70 | Some Rust crates use the [cmake](https://github.com/alexcrichton/cmake-rs) crate to build C/C++ dependencies, 71 | cargo-xwin will generate a [CMake toolchain](https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html) file 72 | automatically to make cross compilation work out of the box. 73 | 74 | **[ninja](https://ninja-build.org/) is required** to enable CMake support. 75 | 76 | ## License 77 | 78 | This work is released under the MIT license. A copy of the license is provided 79 | in the [LICENSE](./LICENSE) file. 80 | -------------------------------------------------------------------------------- /clippy.toml: -------------------------------------------------------------------------------- 1 | msrv = "1.74.0" 2 | 3 | disallowed-types = [ 4 | "std::fs::DirEntry", 5 | "std::fs::File", 6 | "std::fs::OpenOptions", 7 | "std::fs::ReadDir", 8 | ] 9 | 10 | disallowed-methods = [ 11 | "std::fs::canonicalize", 12 | "std::fs::copy", 13 | "std::fs::create_dir", 14 | "std::fs::create_dir_all", 15 | "std::fs::hard_link", 16 | "std::fs::metadata", 17 | "std::fs::read", 18 | "std::fs::read_dir", 19 | "std::fs::read_link", 20 | "std::fs::read_to_string", 21 | "std::fs::remove_dir", 22 | "std::fs::remove_dir_all", 23 | "std::fs::remove_file", 24 | "std::fs::rename", 25 | "std::fs::set_permissions", 26 | "std::fs::soft_link", 27 | "std::fs::symlink_metadata", 28 | "std::fs::write", 29 | "std::os::windows::fs::symlink_file", 30 | "std::os::unix::fs::symlink", 31 | ] 32 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["maturin>=0.14,<0.15"] 3 | build-backend = "maturin" 4 | 5 | [project] 6 | name = "cargo-xwin" 7 | dependencies = ["ninja"] 8 | dynamic = ["version"] 9 | 10 | [tool.maturin] 11 | bindings = "bin" 12 | -------------------------------------------------------------------------------- /src/bin/cargo-xwin.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::ffi::OsString; 3 | use std::process::Command; 4 | 5 | use cargo_xwin::{Build, Check, Clippy, Doc, Env, Run, Rustc, Test}; 6 | use clap::{Parser, Subcommand}; 7 | 8 | #[derive(Debug, Parser)] 9 | #[command( 10 | version, 11 | name = "cargo-xwin", 12 | styles = cargo_options::styles(), 13 | )] 14 | pub enum Cli { 15 | #[command(subcommand, name = "xwin")] 16 | Opt(Opt), 17 | // flatten opt here so that `cargo-xwin build` also works 18 | #[command(flatten)] 19 | Cargo(Opt), 20 | #[command(external_subcommand)] 21 | External(Vec), 22 | } 23 | 24 | #[allow(clippy::large_enum_variant)] 25 | #[derive(Debug, Subcommand)] 26 | #[command(version, display_order = 1)] 27 | pub enum Opt { 28 | #[command(name = "build", alias = "b")] 29 | Build(Build), 30 | Check(Check), 31 | Clippy(Clippy), 32 | Doc(Doc), 33 | #[command(name = "run", alias = "r")] 34 | Run(Run), 35 | #[command(name = "rustc")] 36 | Rustc(Rustc), 37 | #[command(name = "test", alias = "t")] 38 | Test(Test), 39 | #[command(name = "env")] 40 | Env(Env), 41 | } 42 | 43 | fn main() -> anyhow::Result<()> { 44 | tracing_subscriber::fmt::init(); 45 | 46 | let cli = Cli::parse(); 47 | match cli { 48 | Cli::Opt(opt) | Cli::Cargo(opt) => match opt { 49 | Opt::Build(build) => build.execute()?, 50 | Opt::Run(run) => run.execute()?, 51 | Opt::Rustc(rustc) => rustc.execute()?, 52 | Opt::Test(test) => test.execute()?, 53 | Opt::Check(check) => check.execute()?, 54 | Opt::Clippy(clippy) => clippy.execute()?, 55 | Opt::Doc(doc) => doc.execute()?, 56 | Opt::Env(env) => env.execute()?, 57 | }, 58 | Cli::External(args) => { 59 | let mut child = Command::new(env::var_os("CARGO").unwrap_or("cargo".into())) 60 | .args(args) 61 | .env_remove("CARGO") 62 | .spawn()?; 63 | let status = child.wait().expect("Failed to wait on cargo process"); 64 | if !status.success() { 65 | std::process::exit(status.code().unwrap_or(1)); 66 | } 67 | } 68 | } 69 | Ok(()) 70 | } 71 | -------------------------------------------------------------------------------- /src/compiler/clang.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::path::{Path, PathBuf}; 3 | use std::process::Command; 4 | use std::time::{Duration, Instant}; 5 | 6 | use anyhow::{Context, Result}; 7 | use fs_err as fs; 8 | use path_slash::PathExt; 9 | use serde::Deserialize; 10 | 11 | use crate::compiler::common::{ 12 | adjust_canonicalization, default_build_target_from_config, get_rustflags, http_agent, 13 | setup_cmake_env, setup_env_path, setup_llvm_tools, setup_target_compiler_and_linker_env, 14 | }; 15 | 16 | const MSVC_SYSROOT_REPOSITORY: &str = "trcrsired/windows-msvc-sysroot"; 17 | const MSVC_SYSROOT_ASSET_NAME: &str = "windows-msvc-sysroot.tar.xz"; 18 | const FALLBACK_DOWNLOAD_URL: &str = "https://github.com/trcrsired/windows-msvc-sysroot/releases/download/2025-01-22/windows-msvc-sysroot.tar.xz"; 19 | 20 | #[derive(Debug)] 21 | pub struct Clang; 22 | 23 | impl Clang { 24 | pub fn new() -> Self { 25 | Clang 26 | } 27 | 28 | pub fn apply_command_env( 29 | &self, 30 | manifest_path: Option<&Path>, 31 | cargo: &cargo_options::CommonOptions, 32 | cache_dir: PathBuf, 33 | cmd: &mut Command, 34 | ) -> Result<()> { 35 | let env_path = setup_env_path(&cache_dir)?; 36 | let workdir = manifest_path 37 | .and_then(|p| p.parent().map(|x| x.to_path_buf())) 38 | .or_else(|| env::current_dir().ok()) 39 | .unwrap(); 40 | let mut targets = cargo.target.clone(); 41 | if targets.is_empty() { 42 | if let Some(build_target) = default_build_target_from_config(&workdir)? { 43 | // if no target is specified, use the default build target 44 | // Note that this is required, otherwise it may fail with link errors 45 | cmd.arg("--target").arg(&build_target); 46 | targets.push(build_target); 47 | } 48 | } 49 | 50 | for target in &targets { 51 | if target.contains("msvc") { 52 | let msvc_sysroot_dir = self 53 | .setup_msvc_sysroot(cache_dir.clone()) 54 | .context("Failed to setup MSVC sysroot")?; 55 | // x86_64-pc-windows-msvc -> x86_64-windows-msvc 56 | let target_no_vendor = target.replace("-pc-", "-"); 57 | let target_unknown_vendor = target.replace("-pc-", "-unknown-"); 58 | let env_target = target.to_lowercase().replace('-', "_"); 59 | 60 | setup_llvm_tools(&env_path, &cache_dir).context("Failed to setup LLVM tools")?; 61 | setup_target_compiler_and_linker_env(cmd, &env_target, "clang"); 62 | 63 | let user_set_c_flags = env::var("CFLAGS").unwrap_or_default(); 64 | let user_set_cxx_flags = env::var("CXXFLAGS").unwrap_or_default(); 65 | let sysroot_dir = 66 | adjust_canonicalization(msvc_sysroot_dir.to_slash_lossy().to_string()); 67 | let clang_flags = format!( 68 | "--target={target_no_vendor} -fuse-ld=lld-link -I{dir}/include -I{dir}/include/c++/stl -I{dir}/include/__msvc_vcruntime_intrinsics -L{dir}/lib/{target_unknown_vendor}", 69 | dir = sysroot_dir, 70 | ); 71 | cmd.env( 72 | format!("CFLAGS_{env_target}"), 73 | format!("{clang_flags} {user_set_c_flags}",), 74 | ); 75 | cmd.env( 76 | format!("CXXFLAGS_{env_target}"), 77 | format!("{clang_flags} {user_set_cxx_flags}",), 78 | ); 79 | cmd.env( 80 | format!("BINDGEN_EXTRA_CLANG_ARGS_{env_target}"), 81 | format!("-I{dir}/include -I{dir}/include/c++/stl -I{dir}/include/__msvc_vcruntime_intrinsics", dir = sysroot_dir), 82 | ); 83 | cmd.env( 84 | "RCFLAGS", 85 | format!("-I{dir}/include -I{dir}/include/c++/stl -I{dir}/include/__msvc_vcruntime_intrinsics", dir = sysroot_dir), 86 | ); 87 | 88 | let mut rustflags = get_rustflags(&workdir, target)?.unwrap_or_default(); 89 | rustflags.flags.extend([ 90 | "-C".to_string(), 91 | "linker-flavor=lld-link".to_string(), 92 | "-C".to_string(), 93 | "link-arg=-defaultlib:oldnames".to_string(), 94 | ]); 95 | rustflags.push(format!( 96 | "-Lnative={dir}/lib/{target_unknown_vendor}", 97 | dir = sysroot_dir, 98 | )); 99 | cmd.env("CARGO_ENCODED_RUSTFLAGS", rustflags.encode()?); 100 | cmd.env("PATH", &env_path); 101 | 102 | // CMake support 103 | let cmake_toolchain = self 104 | .setup_cmake_toolchain(target, &sysroot_dir, &cache_dir) 105 | .with_context(|| format!("Failed to setup CMake toolchain for {}", target))?; 106 | setup_cmake_env(cmd, target, cmake_toolchain); 107 | } 108 | } 109 | Ok(()) 110 | } 111 | 112 | /// Download and unpack the latest MSVC sysroot from GitHub Releases. 113 | /// 114 | /// If the sysroot is already downloaded and unpacked, it will be reused. 115 | /// The sysroot will be stored in `/windows-msvc-sysroot`. 116 | /// A file named `DONE` will be created in the same directory with the 117 | /// download URL as its content. 118 | /// 119 | /// The environment variable `XWIN_MSVC_SYSROOT_DOWNLOAD_URL` can be used 120 | /// to override the download URL. 121 | fn setup_msvc_sysroot(&self, cache_dir: PathBuf) -> Result { 122 | let msvc_sysroot_dir = cache_dir.join("windows-msvc-sysroot"); 123 | let done_mark_file = msvc_sysroot_dir.join("DONE"); 124 | if msvc_sysroot_dir.is_dir() { 125 | if done_mark_file.is_file() { 126 | // Already downloaded and unpacked 127 | return Ok(msvc_sysroot_dir); 128 | } else { 129 | // Download again 130 | fs::remove_dir_all(&msvc_sysroot_dir) 131 | .context("Failed to remove existing msvc sysroot")?; 132 | } 133 | } 134 | 135 | let agent = http_agent()?; 136 | // fetch release info to get download url 137 | let download_url = self 138 | .get_latest_msvc_sysroot_download_url(agent.clone()) 139 | .unwrap_or_else(|_| FALLBACK_DOWNLOAD_URL.to_string()); 140 | self.download_msvc_sysroot(&cache_dir, agent, &download_url) 141 | .context("Failed to unpack msvc sysroot")?; 142 | fs::write(done_mark_file, download_url)?; 143 | Ok(msvc_sysroot_dir) 144 | } 145 | 146 | /// Retrieves the latest MSVC sysroot download URL from GitHub Releases. 147 | /// 148 | /// The function uses the `ureq` agent to make an HTTP GET request to the GitHub API. If a 149 | /// `GITHUB_TOKEN` environment variable is present, it includes it as a Bearer token for 150 | /// authentication. 151 | /// 152 | fn get_latest_msvc_sysroot_download_url(&self, agent: ureq::Agent) -> Result { 153 | if let Ok(url) = env::var("XWIN_MSVC_SYSROOT_DOWNLOAD_URL") { 154 | return Ok(url); 155 | } 156 | let mut request = agent 157 | .get(&format!( 158 | "https://api.github.com/repos/{}/releases/latest", 159 | MSVC_SYSROOT_REPOSITORY 160 | )) 161 | .set("X-GitHub-Api-Version", "2022-11-28"); 162 | if let Ok(token) = env::var("GITHUB_TOKEN") { 163 | request = request.set("Authorization", &format!("Bearer {token}")); 164 | } 165 | let response = request.call().context("Failed to get GitHub release")?; 166 | let release: GitHubRelease = response 167 | .into_json() 168 | .context("Failed to deserialize GitHub release")?; 169 | let asset = release 170 | .assets 171 | .iter() 172 | .find(|x| x.name == MSVC_SYSROOT_ASSET_NAME) 173 | .with_context(|| { 174 | format!("Failed to find {MSVC_SYSROOT_ASSET_NAME} in GitHub release") 175 | })?; 176 | let download_url = asset.browser_download_url.clone(); 177 | Ok(download_url) 178 | } 179 | 180 | fn download_msvc_sysroot_once( 181 | &self, 182 | cache_dir: &Path, 183 | agent: &ureq::Agent, 184 | download_url: &str, 185 | ) -> Result<()> { 186 | use indicatif::{ProgressBar, ProgressDrawTarget, ProgressStyle}; 187 | use xz2::read::XzDecoder; 188 | 189 | let response = agent.get(download_url).call()?; 190 | let len = response 191 | .header("content-length") 192 | .and_then(|s| s.parse::().ok()) 193 | .unwrap_or(0); 194 | let pb = ProgressBar::new(len); 195 | pb.set_draw_target(ProgressDrawTarget::stdout()); 196 | pb.set_style( 197 | ProgressStyle::default_bar() 198 | .template( 199 | "{spinner:.green} {prefix:.bold} [{elapsed}] {wide_bar:.green} {bytes}/{total_bytes} {msg}", 200 | )? 201 | .progress_chars("=> "), 202 | ); 203 | pb.set_prefix("sysroot"); 204 | pb.set_message("📥 downloading"); 205 | if pb.is_hidden() { 206 | eprintln!("📥 Downloading MSVC sysroot..."); 207 | } 208 | let start_time = Instant::now(); 209 | let reader = pb.wrap_read(response.into_reader()); 210 | let tar = XzDecoder::new(reader); 211 | let mut archive = tar::Archive::new(tar); 212 | archive.unpack(cache_dir)?; 213 | pb.finish_with_message("Download completed"); 214 | if pb.is_hidden() { 215 | // Display elapsed time in human-readable format to seconds only 216 | let elapsed = 217 | humantime::format_duration(Duration::from_secs(start_time.elapsed().as_secs())); 218 | eprintln!("✅ Downloaded MSVC sysroot in {elapsed}."); 219 | } 220 | Ok(()) 221 | } 222 | 223 | fn download_msvc_sysroot( 224 | &self, 225 | cache_dir: &Path, 226 | agent: ureq::Agent, 227 | download_url: &str, 228 | ) -> Result<()> { 229 | use std::time::Duration; 230 | 231 | const MAX_RETRIES: u32 = 3; 232 | let mut retry_count = 0; 233 | let mut last_error = None; 234 | 235 | while retry_count < MAX_RETRIES { 236 | if retry_count > 0 { 237 | let wait_time = Duration::from_secs(2u64.pow(retry_count - 1)); 238 | std::thread::sleep(wait_time); 239 | eprintln!( 240 | "Retrying download (attempt {}/{})", 241 | retry_count + 1, 242 | MAX_RETRIES 243 | ); 244 | } 245 | 246 | match self.download_msvc_sysroot_once(cache_dir, &agent, download_url) { 247 | Ok(()) => return Ok(()), 248 | Err(e) => { 249 | last_error = Some(e); 250 | retry_count += 1; 251 | } 252 | } 253 | } 254 | 255 | Err(last_error.unwrap_or_else(|| anyhow::anyhow!("Failed to download MSVC sysroot"))) 256 | } 257 | 258 | fn setup_cmake_toolchain( 259 | &self, 260 | target: &str, 261 | sysroot_dir: &str, 262 | cache_dir: &Path, 263 | ) -> Result { 264 | // x86_64-pc-windows-msvc -> x86_64-windows-msvc 265 | let target_no_vendor = target.replace("-pc-", "-"); 266 | let target_unknown_vendor = target.replace("-pc-", "-unknown-"); 267 | let cmake_cache_dir = cache_dir.join("cmake").join("clang"); 268 | fs::create_dir_all(&cmake_cache_dir)?; 269 | 270 | let toolchain_file = cmake_cache_dir.join(format!("{}-toolchain.cmake", target)); 271 | let target_arch = target 272 | .split_once('-') 273 | .map(|(x, _)| x) 274 | .context("invalid target triple")?; 275 | let processor = match target_arch { 276 | "i586" | "i686" => "X86", 277 | "x86_64" => "AMD64", 278 | "aarch64" => "ARM64", 279 | "arm64ec" => "ARM64EC", 280 | _ => target_arch, 281 | }; 282 | 283 | let content = format!( 284 | r#" 285 | set(CMAKE_SYSTEM_NAME Windows) 286 | set(CMAKE_SYSTEM_PROCESSOR {processor}) 287 | 288 | set(CMAKE_C_COMPILER clang CACHE FILEPATH "") 289 | set(CMAKE_CXX_COMPILER clang++ CACHE FILEPATH "") 290 | set(CMAKE_LINKER lld-link CACHE FILEPATH "") 291 | set(CMAKE_RC_COMPILER llvm-rc CACHE FILEPATH "") 292 | set(CMAKE_C_COMPILER_TARGET {target} CACHE STRING "") 293 | set(CMAKE_CXX_COMPILER_TARGET {target} CACHE STRING "") 294 | 295 | set(COMPILE_FLAGS 296 | --target={target_no_vendor} 297 | -fuse-ld=lld-link 298 | -I{dir}/include 299 | -I{dir}/include/c++/stl 300 | -I{dir}/include/__msvc_vcruntime_intrinsics) 301 | 302 | set(LINK_FLAGS 303 | /manifest:no 304 | -libpath:"{dir}/lib/{target_unknown_vendor}") 305 | "#, 306 | dir = sysroot_dir, 307 | ); 308 | fs::write(&toolchain_file, content)?; 309 | Ok(toolchain_file) 310 | } 311 | } 312 | 313 | #[derive(Debug, Deserialize)] 314 | struct GitHubRelease { 315 | assets: Vec, 316 | } 317 | 318 | #[derive(Debug, Deserialize)] 319 | struct GitHubReleaseAsset { 320 | browser_download_url: String, 321 | name: String, 322 | } 323 | -------------------------------------------------------------------------------- /src/compiler/clang_cl.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use std::convert::TryInto; 3 | use std::env; 4 | use std::ffi::OsStr; 5 | use std::path::{Path, PathBuf}; 6 | use std::process::Command; 7 | use std::time::{Duration, Instant}; 8 | 9 | use anyhow::{Context, Result}; 10 | use fs_err as fs; 11 | use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 12 | use path_slash::PathExt; 13 | use which::which_in; 14 | use xwin::util::ProgressTarget; 15 | 16 | use crate::compiler::common::{ 17 | adjust_canonicalization, default_build_target_from_config, get_rustflags, http_agent, 18 | setup_cmake_env, setup_env_path, setup_llvm_tools, setup_target_compiler_and_linker_env, 19 | }; 20 | use crate::options::XWinOptions; 21 | 22 | #[derive(Debug)] 23 | pub struct ClangCl<'a> { 24 | xwin_options: &'a XWinOptions, 25 | } 26 | 27 | impl<'a> ClangCl<'a> { 28 | pub fn new(xwin_options: &'a XWinOptions) -> Self { 29 | Self { xwin_options } 30 | } 31 | 32 | pub fn apply_command_env( 33 | &self, 34 | manifest_path: Option<&Path>, 35 | cargo: &cargo_options::CommonOptions, 36 | cache_dir: PathBuf, 37 | cmd: &mut Command, 38 | ) -> Result<()> { 39 | let env_path = setup_env_path(&cache_dir)?; 40 | 41 | let xwin_cache_dir = cache_dir.join("xwin"); 42 | fs::create_dir_all(&xwin_cache_dir).context("Failed to create xwin cache dir")?; 43 | let xwin_cache_dir = xwin_cache_dir 44 | .canonicalize() 45 | .context("Failed to canonicalize xwin cache dir")?; 46 | 47 | let workdir = manifest_path 48 | .and_then(|p| p.parent().map(|x| x.to_path_buf())) 49 | .or_else(|| env::current_dir().ok()) 50 | .unwrap(); 51 | let mut targets = cargo.target.clone(); 52 | if targets.is_empty() { 53 | if let Some(build_target) = default_build_target_from_config(&workdir)? { 54 | // if no target is specified, use the default build target 55 | // Note that this is required, otherwise it may fail with link errors 56 | cmd.arg("--target").arg(&build_target); 57 | targets.push(build_target); 58 | } 59 | } 60 | 61 | for target in &targets { 62 | if target.contains("msvc") { 63 | self.setup_msvc_crt(xwin_cache_dir.clone()) 64 | .context("Failed to setup MSVC CRT")?; 65 | let env_target = target.to_lowercase().replace('-', "_"); 66 | 67 | setup_clang_cl_symlink(&env_path, &cache_dir) 68 | .context("Failed to setup clang-cl symlink")?; 69 | setup_llvm_tools(&env_path, &cache_dir).context("Failed to setup LLVM tools")?; 70 | setup_target_compiler_and_linker_env(cmd, &env_target, "clang-cl"); 71 | 72 | let user_set_cl_flags = env::var("CL_FLAGS").unwrap_or_default(); 73 | let user_set_c_flags = env::var("CFLAGS").unwrap_or_default(); 74 | let user_set_cxx_flags = env::var("CXXFLAGS").unwrap_or_default(); 75 | 76 | let xwin_dir = adjust_canonicalization(xwin_cache_dir.to_slash_lossy().to_string()); 77 | let cl_flags = format!( 78 | "--target={target} -Wno-unused-command-line-argument -fuse-ld=lld-link /imsvc{dir}/crt/include /imsvc{dir}/sdk/include/ucrt /imsvc{dir}/sdk/include/um /imsvc{dir}/sdk/include/shared {user_set_cl_flags}", 79 | dir = xwin_dir, 80 | ); 81 | cmd.env("CL_FLAGS", &cl_flags); 82 | cmd.env( 83 | format!("CFLAGS_{env_target}"), 84 | format!("{cl_flags} {user_set_c_flags}",), 85 | ); 86 | cmd.env( 87 | format!("CXXFLAGS_{env_target}"), 88 | format!("{cl_flags} /EHsc {user_set_cxx_flags}",), 89 | ); 90 | 91 | cmd.env( 92 | format!("BINDGEN_EXTRA_CLANG_ARGS_{env_target}"), 93 | format!( 94 | "-I{dir}/crt/include -I{dir}/sdk/include/ucrt -I{dir}/sdk/include/um -I{dir}/sdk/include/shared", 95 | dir = xwin_dir 96 | ) 97 | ); 98 | 99 | cmd.env( 100 | "RCFLAGS", 101 | format!( 102 | "-I{dir}/crt/include -I{dir}/sdk/include/ucrt -I{dir}/sdk/include/um -I{dir}/sdk/include/shared", 103 | dir = xwin_dir 104 | ) 105 | ); 106 | 107 | let target_arch = target 108 | .split_once('-') 109 | .map(|(x, _)| x) 110 | .context("invalid target triple")?; 111 | let xwin_arch = match target_arch { 112 | "i586" | "i686" => "x86", 113 | _ => target_arch, 114 | }; 115 | 116 | let mut rustflags = get_rustflags(&workdir, target)?.unwrap_or_default(); 117 | rustflags 118 | .flags 119 | .extend(["-C".to_string(), "linker-flavor=lld-link".to_string()]); 120 | rustflags.push(format!( 121 | "-Lnative={dir}/crt/lib/{arch}", 122 | dir = xwin_dir, 123 | arch = xwin_arch 124 | )); 125 | rustflags.push(format!( 126 | "-Lnative={dir}/sdk/lib/um/{arch}", 127 | dir = xwin_dir, 128 | arch = xwin_arch 129 | )); 130 | rustflags.push(format!( 131 | "-Lnative={dir}/sdk/lib/ucrt/{arch}", 132 | dir = xwin_dir, 133 | arch = xwin_arch 134 | )); 135 | cmd.env("CARGO_ENCODED_RUSTFLAGS", rustflags.encode()?); 136 | cmd.env("PATH", &env_path); 137 | 138 | // CMake support 139 | let cmake_toolchain = self 140 | .setup_cmake_toolchain(target, &xwin_cache_dir) 141 | .with_context(|| format!("Failed to setup CMake toolchain for {}", target))?; 142 | setup_cmake_env(cmd, target, cmake_toolchain); 143 | } 144 | } 145 | Ok(()) 146 | } 147 | 148 | /// Downloads and extracts the specified MSVC CRT components into the specified `cache_dir`. 149 | fn setup_msvc_crt(&self, cache_dir: PathBuf) -> Result<()> { 150 | let done_mark_file = cache_dir.join("DONE"); 151 | let xwin_arches: HashSet<_> = self 152 | .xwin_options 153 | .xwin_arch 154 | .iter() 155 | .map(|x| x.as_str().to_string()) 156 | .collect(); 157 | let mut downloaded_arches = HashSet::new(); 158 | if let Ok(content) = fs::read_to_string(&done_mark_file) { 159 | for arch in content.split_whitespace() { 160 | downloaded_arches.insert(arch.to_string()); 161 | } 162 | } 163 | if xwin_arches.difference(&downloaded_arches).next().is_none() { 164 | return Ok(()); 165 | } 166 | 167 | let draw_target = ProgressTarget::Stdout; 168 | 169 | let agent = http_agent()?; 170 | let xwin_dir = adjust_canonicalization(cache_dir.to_slash_lossy().to_string()); 171 | // timeout defaults to 60s 172 | let ctx = xwin::Ctx::with_dir(xwin::PathBuf::from(xwin_dir), draw_target, agent)?; 173 | let ctx = std::sync::Arc::new(ctx); 174 | let pkg_manifest = self.load_manifest(&ctx, draw_target)?; 175 | 176 | let arches = self 177 | .xwin_options 178 | .xwin_arch 179 | .iter() 180 | .fold(0, |acc, arch| acc | *arch as u32); 181 | let variants = self 182 | .xwin_options 183 | .xwin_variant 184 | .iter() 185 | .fold(0, |acc, var| acc | *var as u32); 186 | let pruned = xwin::prune_pkg_list(&pkg_manifest, arches, variants, false, None, None)?; 187 | let op = xwin::Ops::Splat(xwin::SplatConfig { 188 | include_debug_libs: self.xwin_options.xwin_include_debug_libs, 189 | include_debug_symbols: self.xwin_options.xwin_include_debug_symbols, 190 | enable_symlinks: !cfg!(target_os = "macos"), 191 | preserve_ms_arch_notation: false, 192 | use_winsysroot_style: false, 193 | copy: false, 194 | output: cache_dir.clone().try_into()?, 195 | map: None, 196 | }); 197 | let pkgs = pkg_manifest.packages; 198 | 199 | let mp = MultiProgress::with_draw_target(draw_target.into()); 200 | let work_items: Vec<_> = pruned.payloads 201 | .into_iter() 202 | .map(|pay| { 203 | let prefix = match pay.kind { 204 | xwin::PayloadKind::CrtHeaders => "CRT.headers".to_owned(), 205 | xwin::PayloadKind::AtlHeaders => "ATL.headers".to_owned(), 206 | xwin::PayloadKind::CrtLibs => { 207 | format!( 208 | "CRT.libs.{}.{}", 209 | pay.target_arch.map(|ta| ta.as_str()).unwrap_or("all"), 210 | pay.variant.map(|v| v.as_str()).unwrap_or("none") 211 | ) 212 | } 213 | xwin::PayloadKind::AtlLibs => { 214 | format!( 215 | "ATL.libs.{}", 216 | pay.target_arch.map(|ta| ta.as_str()).unwrap_or("all"), 217 | ) 218 | } 219 | xwin::PayloadKind::SdkHeaders => { 220 | format!( 221 | "SDK.headers.{}.{}", 222 | pay.target_arch.map(|v| v.as_str()).unwrap_or("all"), 223 | pay.variant.map(|v| v.as_str()).unwrap_or("none") 224 | ) 225 | } 226 | xwin::PayloadKind::SdkLibs => { 227 | format!( 228 | "SDK.libs.{}", 229 | pay.target_arch.map(|ta| ta.as_str()).unwrap_or("all") 230 | ) 231 | } 232 | xwin::PayloadKind::SdkStoreLibs => "SDK.libs.store.all".to_owned(), 233 | xwin::PayloadKind::Ucrt => "SDK.ucrt.all".to_owned(), 234 | }; 235 | 236 | let pb = mp.add( 237 | ProgressBar::with_draw_target(Some(0), draw_target.into()).with_prefix(prefix).with_style( 238 | ProgressStyle::default_bar() 239 | .template("{spinner:.green} {prefix:.bold} [{elapsed}] {wide_bar:.green} {bytes}/{total_bytes} {msg}").unwrap() 240 | .progress_chars("=> "), 241 | ), 242 | ); 243 | xwin::WorkItem { 244 | payload: std::sync::Arc::new(pay), 245 | progress: pb, 246 | } 247 | }) 248 | .collect(); 249 | 250 | mp.set_move_cursor(true); 251 | if mp.is_hidden() { 252 | eprintln!("⏬ Downloading MSVC CRT..."); 253 | } 254 | let start_time = Instant::now(); 255 | ctx.execute( 256 | pkgs, 257 | work_items, 258 | pruned.crt_version, 259 | pruned.sdk_version, 260 | arches, 261 | variants, 262 | op, 263 | )?; 264 | 265 | let downloaded_arches: Vec<_> = self 266 | .xwin_options 267 | .xwin_arch 268 | .iter() 269 | .map(|x| x.as_str().to_string()) 270 | .collect(); 271 | fs::write(done_mark_file, downloaded_arches.join(" "))?; 272 | 273 | let dl = cache_dir.join("dl"); 274 | if dl.exists() { 275 | let _ = fs::remove_dir_all(dl); 276 | } 277 | let unpack = cache_dir.join("unpack"); 278 | if unpack.exists() { 279 | let _ = fs::remove_dir_all(unpack); 280 | } 281 | if mp.is_hidden() { 282 | // Display elapsed time in human-readable format to seconds only 283 | let elapsed = 284 | humantime::format_duration(Duration::from_secs(start_time.elapsed().as_secs())); 285 | eprintln!("✅ Downloaded MSVC CRT in {elapsed}."); 286 | } 287 | Ok(()) 288 | } 289 | 290 | fn load_manifest( 291 | &self, 292 | ctx: &xwin::Ctx, 293 | dt: ProgressTarget, 294 | ) -> Result { 295 | let manifest_pb = ProgressBar::with_draw_target(Some(0), dt.into()) 296 | .with_style( 297 | ProgressStyle::default_bar() 298 | .template( 299 | "{spinner:.green} {prefix:.bold} [{elapsed}] {wide_bar:.green} {bytes}/{total_bytes} {msg}", 300 | )? 301 | .progress_chars("=> "), 302 | ); 303 | manifest_pb.set_prefix("Manifest"); 304 | manifest_pb.set_message("📥 downloading"); 305 | 306 | let manifest = xwin::manifest::get_manifest( 307 | ctx, 308 | &self.xwin_options.xwin_version, 309 | "release", 310 | manifest_pb.clone(), 311 | )?; 312 | let pkg_manifest = 313 | xwin::manifest::get_package_manifest(ctx, &manifest, manifest_pb.clone())?; 314 | manifest_pb.finish_with_message("📥 downloaded"); 315 | Ok(pkg_manifest) 316 | } 317 | 318 | fn setup_cmake_toolchain(&self, target: &str, xwin_cache_dir: &Path) -> Result { 319 | let cmake_cache_dir = xwin_cache_dir 320 | .parent() 321 | .unwrap() 322 | .join("cmake") 323 | .join("clang-cl"); 324 | fs::create_dir_all(&cmake_cache_dir)?; 325 | 326 | let override_file = cmake_cache_dir.join("override.cmake"); 327 | fs::write(override_file, include_bytes!("override.cmake"))?; 328 | 329 | let toolchain_file = cmake_cache_dir.join(format!("{}-toolchain.cmake", target)); 330 | let target_arch = target 331 | .split_once('-') 332 | .map(|(x, _)| x) 333 | .context("invalid target triple")?; 334 | let processor = match target_arch { 335 | "i586" | "i686" => "X86", 336 | "x86_64" => "AMD64", 337 | "aarch64" => "ARM64", 338 | "arm64ec" => "ARM64EC", 339 | _ => target_arch, 340 | }; 341 | let xwin_arch = match target_arch { 342 | "i586" | "i686" => "x86", 343 | _ => target_arch, 344 | }; 345 | 346 | let content = format!( 347 | r#" 348 | set(CMAKE_SYSTEM_NAME Windows) 349 | set(CMAKE_SYSTEM_PROCESSOR {processor}) 350 | 351 | set(CMAKE_C_COMPILER clang-cl CACHE FILEPATH "") 352 | set(CMAKE_CXX_COMPILER clang-cl CACHE FILEPATH "") 353 | set(CMAKE_AR llvm-lib) 354 | set(CMAKE_LINKER lld-link CACHE FILEPATH "") 355 | 356 | set(COMPILE_FLAGS 357 | --target={target} 358 | -Wno-unused-command-line-argument 359 | -fuse-ld=lld-link 360 | 361 | /imsvc{xwin_dir}/crt/include 362 | /imsvc{xwin_dir}/sdk/include/ucrt 363 | /imsvc{xwin_dir}/sdk/include/um 364 | /imsvc{xwin_dir}/sdk/include/shared) 365 | 366 | set(LINK_FLAGS 367 | /manifest:no 368 | 369 | -libpath:"{xwin_dir}/crt/lib/{xwin_arch}" 370 | -libpath:"{xwin_dir}/sdk/lib/um/{xwin_arch}" 371 | -libpath:"{xwin_dir}/sdk/lib/ucrt/{xwin_arch}") 372 | 373 | string(REPLACE ";" " " COMPILE_FLAGS "${{COMPILE_FLAGS}}") 374 | 375 | set(_CMAKE_C_FLAGS_INITIAL "${{CMAKE_C_FLAGS}}" CACHE STRING "") 376 | set(CMAKE_C_FLAGS "${{_CMAKE_C_FLAGS_INITIAL}} ${{COMPILE_FLAGS}}" CACHE STRING "" FORCE) 377 | 378 | set(_CMAKE_CXX_FLAGS_INITIAL "${{CMAKE_CXX_FLAGS}}" CACHE STRING "") 379 | set(CMAKE_CXX_FLAGS "${{_CMAKE_CXX_FLAGS_INITIAL}} ${{COMPILE_FLAGS}} /EHsc" CACHE STRING "" FORCE) 380 | 381 | string(REPLACE ";" " " LINK_FLAGS "${{LINK_FLAGS}}") 382 | 383 | set(_CMAKE_EXE_LINKER_FLAGS_INITIAL "${{CMAKE_EXE_LINKER_FLAGS}}" CACHE STRING "") 384 | set(CMAKE_EXE_LINKER_FLAGS "${{_CMAKE_EXE_LINKER_FLAGS_INITIAL}} ${{LINK_FLAGS}}" CACHE STRING "" FORCE) 385 | 386 | set(_CMAKE_MODULE_LINKER_FLAGS_INITIAL "${{CMAKE_MODULE_LINKER_FLAGS}}" CACHE STRING "") 387 | set(CMAKE_MODULE_LINKER_FLAGS "${{_CMAKE_MODULE_LINKER_FLAGS_INITIAL}} ${{LINK_FLAGS}}" CACHE STRING "" FORCE) 388 | 389 | set(_CMAKE_SHARED_LINKER_FLAGS_INITIAL "${{CMAKE_SHARED_LINKER_FLAGS}}" CACHE STRING "") 390 | set(CMAKE_SHARED_LINKER_FLAGS "${{_CMAKE_SHARED_LINKER_FLAGS_INITIAL}} ${{LINK_FLAGS}}" CACHE STRING "" FORCE) 391 | 392 | # CMake populates these with a bunch of unnecessary libraries, which requires 393 | # extra case-correcting symlinks and what not. Instead, let projects explicitly 394 | # control which libraries they require. 395 | set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE) 396 | set(CMAKE_CXX_STANDARD_LIBRARIES "" CACHE STRING "" FORCE) 397 | 398 | set(CMAKE_TRY_COMPILE_CONFIGURATION Release) 399 | 400 | # Allow clang-cl to work with macOS paths. 401 | set(CMAKE_USER_MAKE_RULES_OVERRIDE "${{CMAKE_CURRENT_LIST_DIR}}/override.cmake") 402 | "#, 403 | target = target, 404 | processor = processor, 405 | xwin_dir = adjust_canonicalization(xwin_cache_dir.to_slash_lossy().to_string()), 406 | xwin_arch = xwin_arch, 407 | ); 408 | fs::write(&toolchain_file, content)?; 409 | Ok(toolchain_file) 410 | } 411 | } 412 | 413 | /// Creates a symlink to the `clang` binary in `cache_dir` and names it 414 | /// `clang-cl`. This is necessary because the `clang-cl` binary doesn't 415 | /// exist on macOS, but `clang` does and can be used as a drop-in 416 | /// replacement for `clang-cl`. 417 | /// 418 | /// The `clang` binary is first searched for in `PATH` (skipping the system 419 | /// clang), and if no suitable clang is found, the Xcode clang is tried as 420 | /// a fallback. If no usable clang is found, the function does nothing. 421 | #[cfg(target_os = "macos")] 422 | pub fn setup_clang_cl_symlink(env_path: &OsStr, cache_dir: &Path) -> Result<()> { 423 | // Try PATH first, but skip system clang 424 | let clang = which_in("clang", Some(env_path), env::current_dir()?) 425 | .ok() 426 | .and_then(|clang| { 427 | if clang != PathBuf::from("/usr/bin/clang") { 428 | Some(clang) 429 | } else { 430 | None 431 | } 432 | }); 433 | 434 | // Fall back to xcrun if no suitable clang found in PATH 435 | let clang = if let Some(clang) = clang { 436 | clang 437 | } else { 438 | // Try Xcode clang as fallback 439 | if let Ok(output) = Command::new("xcrun").args(["--find", "clang"]).output() { 440 | if output.status.success() { 441 | if let Ok(path) = String::from_utf8(output.stdout) { 442 | PathBuf::from(path.trim()) 443 | } else { 444 | // No usable clang found 445 | return Ok(()); 446 | } 447 | } else { 448 | // No usable clang found 449 | return Ok(()); 450 | } 451 | } else { 452 | // No usable clang found 453 | return Ok(()); 454 | } 455 | }; 456 | 457 | let symlink = cache_dir.join("clang-cl"); 458 | if symlink.is_symlink() || symlink.is_file() { 459 | fs::remove_file(&symlink)?; 460 | } 461 | fs_err::os::unix::fs::symlink(clang, symlink)?; 462 | Ok(()) 463 | } 464 | 465 | #[cfg(not(target_os = "macos"))] 466 | pub fn setup_clang_cl_symlink(env_path: &OsStr, cache_dir: &Path) -> Result<()> { 467 | if let Ok(clang) = which_in("clang", Some(env_path), env::current_dir()?) { 468 | #[cfg(windows)] 469 | { 470 | let symlink = cache_dir.join("clang-cl.exe"); 471 | if symlink.exists() { 472 | fs::remove_file(&symlink)?; 473 | } 474 | fs_err::os::windows::fs::symlink_file(clang, symlink)?; 475 | } 476 | 477 | #[cfg(unix)] 478 | { 479 | let symlink = cache_dir.join("clang-cl"); 480 | if symlink.exists() { 481 | fs::remove_file(&symlink)?; 482 | } 483 | fs_err::os::unix::fs::symlink(clang, symlink)?; 484 | } 485 | } 486 | Ok(()) 487 | } 488 | -------------------------------------------------------------------------------- /src/compiler/common.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use fs_err as fs; 3 | use std::env; 4 | use std::ffi::{OsStr, OsString}; 5 | use std::path::{Path, PathBuf}; 6 | use std::process::Command; 7 | use which::which_in; 8 | 9 | /// Sets up the environment path by adding necessary directories to the existing `PATH`. 10 | /// 11 | /// On macOS, it checks for specific LLVM installation paths based on the architecture 12 | /// and adds them to the front of the environment paths if they exist. 13 | /// It then appends the `cache_dir` provided to the list of paths. 14 | pub fn setup_env_path(cache_dir: &Path) -> Result { 15 | let env_path = env::var("PATH").unwrap_or_default(); 16 | let mut env_paths: Vec<_> = env::split_paths(&env_path).collect(); 17 | if cfg!(target_os = "macos") { 18 | // setup macos homebrew llvm paths 19 | let usr_llvm = "/usr/local/opt/llvm/bin".into(); 20 | let opt_llvm = "/opt/homebrew/opt/llvm/bin".into(); 21 | if cfg!(target_arch = "x86_64") 22 | && Path::new(&usr_llvm).is_dir() 23 | && !env_paths.contains(&usr_llvm) 24 | { 25 | env_paths.insert(0, usr_llvm); 26 | } else if cfg!(target_arch = "aarch64") 27 | && Path::new(&opt_llvm).is_dir() 28 | && !env_paths.contains(&opt_llvm) 29 | { 30 | env_paths.insert(0, opt_llvm); 31 | } 32 | } 33 | env_paths.push(cache_dir.to_path_buf()); 34 | Ok(env::join_paths(env_paths)?) 35 | } 36 | 37 | /// Sets up symlinks for LLVM tools in the provided environment path and cache directory. 38 | /// 39 | /// This function creates symlinks for the following tools: 40 | /// - `rust-lld` to `lld-link` 41 | /// - `llvm-ar` to `llvm-lib` 42 | /// - `llvm-ar` to `llvm-dlltool` 43 | /// 44 | /// These symlinks are established if they do not already exist in the specified environment path. 45 | pub fn setup_llvm_tools(env_path: &OsStr, cache_dir: &Path) -> Result<()> { 46 | symlink_llvm_tool("rust-lld", "lld-link", env_path, cache_dir)?; 47 | symlink_llvm_tool("llvm-ar", "llvm-lib", env_path, cache_dir)?; 48 | symlink_llvm_tool("llvm-ar", "llvm-dlltool", env_path, cache_dir)?; 49 | Ok(()) 50 | } 51 | 52 | /// Configures the environment variables for the target compiler and linker. 53 | /// 54 | /// This function sets up environment variables for the specified target compiler and linker, 55 | /// allowing the build system to correctly use the desired tools for compilation and linking. 56 | /// It sets up the following environment variables: 57 | /// - `TARGET_CC` and `TARGET_CXX` with the provided compiler. 58 | /// - `CC_` and `CXX_` with the provided compiler. 59 | /// - `TARGET_AR` and `AR_` with "llvm-lib". 60 | /// - `CARGO_TARGET__LINKER` with "lld-link". 61 | pub fn setup_target_compiler_and_linker_env(cmd: &mut Command, env_target: &str, compiler: &str) { 62 | cmd.env("TARGET_CC", compiler); 63 | cmd.env("TARGET_CXX", compiler); 64 | cmd.env(format!("CC_{}", env_target), compiler); 65 | cmd.env(format!("CXX_{}", env_target), compiler); 66 | cmd.env("TARGET_AR", "llvm-lib"); 67 | cmd.env(format!("AR_{}", env_target), "llvm-lib"); 68 | cmd.env( 69 | format!("CARGO_TARGET_{}_LINKER", env_target.to_uppercase()), 70 | "lld-link", 71 | ); 72 | } 73 | 74 | /// Configures the environment variables for CMake to use the Ninja generator and Windows system. 75 | /// 76 | /// This function sets up the following environment variables: 77 | /// - `CMAKE_GENERATOR` as "Ninja". 78 | /// - `CMAKE_SYSTEM_NAME` as "Windows". 79 | /// - `CMAKE_TOOLCHAIN_FILE_` with the provided toolchain path, where `` is the target string 80 | /// converted to lowercase and hyphens replaced with underscores. 81 | pub fn setup_cmake_env(cmd: &mut Command, target: &str, toolchain_path: PathBuf) { 82 | let env_target = target.to_lowercase().replace('-', "_"); 83 | cmd.env("CMAKE_GENERATOR", "Ninja") 84 | .env("CMAKE_SYSTEM_NAME", "Windows") 85 | .env( 86 | format!("CMAKE_TOOLCHAIN_FILE_{}", env_target), 87 | toolchain_path, 88 | ); 89 | } 90 | 91 | pub fn rustc_target_bin_dir() -> Result { 92 | let output = Command::new("rustc") 93 | .args(["--print", "target-libdir"]) 94 | .output()?; 95 | let stdout = String::from_utf8(output.stdout)?; 96 | let lib_dir = Path::new(&stdout); 97 | let bin_dir = lib_dir.parent().unwrap().join("bin"); 98 | Ok(bin_dir) 99 | } 100 | 101 | /// Symlink Rust provided llvm tool component 102 | fn symlink_llvm_tool( 103 | tool: &str, 104 | link_name: &str, 105 | env_path: &OsStr, 106 | cache_dir: &Path, 107 | ) -> Result<()> { 108 | if which_in(link_name, Some(env_path), env::current_dir()?).is_err() { 109 | let bin_dir = rustc_target_bin_dir()?; 110 | let rust_tool = bin_dir.join(tool); 111 | if rust_tool.exists() { 112 | #[cfg(windows)] 113 | { 114 | let symlink = cache_dir.join(format!("{}.exe", link_name)); 115 | if symlink.is_symlink() || symlink.is_file() { 116 | fs::remove_file(&symlink)?; 117 | } 118 | fs_err::os::windows::fs::symlink_file(rust_tool, symlink)?; 119 | } 120 | 121 | #[cfg(unix)] 122 | { 123 | let symlink = cache_dir.join(link_name); 124 | if symlink.is_symlink() || symlink.is_file() { 125 | fs::remove_file(&symlink)?; 126 | } 127 | fs_err::os::unix::fs::symlink(rust_tool, symlink)?; 128 | } 129 | } 130 | } 131 | Ok(()) 132 | } 133 | 134 | #[cfg(target_family = "unix")] 135 | pub fn adjust_canonicalization(p: String) -> String { 136 | p 137 | } 138 | 139 | #[cfg(target_os = "windows")] 140 | pub fn adjust_canonicalization(p: String) -> String { 141 | const VERBATIM_PREFIX: &str = r#"\\?\"#; 142 | if let Some(p) = p.strip_prefix(VERBATIM_PREFIX) { 143 | p.to_string() 144 | } else { 145 | p 146 | } 147 | } 148 | 149 | pub fn default_build_target_from_config(workdir: &Path) -> Result> { 150 | let output = Command::new("cargo") 151 | .current_dir(workdir) 152 | .args([ 153 | "config", 154 | "get", 155 | "-Z", 156 | "unstable-options", 157 | "--format", 158 | "json-value", 159 | "build.target", 160 | ]) 161 | .env("__CARGO_TEST_CHANNEL_OVERRIDE_DO_NOT_USE_THIS", "nightly") 162 | .output()?; 163 | if !output.status.success() { 164 | return Ok(None); 165 | } 166 | let stdout = String::from_utf8(output.stdout)?; 167 | let target = stdout.trim().trim_matches('"'); 168 | Ok(Some(target.to_string())) 169 | } 170 | 171 | /// Get RUSTFLAGS in the following order: 172 | /// 173 | /// 1. `RUSTFLAGS` environment variable. 174 | /// 2. `rustflags` cargo configuration 175 | pub fn get_rustflags(workdir: &Path, target: &str) -> Result> { 176 | let cargo_config = cargo_config2::Config::load_with_cwd(workdir)?; 177 | let rustflags = cargo_config.rustflags(target)?; 178 | Ok(rustflags) 179 | } 180 | 181 | #[cfg(any(feature = "native-tls", feature = "rustls"))] 182 | fn tls_ca_bundle() -> Option { 183 | env::var_os("REQUESTS_CA_BUNDLE") 184 | .or_else(|| env::var_os("CURL_CA_BUNDLE")) 185 | .or_else(|| env::var_os("SSL_CERT_FILE")) 186 | } 187 | 188 | #[cfg(all(feature = "native-tls", not(feature = "rustls")))] 189 | pub fn http_agent() -> Result { 190 | use fs_err::File; 191 | use std::io; 192 | use std::sync::Arc; 193 | 194 | let mut builder = ureq::builder().try_proxy_from_env(true); 195 | let mut tls_builder = native_tls_crate::TlsConnector::builder(); 196 | if let Some(ca_bundle) = tls_ca_bundle() { 197 | let mut reader = io::BufReader::new(File::open(ca_bundle)?); 198 | for cert in rustls_pemfile::certs(&mut reader) { 199 | let cert = cert?; 200 | tls_builder.add_root_certificate(native_tls_crate::Certificate::from_pem(&cert)?); 201 | } 202 | } 203 | builder = builder.tls_connector(Arc::new(tls_builder.build()?)); 204 | Ok(builder.build()) 205 | } 206 | 207 | #[cfg(feature = "rustls")] 208 | pub fn http_agent() -> Result { 209 | use fs_err::File; 210 | use std::io; 211 | use std::sync::Arc; 212 | 213 | let builder = ureq::builder().try_proxy_from_env(true); 214 | if let Some(ca_bundle) = tls_ca_bundle() { 215 | let mut reader = io::BufReader::new(File::open(ca_bundle)?); 216 | let certs = rustls_pemfile::certs(&mut reader).collect::, _>>()?; 217 | let mut root_certs = rustls::RootCertStore::empty(); 218 | root_certs.add_parsable_certificates(certs); 219 | let client_config = rustls::ClientConfig::builder() 220 | .with_root_certificates(root_certs) 221 | .with_no_client_auth(); 222 | Ok(builder.tls_config(Arc::new(client_config)).build()) 223 | } else { 224 | Ok(builder.build()) 225 | } 226 | } 227 | 228 | #[cfg(not(any(feature = "native-tls", feature = "rustls")))] 229 | pub fn http_agent() -> Result { 230 | let builder = ureq::builder().try_proxy_from_env(true); 231 | Ok(builder.build()) 232 | } 233 | -------------------------------------------------------------------------------- /src/compiler/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod clang; 2 | pub mod clang_cl; 3 | pub mod common; 4 | -------------------------------------------------------------------------------- /src/compiler/override.cmake: -------------------------------------------------------------------------------- 1 | # macOS paths usually start with /Users/*. Unfortunately, clang-cl interprets 2 | # paths starting with /U as macro undefines, so we need to put a -- before the 3 | # input file path to force it to be treated as a path. CMake's compilation rules 4 | # should be tweaked accordingly, but until that's done, and to support older 5 | # CMake versions, overriding compilation rules works well enough. This file will 6 | # be included by cmake after the default compilation rules have already been set 7 | # up, so we can just modify them instead of duplicating them entirely. 8 | string(REPLACE "-c " "-c -- " CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}") 9 | string(REPLACE "-c " "-c -- " CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}") 10 | # why not CMAKE_RC_FLAGS_INIT out? fixed in cmake e53a968e (replace " /D", but in old cmake, it's "/D") 11 | string(REPLACE "/D" "-D" CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS_INIT}") 12 | string(REPLACE "/D" "-D" CMAKE_RC_FLAGS_DEBUG "${CMAKE_RC_FLAGS_DEBUG_INIT}") 13 | if(NOT CMAKE_HOST_WIN32) 14 | set(CMAKE_NINJA_CMCLDEPS_RC 0) # cmcldeps is windows only 15 | endif() -------------------------------------------------------------------------------- /src/env.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::ops::{Deref, DerefMut}; 3 | use std::path::PathBuf; 4 | use std::process::Command; 5 | 6 | use anyhow::Result; 7 | use clap::Parser; 8 | 9 | use crate::options::XWinOptions; 10 | 11 | /// Print environment variables required for cross-compilation 12 | #[derive(Clone, Debug, Default, Parser)] 13 | #[command(display_order = 1)] 14 | pub struct Env { 15 | #[command(flatten)] 16 | pub xwin: XWinOptions, 17 | 18 | #[command(flatten)] 19 | pub cargo: cargo_options::CommonOptions, 20 | 21 | #[arg(long, value_name = "PATH", help_heading = cargo_options::heading::MANIFEST_OPTIONS)] 22 | pub manifest_path: Option, 23 | } 24 | 25 | impl Env { 26 | /// Create a new env from manifest path 27 | #[allow(clippy::field_reassign_with_default)] 28 | pub fn new(manifest_path: Option) -> Self { 29 | let mut build = Self::default(); 30 | build.manifest_path = manifest_path; 31 | build 32 | } 33 | 34 | /// Print env 35 | pub fn execute(&self) -> Result<()> { 36 | let mut env = self.build_command()?; 37 | 38 | for target in &self.target { 39 | if target.contains("msvc") { 40 | if env::var_os("WINEDEBUG").is_none() { 41 | env.env("WINEDEBUG", "-all"); 42 | } 43 | let env_target = target.to_uppercase().replace('-', "_"); 44 | let runner_env = format!("CARGO_TARGET_{}_RUNNER", env_target); 45 | if env::var_os(&runner_env).is_none() { 46 | env.env(runner_env, "wine"); 47 | } 48 | } 49 | } 50 | 51 | for (key, value) in env.get_envs() { 52 | println!( 53 | "export {}=\"{}\";", 54 | key.to_string_lossy(), 55 | value.unwrap_or_default().to_string_lossy() 56 | ); 57 | } 58 | 59 | Ok(()) 60 | } 61 | 62 | /// Generate cargo subcommand 63 | pub fn build_command(&self) -> Result { 64 | let mut build = Command::new("cargo"); 65 | self.xwin 66 | .apply_command_env(self.manifest_path.as_deref(), &self.cargo, &mut build)?; 67 | Ok(build) 68 | } 69 | } 70 | 71 | impl Deref for Env { 72 | type Target = cargo_options::CommonOptions; 73 | 74 | fn deref(&self) -> &Self::Target { 75 | &self.cargo 76 | } 77 | } 78 | 79 | impl DerefMut for Env { 80 | fn deref_mut(&mut self) -> &mut Self::Target { 81 | &mut self.cargo 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | mod compiler; 2 | mod env; 3 | mod macros; 4 | mod options; 5 | mod run; 6 | mod test; 7 | 8 | pub use env::Env; 9 | pub use macros::{build::Build, check::Check, clippy::Clippy, doc::Doc, rustc::Rustc}; 10 | pub use options::XWinOptions; 11 | pub use run::Run; 12 | pub use test::Test; 13 | -------------------------------------------------------------------------------- /src/macros.rs: -------------------------------------------------------------------------------- 1 | use paste::paste; 2 | 3 | macro_rules! cargo_command { 4 | ($command: ident) => { 5 | paste! { 6 | pub mod [<$command:lower>] { 7 | use std::ops::{Deref, DerefMut}; 8 | use std::path::PathBuf; 9 | use std::process::{self, Command}; 10 | 11 | use anyhow::{Context, Result}; 12 | use clap::Parser; 13 | 14 | use crate::options::XWinOptions; 15 | 16 | #[derive(Clone, Debug, Default, Parser)] 17 | #[command( 18 | display_order = 1, 19 | about = "Run cargo " $command:lower " command", 20 | after_help = "Run `cargo help " $command:lower "` for more detailed information." 21 | )] 22 | pub struct $command { 23 | #[command(flatten)] 24 | pub cargo: cargo_options::$command, 25 | 26 | #[command(flatten)] 27 | pub xwin: XWinOptions, 28 | } 29 | 30 | impl $command { 31 | /// Create a new build from manifest path 32 | #[allow(clippy::field_reassign_with_default)] 33 | pub fn new(manifest_path: Option) -> Self { 34 | let mut build = Self::default(); 35 | build.manifest_path = manifest_path; 36 | build 37 | } 38 | 39 | /// Execute cargo command 40 | pub fn execute(&self) -> Result<()> { 41 | let current_command = stringify!([<$command:lower>]); 42 | let mut build = self.build_command()?; 43 | let mut child = build.spawn().with_context(|| format!("Failed to run cargo {current_command}"))?; 44 | let status = child.wait().expect(&format!("Failed to wait on cargo {current_command} process")); 45 | if !status.success() { 46 | process::exit(status.code().unwrap_or(1)); 47 | } 48 | Ok(()) 49 | } 50 | 51 | /// Generate cargo subcommand 52 | pub fn build_command(&self) -> Result { 53 | let mut build = self.cargo.command(); 54 | self.xwin.apply_command_env( 55 | self.manifest_path.as_deref(), 56 | &self.cargo.common, 57 | &mut build, 58 | )?; 59 | Ok(build) 60 | } 61 | } 62 | 63 | impl Deref for $command { 64 | type Target = cargo_options::$command; 65 | 66 | fn deref(&self) -> &Self::Target { 67 | &self.cargo 68 | } 69 | } 70 | 71 | impl DerefMut for $command { 72 | fn deref_mut(&mut self) -> &mut Self::Target { 73 | &mut self.cargo 74 | } 75 | } 76 | 77 | impl From for $command { 78 | fn from(cargo: cargo_options::$command) -> Self { 79 | Self { 80 | cargo, 81 | ..Default::default() 82 | } 83 | } 84 | } 85 | 86 | } 87 | } 88 | }; 89 | } 90 | 91 | cargo_command!(Build); 92 | cargo_command!(Check); 93 | cargo_command!(Clippy); 94 | cargo_command!(Doc); 95 | cargo_command!(Rustc); 96 | -------------------------------------------------------------------------------- /src/options.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | use std::process::Command; 3 | 4 | use anyhow::Result; 5 | use clap::{ 6 | builder::{PossibleValuesParser, TypedValueParser as _}, 7 | Parser, ValueEnum, 8 | }; 9 | use fs_err as fs; 10 | 11 | /// MSVC cross compiler 12 | #[derive(Clone, Debug, Default, ValueEnum)] 13 | pub enum CrossCompiler { 14 | /// clang-cl backend 15 | #[default] 16 | ClangCl, 17 | /// clang backend 18 | Clang, 19 | } 20 | 21 | /// common xwin options 22 | #[derive(Clone, Debug, Parser)] 23 | pub struct XWinOptions { 24 | /// The cross compiler to use 25 | #[arg(long, env = "XWIN_CROSS_COMPILER", default_value = "clang-cl")] 26 | pub cross_compiler: CrossCompiler, 27 | 28 | /// xwin cache directory 29 | #[arg(long, env = "XWIN_CACHE_DIR", hide = true)] 30 | pub xwin_cache_dir: Option, 31 | 32 | /// The architectures to include in CRT/SDK 33 | #[arg( 34 | long, 35 | env = "XWIN_ARCH", 36 | value_parser = PossibleValuesParser::new(["x86", "x86_64", "aarch", "aarch64"]) 37 | .map(|s| s.parse::().unwrap()), 38 | value_delimiter = ',', 39 | default_values_t = vec![xwin::Arch::X86_64, xwin::Arch::Aarch64], 40 | hide = true, 41 | )] 42 | pub xwin_arch: Vec, 43 | 44 | /// The variants to include 45 | #[arg( 46 | long, 47 | env = "XWIN_VARIANT", 48 | value_parser = PossibleValuesParser::new(["desktop", "onecore", /*"store",*/ "spectre"]) 49 | .map(|s| s.parse::().unwrap()), 50 | value_delimiter = ',', 51 | default_values_t = vec![xwin::Variant::Desktop], 52 | hide = true, 53 | )] 54 | pub xwin_variant: Vec, 55 | 56 | /// The version to retrieve, can either be a major version of 15, 16 or 17, or 57 | /// a "." version. 58 | #[arg(long, env = "XWIN_VERSION", default_value = "16", hide = true)] 59 | pub xwin_version: String, 60 | 61 | /// Whether or not to include debug libs 62 | #[arg(long, env = "XWIN_INCLUDE_DEBUG_LIBS", hide = true)] 63 | pub xwin_include_debug_libs: bool, 64 | 65 | /// Whether or not to include debug symbols (PDBs) 66 | #[arg(long, env = "XWIN_INCLUDE_DEBUG_SYMBOLS", hide = true)] 67 | pub xwin_include_debug_symbols: bool, 68 | } 69 | 70 | impl Default for XWinOptions { 71 | fn default() -> Self { 72 | Self { 73 | xwin_cache_dir: None, 74 | xwin_arch: vec![xwin::Arch::X86_64, xwin::Arch::Aarch64], 75 | xwin_variant: vec![xwin::Variant::Desktop], 76 | xwin_version: "16".to_string(), 77 | xwin_include_debug_libs: false, 78 | xwin_include_debug_symbols: false, 79 | cross_compiler: CrossCompiler::ClangCl, 80 | } 81 | } 82 | } 83 | 84 | impl XWinOptions { 85 | pub fn apply_command_env( 86 | &self, 87 | manifest_path: Option<&Path>, 88 | cargo: &cargo_options::CommonOptions, 89 | cmd: &mut Command, 90 | ) -> Result<()> { 91 | let cache_dir = { 92 | let cache_dir = self.xwin_cache_dir.clone().unwrap_or_else(|| { 93 | dirs::cache_dir() 94 | .unwrap_or_else(|| std::env::current_dir().expect("Failed to get current dir")) 95 | .join(env!("CARGO_PKG_NAME")) 96 | }); 97 | fs::create_dir_all(&cache_dir)?; 98 | cache_dir.canonicalize()? 99 | }; 100 | match self.cross_compiler { 101 | CrossCompiler::ClangCl => { 102 | let clang_cl = crate::compiler::clang_cl::ClangCl::new(self); 103 | clang_cl.apply_command_env(manifest_path, cargo, cache_dir, cmd)?; 104 | } 105 | CrossCompiler::Clang => { 106 | let clang = crate::compiler::clang::Clang::new(); 107 | clang.apply_command_env(manifest_path, cargo, cache_dir, cmd)?; 108 | } 109 | } 110 | Ok(()) 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/run.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::ops::{Deref, DerefMut}; 3 | use std::path::PathBuf; 4 | use std::process::{self, Command}; 5 | 6 | use anyhow::{Context, Result}; 7 | use clap::Parser; 8 | 9 | use crate::options::XWinOptions; 10 | 11 | /// Run a binary or example of the local package 12 | #[derive(Clone, Debug, Default, Parser)] 13 | #[command( 14 | display_order = 1, 15 | after_help = "Run `cargo help run` for more detailed information." 16 | )] 17 | pub struct Run { 18 | #[command(flatten)] 19 | pub xwin: XWinOptions, 20 | 21 | #[command(flatten)] 22 | pub cargo: cargo_options::Run, 23 | } 24 | 25 | impl Run { 26 | /// Create a new run from manifest path 27 | #[allow(clippy::field_reassign_with_default)] 28 | pub fn new(manifest_path: Option) -> Self { 29 | let mut build = Self::default(); 30 | build.manifest_path = manifest_path; 31 | build 32 | } 33 | 34 | /// Execute `cargo run` command 35 | pub fn execute(&self) -> Result<()> { 36 | let mut run = self.build_command()?; 37 | 38 | for target in &self.cargo.target { 39 | if target.contains("msvc") { 40 | if env::var_os("WINEDEBUG").is_none() { 41 | run.env("WINEDEBUG", "-all"); 42 | } 43 | let env_target = target.to_uppercase().replace('-', "_"); 44 | let runner_env = format!("CARGO_TARGET_{}_RUNNER", env_target); 45 | if env::var_os(&runner_env).is_none() { 46 | run.env(runner_env, "wine"); 47 | } 48 | } 49 | } 50 | 51 | let mut child = run.spawn().context("Failed to run cargo run")?; 52 | let status = child.wait().expect("Failed to wait on cargo run process"); 53 | if !status.success() { 54 | process::exit(status.code().unwrap_or(1)); 55 | } 56 | Ok(()) 57 | } 58 | 59 | /// Generate cargo subcommand 60 | pub fn build_command(&self) -> Result { 61 | let mut build = self.cargo.command(); 62 | self.xwin.apply_command_env( 63 | self.manifest_path.as_deref(), 64 | &self.cargo.common, 65 | &mut build, 66 | )?; 67 | Ok(build) 68 | } 69 | } 70 | 71 | impl Deref for Run { 72 | type Target = cargo_options::Run; 73 | 74 | fn deref(&self) -> &Self::Target { 75 | &self.cargo 76 | } 77 | } 78 | 79 | impl DerefMut for Run { 80 | fn deref_mut(&mut self) -> &mut Self::Target { 81 | &mut self.cargo 82 | } 83 | } 84 | 85 | impl From for Run { 86 | fn from(cargo: cargo_options::Run) -> Self { 87 | Self { 88 | cargo, 89 | ..Default::default() 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/test.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::ops::{Deref, DerefMut}; 3 | use std::path::PathBuf; 4 | use std::process::{self, Command}; 5 | 6 | use anyhow::{Context, Result}; 7 | use clap::Parser; 8 | 9 | use crate::options::XWinOptions; 10 | 11 | /// Execute all unit and integration tests and build examples of a local package 12 | #[derive(Clone, Debug, Default, Parser)] 13 | #[command( 14 | display_order = 1, 15 | after_help = "Run `cargo help test` for more detailed information.\nRun `cargo test -- --help` for test binary options." 16 | )] 17 | pub struct Test { 18 | #[command(flatten)] 19 | pub xwin: XWinOptions, 20 | 21 | #[command(flatten)] 22 | pub cargo: cargo_options::Test, 23 | } 24 | 25 | impl Test { 26 | /// Create a new test from manifest path 27 | #[allow(clippy::field_reassign_with_default)] 28 | pub fn new(manifest_path: Option) -> Self { 29 | let mut build = Self::default(); 30 | build.manifest_path = manifest_path; 31 | build 32 | } 33 | 34 | /// Execute `cargo test` command 35 | pub fn execute(&self) -> Result<()> { 36 | let mut test = self.build_command()?; 37 | 38 | for target in &self.cargo.target { 39 | if target.contains("msvc") { 40 | if env::var_os("WINEDEBUG").is_none() { 41 | test.env("WINEDEBUG", "-all"); 42 | } 43 | let env_target = target.to_uppercase().replace('-', "_"); 44 | let runner_env = format!("CARGO_TARGET_{}_RUNNER", env_target); 45 | if env::var_os(&runner_env).is_none() { 46 | test.env(runner_env, "wine"); 47 | } 48 | } 49 | } 50 | 51 | let mut child = test.spawn().context("Failed to run cargo test")?; 52 | let status = child.wait().expect("Failed to wait on cargo test process"); 53 | if !status.success() { 54 | process::exit(status.code().unwrap_or(1)); 55 | } 56 | Ok(()) 57 | } 58 | 59 | /// Generate cargo subcommand 60 | pub fn build_command(&self) -> Result { 61 | let mut build = self.cargo.command(); 62 | self.xwin.apply_command_env( 63 | self.manifest_path.as_deref(), 64 | &self.cargo.common, 65 | &mut build, 66 | )?; 67 | Ok(build) 68 | } 69 | } 70 | 71 | impl Deref for Test { 72 | type Target = cargo_options::Test; 73 | 74 | fn deref(&self) -> &Self::Target { 75 | &self.cargo 76 | } 77 | } 78 | 79 | impl DerefMut for Test { 80 | fn deref_mut(&mut self) -> &mut Self::Target { 81 | &mut self.cargo 82 | } 83 | } 84 | 85 | impl From for Test { 86 | fn from(cargo: cargo_options::Test) -> Self { 87 | Self { 88 | cargo, 89 | ..Default::default() 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /tests/hello-rustls/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.4.0" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 25 | 26 | [[package]] 27 | name = "backtrace" 28 | version = "0.3.75" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 31 | dependencies = [ 32 | "addr2line", 33 | "cfg-if", 34 | "libc", 35 | "miniz_oxide", 36 | "object", 37 | "rustc-demangle", 38 | "windows-targets", 39 | ] 40 | 41 | [[package]] 42 | name = "base64" 43 | version = "0.22.1" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 46 | 47 | [[package]] 48 | name = "bitflags" 49 | version = "2.9.1" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 52 | 53 | [[package]] 54 | name = "bumpalo" 55 | version = "3.17.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 58 | 59 | [[package]] 60 | name = "bytes" 61 | version = "1.10.1" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 64 | 65 | [[package]] 66 | name = "cc" 67 | version = "1.2.25" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" 70 | dependencies = [ 71 | "shlex", 72 | ] 73 | 74 | [[package]] 75 | name = "cfg-if" 76 | version = "1.0.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 79 | 80 | [[package]] 81 | name = "cfg_aliases" 82 | version = "0.2.1" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" 85 | 86 | [[package]] 87 | name = "displaydoc" 88 | version = "0.2.5" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 91 | dependencies = [ 92 | "proc-macro2", 93 | "quote", 94 | "syn", 95 | ] 96 | 97 | [[package]] 98 | name = "fnv" 99 | version = "1.0.7" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 102 | 103 | [[package]] 104 | name = "form_urlencoded" 105 | version = "1.2.1" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 108 | dependencies = [ 109 | "percent-encoding", 110 | ] 111 | 112 | [[package]] 113 | name = "futures-channel" 114 | version = "0.3.31" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 117 | dependencies = [ 118 | "futures-core", 119 | ] 120 | 121 | [[package]] 122 | name = "futures-core" 123 | version = "0.3.31" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 126 | 127 | [[package]] 128 | name = "futures-task" 129 | version = "0.3.31" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 132 | 133 | [[package]] 134 | name = "futures-util" 135 | version = "0.3.31" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 138 | dependencies = [ 139 | "futures-core", 140 | "futures-task", 141 | "pin-project-lite", 142 | "pin-utils", 143 | ] 144 | 145 | [[package]] 146 | name = "getrandom" 147 | version = "0.2.16" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 150 | dependencies = [ 151 | "cfg-if", 152 | "js-sys", 153 | "libc", 154 | "wasi 0.11.0+wasi-snapshot-preview1", 155 | "wasm-bindgen", 156 | ] 157 | 158 | [[package]] 159 | name = "getrandom" 160 | version = "0.3.3" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 163 | dependencies = [ 164 | "cfg-if", 165 | "js-sys", 166 | "libc", 167 | "r-efi", 168 | "wasi 0.14.2+wasi-0.2.4", 169 | "wasm-bindgen", 170 | ] 171 | 172 | [[package]] 173 | name = "gimli" 174 | version = "0.31.1" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 177 | 178 | [[package]] 179 | name = "hello-rustls" 180 | version = "0.1.0" 181 | dependencies = [ 182 | "reqwest", 183 | "tokio", 184 | ] 185 | 186 | [[package]] 187 | name = "http" 188 | version = "1.3.1" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 191 | dependencies = [ 192 | "bytes", 193 | "fnv", 194 | "itoa", 195 | ] 196 | 197 | [[package]] 198 | name = "http-body" 199 | version = "1.0.1" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 202 | dependencies = [ 203 | "bytes", 204 | "http", 205 | ] 206 | 207 | [[package]] 208 | name = "http-body-util" 209 | version = "0.1.3" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 212 | dependencies = [ 213 | "bytes", 214 | "futures-core", 215 | "http", 216 | "http-body", 217 | "pin-project-lite", 218 | ] 219 | 220 | [[package]] 221 | name = "httparse" 222 | version = "1.10.1" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 225 | 226 | [[package]] 227 | name = "hyper" 228 | version = "1.6.0" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 231 | dependencies = [ 232 | "bytes", 233 | "futures-channel", 234 | "futures-util", 235 | "http", 236 | "http-body", 237 | "httparse", 238 | "itoa", 239 | "pin-project-lite", 240 | "smallvec", 241 | "tokio", 242 | "want", 243 | ] 244 | 245 | [[package]] 246 | name = "hyper-rustls" 247 | version = "0.27.6" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" 250 | dependencies = [ 251 | "http", 252 | "hyper", 253 | "hyper-util", 254 | "rustls", 255 | "rustls-pki-types", 256 | "tokio", 257 | "tokio-rustls", 258 | "tower-service", 259 | "webpki-roots", 260 | ] 261 | 262 | [[package]] 263 | name = "hyper-util" 264 | version = "0.1.13" 265 | source = "registry+https://github.com/rust-lang/crates.io-index" 266 | checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" 267 | dependencies = [ 268 | "base64", 269 | "bytes", 270 | "futures-channel", 271 | "futures-core", 272 | "futures-util", 273 | "http", 274 | "http-body", 275 | "hyper", 276 | "ipnet", 277 | "libc", 278 | "percent-encoding", 279 | "pin-project-lite", 280 | "socket2", 281 | "tokio", 282 | "tower-service", 283 | "tracing", 284 | ] 285 | 286 | [[package]] 287 | name = "icu_collections" 288 | version = "2.0.0" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" 291 | dependencies = [ 292 | "displaydoc", 293 | "potential_utf", 294 | "yoke", 295 | "zerofrom", 296 | "zerovec", 297 | ] 298 | 299 | [[package]] 300 | name = "icu_locale_core" 301 | version = "2.0.0" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" 304 | dependencies = [ 305 | "displaydoc", 306 | "litemap", 307 | "tinystr", 308 | "writeable", 309 | "zerovec", 310 | ] 311 | 312 | [[package]] 313 | name = "icu_normalizer" 314 | version = "2.0.0" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" 317 | dependencies = [ 318 | "displaydoc", 319 | "icu_collections", 320 | "icu_normalizer_data", 321 | "icu_properties", 322 | "icu_provider", 323 | "smallvec", 324 | "zerovec", 325 | ] 326 | 327 | [[package]] 328 | name = "icu_normalizer_data" 329 | version = "2.0.0" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" 332 | 333 | [[package]] 334 | name = "icu_properties" 335 | version = "2.0.1" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" 338 | dependencies = [ 339 | "displaydoc", 340 | "icu_collections", 341 | "icu_locale_core", 342 | "icu_properties_data", 343 | "icu_provider", 344 | "potential_utf", 345 | "zerotrie", 346 | "zerovec", 347 | ] 348 | 349 | [[package]] 350 | name = "icu_properties_data" 351 | version = "2.0.1" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" 354 | 355 | [[package]] 356 | name = "icu_provider" 357 | version = "2.0.0" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" 360 | dependencies = [ 361 | "displaydoc", 362 | "icu_locale_core", 363 | "stable_deref_trait", 364 | "tinystr", 365 | "writeable", 366 | "yoke", 367 | "zerofrom", 368 | "zerotrie", 369 | "zerovec", 370 | ] 371 | 372 | [[package]] 373 | name = "idna" 374 | version = "1.0.3" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 377 | dependencies = [ 378 | "idna_adapter", 379 | "smallvec", 380 | "utf8_iter", 381 | ] 382 | 383 | [[package]] 384 | name = "idna_adapter" 385 | version = "1.2.1" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" 388 | dependencies = [ 389 | "icu_normalizer", 390 | "icu_properties", 391 | ] 392 | 393 | [[package]] 394 | name = "ipnet" 395 | version = "2.11.0" 396 | source = "registry+https://github.com/rust-lang/crates.io-index" 397 | checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 398 | 399 | [[package]] 400 | name = "iri-string" 401 | version = "0.7.8" 402 | source = "registry+https://github.com/rust-lang/crates.io-index" 403 | checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" 404 | dependencies = [ 405 | "memchr", 406 | "serde", 407 | ] 408 | 409 | [[package]] 410 | name = "itoa" 411 | version = "1.0.15" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 414 | 415 | [[package]] 416 | name = "js-sys" 417 | version = "0.3.77" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 420 | dependencies = [ 421 | "once_cell", 422 | "wasm-bindgen", 423 | ] 424 | 425 | [[package]] 426 | name = "libc" 427 | version = "0.2.172" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 430 | 431 | [[package]] 432 | name = "litemap" 433 | version = "0.8.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" 436 | 437 | [[package]] 438 | name = "log" 439 | version = "0.4.27" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 442 | 443 | [[package]] 444 | name = "lru-slab" 445 | version = "0.1.2" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" 448 | 449 | [[package]] 450 | name = "memchr" 451 | version = "2.7.4" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 454 | 455 | [[package]] 456 | name = "mime" 457 | version = "0.3.17" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 460 | 461 | [[package]] 462 | name = "miniz_oxide" 463 | version = "0.8.8" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 466 | dependencies = [ 467 | "adler2", 468 | ] 469 | 470 | [[package]] 471 | name = "mio" 472 | version = "1.0.4" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 475 | dependencies = [ 476 | "libc", 477 | "wasi 0.11.0+wasi-snapshot-preview1", 478 | "windows-sys 0.59.0", 479 | ] 480 | 481 | [[package]] 482 | name = "object" 483 | version = "0.36.7" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 486 | dependencies = [ 487 | "memchr", 488 | ] 489 | 490 | [[package]] 491 | name = "once_cell" 492 | version = "1.21.3" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 495 | 496 | [[package]] 497 | name = "percent-encoding" 498 | version = "2.3.1" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 501 | 502 | [[package]] 503 | name = "pin-project-lite" 504 | version = "0.2.16" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 507 | 508 | [[package]] 509 | name = "pin-utils" 510 | version = "0.1.0" 511 | source = "registry+https://github.com/rust-lang/crates.io-index" 512 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 513 | 514 | [[package]] 515 | name = "potential_utf" 516 | version = "0.1.2" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" 519 | dependencies = [ 520 | "zerovec", 521 | ] 522 | 523 | [[package]] 524 | name = "ppv-lite86" 525 | version = "0.2.21" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 528 | dependencies = [ 529 | "zerocopy", 530 | ] 531 | 532 | [[package]] 533 | name = "proc-macro2" 534 | version = "1.0.95" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 537 | dependencies = [ 538 | "unicode-ident", 539 | ] 540 | 541 | [[package]] 542 | name = "quinn" 543 | version = "0.11.8" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" 546 | dependencies = [ 547 | "bytes", 548 | "cfg_aliases", 549 | "pin-project-lite", 550 | "quinn-proto", 551 | "quinn-udp", 552 | "rustc-hash", 553 | "rustls", 554 | "socket2", 555 | "thiserror", 556 | "tokio", 557 | "tracing", 558 | "web-time", 559 | ] 560 | 561 | [[package]] 562 | name = "quinn-proto" 563 | version = "0.11.12" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" 566 | dependencies = [ 567 | "bytes", 568 | "getrandom 0.3.3", 569 | "lru-slab", 570 | "rand", 571 | "ring", 572 | "rustc-hash", 573 | "rustls", 574 | "rustls-pki-types", 575 | "slab", 576 | "thiserror", 577 | "tinyvec", 578 | "tracing", 579 | "web-time", 580 | ] 581 | 582 | [[package]] 583 | name = "quinn-udp" 584 | version = "0.5.12" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842" 587 | dependencies = [ 588 | "cfg_aliases", 589 | "libc", 590 | "once_cell", 591 | "socket2", 592 | "tracing", 593 | "windows-sys 0.59.0", 594 | ] 595 | 596 | [[package]] 597 | name = "quote" 598 | version = "1.0.40" 599 | source = "registry+https://github.com/rust-lang/crates.io-index" 600 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 601 | dependencies = [ 602 | "proc-macro2", 603 | ] 604 | 605 | [[package]] 606 | name = "r-efi" 607 | version = "5.2.0" 608 | source = "registry+https://github.com/rust-lang/crates.io-index" 609 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 610 | 611 | [[package]] 612 | name = "rand" 613 | version = "0.9.1" 614 | source = "registry+https://github.com/rust-lang/crates.io-index" 615 | checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" 616 | dependencies = [ 617 | "rand_chacha", 618 | "rand_core", 619 | ] 620 | 621 | [[package]] 622 | name = "rand_chacha" 623 | version = "0.9.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 626 | dependencies = [ 627 | "ppv-lite86", 628 | "rand_core", 629 | ] 630 | 631 | [[package]] 632 | name = "rand_core" 633 | version = "0.9.3" 634 | source = "registry+https://github.com/rust-lang/crates.io-index" 635 | checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 636 | dependencies = [ 637 | "getrandom 0.3.3", 638 | ] 639 | 640 | [[package]] 641 | name = "reqwest" 642 | version = "0.12.19" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" 645 | dependencies = [ 646 | "base64", 647 | "bytes", 648 | "futures-core", 649 | "http", 650 | "http-body", 651 | "http-body-util", 652 | "hyper", 653 | "hyper-rustls", 654 | "hyper-util", 655 | "ipnet", 656 | "js-sys", 657 | "log", 658 | "mime", 659 | "once_cell", 660 | "percent-encoding", 661 | "pin-project-lite", 662 | "quinn", 663 | "rustls", 664 | "rustls-pki-types", 665 | "serde", 666 | "serde_json", 667 | "serde_urlencoded", 668 | "sync_wrapper", 669 | "tokio", 670 | "tokio-rustls", 671 | "tower", 672 | "tower-http", 673 | "tower-service", 674 | "url", 675 | "wasm-bindgen", 676 | "wasm-bindgen-futures", 677 | "web-sys", 678 | "webpki-roots", 679 | ] 680 | 681 | [[package]] 682 | name = "ring" 683 | version = "0.17.14" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 686 | dependencies = [ 687 | "cc", 688 | "cfg-if", 689 | "getrandom 0.2.16", 690 | "libc", 691 | "untrusted", 692 | "windows-sys 0.52.0", 693 | ] 694 | 695 | [[package]] 696 | name = "rustc-demangle" 697 | version = "0.1.24" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 700 | 701 | [[package]] 702 | name = "rustc-hash" 703 | version = "2.1.1" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" 706 | 707 | [[package]] 708 | name = "rustls" 709 | version = "0.23.27" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" 712 | dependencies = [ 713 | "once_cell", 714 | "ring", 715 | "rustls-pki-types", 716 | "rustls-webpki", 717 | "subtle", 718 | "zeroize", 719 | ] 720 | 721 | [[package]] 722 | name = "rustls-pki-types" 723 | version = "1.12.0" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" 726 | dependencies = [ 727 | "web-time", 728 | "zeroize", 729 | ] 730 | 731 | [[package]] 732 | name = "rustls-webpki" 733 | version = "0.103.3" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" 736 | dependencies = [ 737 | "ring", 738 | "rustls-pki-types", 739 | "untrusted", 740 | ] 741 | 742 | [[package]] 743 | name = "rustversion" 744 | version = "1.0.21" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" 747 | 748 | [[package]] 749 | name = "ryu" 750 | version = "1.0.20" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 753 | 754 | [[package]] 755 | name = "serde" 756 | version = "1.0.219" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 759 | dependencies = [ 760 | "serde_derive", 761 | ] 762 | 763 | [[package]] 764 | name = "serde_derive" 765 | version = "1.0.219" 766 | source = "registry+https://github.com/rust-lang/crates.io-index" 767 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 768 | dependencies = [ 769 | "proc-macro2", 770 | "quote", 771 | "syn", 772 | ] 773 | 774 | [[package]] 775 | name = "serde_json" 776 | version = "1.0.140" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 779 | dependencies = [ 780 | "itoa", 781 | "memchr", 782 | "ryu", 783 | "serde", 784 | ] 785 | 786 | [[package]] 787 | name = "serde_urlencoded" 788 | version = "0.7.1" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 791 | dependencies = [ 792 | "form_urlencoded", 793 | "itoa", 794 | "ryu", 795 | "serde", 796 | ] 797 | 798 | [[package]] 799 | name = "shlex" 800 | version = "1.3.0" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 803 | 804 | [[package]] 805 | name = "slab" 806 | version = "0.4.9" 807 | source = "registry+https://github.com/rust-lang/crates.io-index" 808 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 809 | dependencies = [ 810 | "autocfg", 811 | ] 812 | 813 | [[package]] 814 | name = "smallvec" 815 | version = "1.15.0" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 818 | 819 | [[package]] 820 | name = "socket2" 821 | version = "0.5.10" 822 | source = "registry+https://github.com/rust-lang/crates.io-index" 823 | checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 824 | dependencies = [ 825 | "libc", 826 | "windows-sys 0.52.0", 827 | ] 828 | 829 | [[package]] 830 | name = "stable_deref_trait" 831 | version = "1.2.0" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 834 | 835 | [[package]] 836 | name = "subtle" 837 | version = "2.6.1" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 840 | 841 | [[package]] 842 | name = "syn" 843 | version = "2.0.101" 844 | source = "registry+https://github.com/rust-lang/crates.io-index" 845 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 846 | dependencies = [ 847 | "proc-macro2", 848 | "quote", 849 | "unicode-ident", 850 | ] 851 | 852 | [[package]] 853 | name = "sync_wrapper" 854 | version = "1.0.2" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 857 | dependencies = [ 858 | "futures-core", 859 | ] 860 | 861 | [[package]] 862 | name = "synstructure" 863 | version = "0.13.2" 864 | source = "registry+https://github.com/rust-lang/crates.io-index" 865 | checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" 866 | dependencies = [ 867 | "proc-macro2", 868 | "quote", 869 | "syn", 870 | ] 871 | 872 | [[package]] 873 | name = "thiserror" 874 | version = "2.0.12" 875 | source = "registry+https://github.com/rust-lang/crates.io-index" 876 | checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" 877 | dependencies = [ 878 | "thiserror-impl", 879 | ] 880 | 881 | [[package]] 882 | name = "thiserror-impl" 883 | version = "2.0.12" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" 886 | dependencies = [ 887 | "proc-macro2", 888 | "quote", 889 | "syn", 890 | ] 891 | 892 | [[package]] 893 | name = "tinystr" 894 | version = "0.8.1" 895 | source = "registry+https://github.com/rust-lang/crates.io-index" 896 | checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" 897 | dependencies = [ 898 | "displaydoc", 899 | "zerovec", 900 | ] 901 | 902 | [[package]] 903 | name = "tinyvec" 904 | version = "1.9.0" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" 907 | dependencies = [ 908 | "tinyvec_macros", 909 | ] 910 | 911 | [[package]] 912 | name = "tinyvec_macros" 913 | version = "0.1.1" 914 | source = "registry+https://github.com/rust-lang/crates.io-index" 915 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 916 | 917 | [[package]] 918 | name = "tokio" 919 | version = "1.45.1" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" 922 | dependencies = [ 923 | "backtrace", 924 | "bytes", 925 | "libc", 926 | "mio", 927 | "pin-project-lite", 928 | "socket2", 929 | "tokio-macros", 930 | "windows-sys 0.52.0", 931 | ] 932 | 933 | [[package]] 934 | name = "tokio-macros" 935 | version = "2.5.0" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 938 | dependencies = [ 939 | "proc-macro2", 940 | "quote", 941 | "syn", 942 | ] 943 | 944 | [[package]] 945 | name = "tokio-rustls" 946 | version = "0.26.2" 947 | source = "registry+https://github.com/rust-lang/crates.io-index" 948 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 949 | dependencies = [ 950 | "rustls", 951 | "tokio", 952 | ] 953 | 954 | [[package]] 955 | name = "tower" 956 | version = "0.5.2" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 959 | dependencies = [ 960 | "futures-core", 961 | "futures-util", 962 | "pin-project-lite", 963 | "sync_wrapper", 964 | "tokio", 965 | "tower-layer", 966 | "tower-service", 967 | ] 968 | 969 | [[package]] 970 | name = "tower-http" 971 | version = "0.6.5" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "5cc2d9e086a412a451384326f521c8123a99a466b329941a9403696bff9b0da2" 974 | dependencies = [ 975 | "bitflags", 976 | "bytes", 977 | "futures-util", 978 | "http", 979 | "http-body", 980 | "iri-string", 981 | "pin-project-lite", 982 | "tower", 983 | "tower-layer", 984 | "tower-service", 985 | ] 986 | 987 | [[package]] 988 | name = "tower-layer" 989 | version = "0.3.3" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 992 | 993 | [[package]] 994 | name = "tower-service" 995 | version = "0.3.3" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 998 | 999 | [[package]] 1000 | name = "tracing" 1001 | version = "0.1.41" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1004 | dependencies = [ 1005 | "pin-project-lite", 1006 | "tracing-core", 1007 | ] 1008 | 1009 | [[package]] 1010 | name = "tracing-core" 1011 | version = "0.1.33" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1014 | dependencies = [ 1015 | "once_cell", 1016 | ] 1017 | 1018 | [[package]] 1019 | name = "try-lock" 1020 | version = "0.2.5" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1023 | 1024 | [[package]] 1025 | name = "unicode-ident" 1026 | version = "1.0.18" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1029 | 1030 | [[package]] 1031 | name = "untrusted" 1032 | version = "0.9.0" 1033 | source = "registry+https://github.com/rust-lang/crates.io-index" 1034 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1035 | 1036 | [[package]] 1037 | name = "url" 1038 | version = "2.5.4" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1041 | dependencies = [ 1042 | "form_urlencoded", 1043 | "idna", 1044 | "percent-encoding", 1045 | ] 1046 | 1047 | [[package]] 1048 | name = "utf8_iter" 1049 | version = "1.0.4" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1052 | 1053 | [[package]] 1054 | name = "want" 1055 | version = "0.3.1" 1056 | source = "registry+https://github.com/rust-lang/crates.io-index" 1057 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1058 | dependencies = [ 1059 | "try-lock", 1060 | ] 1061 | 1062 | [[package]] 1063 | name = "wasi" 1064 | version = "0.11.0+wasi-snapshot-preview1" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1067 | 1068 | [[package]] 1069 | name = "wasi" 1070 | version = "0.14.2+wasi-0.2.4" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1073 | dependencies = [ 1074 | "wit-bindgen-rt", 1075 | ] 1076 | 1077 | [[package]] 1078 | name = "wasm-bindgen" 1079 | version = "0.2.100" 1080 | source = "registry+https://github.com/rust-lang/crates.io-index" 1081 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 1082 | dependencies = [ 1083 | "cfg-if", 1084 | "once_cell", 1085 | "rustversion", 1086 | "wasm-bindgen-macro", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "wasm-bindgen-backend" 1091 | version = "0.2.100" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 1094 | dependencies = [ 1095 | "bumpalo", 1096 | "log", 1097 | "proc-macro2", 1098 | "quote", 1099 | "syn", 1100 | "wasm-bindgen-shared", 1101 | ] 1102 | 1103 | [[package]] 1104 | name = "wasm-bindgen-futures" 1105 | version = "0.4.50" 1106 | source = "registry+https://github.com/rust-lang/crates.io-index" 1107 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 1108 | dependencies = [ 1109 | "cfg-if", 1110 | "js-sys", 1111 | "once_cell", 1112 | "wasm-bindgen", 1113 | "web-sys", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "wasm-bindgen-macro" 1118 | version = "0.2.100" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 1121 | dependencies = [ 1122 | "quote", 1123 | "wasm-bindgen-macro-support", 1124 | ] 1125 | 1126 | [[package]] 1127 | name = "wasm-bindgen-macro-support" 1128 | version = "0.2.100" 1129 | source = "registry+https://github.com/rust-lang/crates.io-index" 1130 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 1131 | dependencies = [ 1132 | "proc-macro2", 1133 | "quote", 1134 | "syn", 1135 | "wasm-bindgen-backend", 1136 | "wasm-bindgen-shared", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "wasm-bindgen-shared" 1141 | version = "0.2.100" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 1144 | dependencies = [ 1145 | "unicode-ident", 1146 | ] 1147 | 1148 | [[package]] 1149 | name = "web-sys" 1150 | version = "0.3.77" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 1153 | dependencies = [ 1154 | "js-sys", 1155 | "wasm-bindgen", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "web-time" 1160 | version = "1.1.0" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 1163 | dependencies = [ 1164 | "js-sys", 1165 | "wasm-bindgen", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "webpki-roots" 1170 | version = "1.0.0" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "2853738d1cc4f2da3a225c18ec6c3721abb31961096e9dbf5ab35fa88b19cfdb" 1173 | dependencies = [ 1174 | "rustls-pki-types", 1175 | ] 1176 | 1177 | [[package]] 1178 | name = "windows-sys" 1179 | version = "0.52.0" 1180 | source = "registry+https://github.com/rust-lang/crates.io-index" 1181 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1182 | dependencies = [ 1183 | "windows-targets", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "windows-sys" 1188 | version = "0.59.0" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1191 | dependencies = [ 1192 | "windows-targets", 1193 | ] 1194 | 1195 | [[package]] 1196 | name = "windows-targets" 1197 | version = "0.52.6" 1198 | source = "registry+https://github.com/rust-lang/crates.io-index" 1199 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1200 | dependencies = [ 1201 | "windows_aarch64_gnullvm", 1202 | "windows_aarch64_msvc", 1203 | "windows_i686_gnu", 1204 | "windows_i686_gnullvm", 1205 | "windows_i686_msvc", 1206 | "windows_x86_64_gnu", 1207 | "windows_x86_64_gnullvm", 1208 | "windows_x86_64_msvc", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "windows_aarch64_gnullvm" 1213 | version = "0.52.6" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1216 | 1217 | [[package]] 1218 | name = "windows_aarch64_msvc" 1219 | version = "0.52.6" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1222 | 1223 | [[package]] 1224 | name = "windows_i686_gnu" 1225 | version = "0.52.6" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1228 | 1229 | [[package]] 1230 | name = "windows_i686_gnullvm" 1231 | version = "0.52.6" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1234 | 1235 | [[package]] 1236 | name = "windows_i686_msvc" 1237 | version = "0.52.6" 1238 | source = "registry+https://github.com/rust-lang/crates.io-index" 1239 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1240 | 1241 | [[package]] 1242 | name = "windows_x86_64_gnu" 1243 | version = "0.52.6" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1246 | 1247 | [[package]] 1248 | name = "windows_x86_64_gnullvm" 1249 | version = "0.52.6" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1252 | 1253 | [[package]] 1254 | name = "windows_x86_64_msvc" 1255 | version = "0.52.6" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1258 | 1259 | [[package]] 1260 | name = "wit-bindgen-rt" 1261 | version = "0.39.0" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1264 | dependencies = [ 1265 | "bitflags", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "writeable" 1270 | version = "0.6.1" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" 1273 | 1274 | [[package]] 1275 | name = "yoke" 1276 | version = "0.8.0" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" 1279 | dependencies = [ 1280 | "serde", 1281 | "stable_deref_trait", 1282 | "yoke-derive", 1283 | "zerofrom", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "yoke-derive" 1288 | version = "0.8.0" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" 1291 | dependencies = [ 1292 | "proc-macro2", 1293 | "quote", 1294 | "syn", 1295 | "synstructure", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "zerocopy" 1300 | version = "0.8.25" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" 1303 | dependencies = [ 1304 | "zerocopy-derive", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "zerocopy-derive" 1309 | version = "0.8.25" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" 1312 | dependencies = [ 1313 | "proc-macro2", 1314 | "quote", 1315 | "syn", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "zerofrom" 1320 | version = "0.1.6" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 1323 | dependencies = [ 1324 | "zerofrom-derive", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "zerofrom-derive" 1329 | version = "0.1.6" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 1332 | dependencies = [ 1333 | "proc-macro2", 1334 | "quote", 1335 | "syn", 1336 | "synstructure", 1337 | ] 1338 | 1339 | [[package]] 1340 | name = "zeroize" 1341 | version = "1.8.1" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1344 | 1345 | [[package]] 1346 | name = "zerotrie" 1347 | version = "0.2.2" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" 1350 | dependencies = [ 1351 | "displaydoc", 1352 | "yoke", 1353 | "zerofrom", 1354 | ] 1355 | 1356 | [[package]] 1357 | name = "zerovec" 1358 | version = "0.11.2" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" 1361 | dependencies = [ 1362 | "yoke", 1363 | "zerofrom", 1364 | "zerovec-derive", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "zerovec-derive" 1369 | version = "0.11.1" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" 1372 | dependencies = [ 1373 | "proc-macro2", 1374 | "quote", 1375 | "syn", 1376 | ] 1377 | -------------------------------------------------------------------------------- /tests/hello-rustls/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello-rustls" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | reqwest = { version = "0.12.9", default-features = false, features = ["rustls-tls"] } 10 | tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } 11 | -------------------------------------------------------------------------------- /tests/hello-rustls/src/main.rs: -------------------------------------------------------------------------------- 1 | #[tokio::main] 2 | async fn main() { 3 | let response = reqwest::Client::new() 4 | .get("http://www.baidu.com") 5 | .send() 6 | .await 7 | .expect("send"); 8 | println!("Response status {}", response.status()); 9 | } 10 | -------------------------------------------------------------------------------- /tests/hello-tls/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "atomic-waker" 22 | version = "1.1.2" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 25 | 26 | [[package]] 27 | name = "autocfg" 28 | version = "1.4.0" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 31 | 32 | [[package]] 33 | name = "backtrace" 34 | version = "0.3.74" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 37 | dependencies = [ 38 | "addr2line", 39 | "cfg-if", 40 | "libc", 41 | "miniz_oxide", 42 | "object", 43 | "rustc-demangle", 44 | "windows-targets", 45 | ] 46 | 47 | [[package]] 48 | name = "base64" 49 | version = "0.22.1" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 52 | 53 | [[package]] 54 | name = "bitflags" 55 | version = "2.6.0" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 58 | 59 | [[package]] 60 | name = "bumpalo" 61 | version = "3.16.0" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 64 | 65 | [[package]] 66 | name = "bytes" 67 | version = "1.9.0" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 70 | 71 | [[package]] 72 | name = "cc" 73 | version = "1.2.2" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" 76 | dependencies = [ 77 | "shlex", 78 | ] 79 | 80 | [[package]] 81 | name = "cfg-if" 82 | version = "1.0.0" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 85 | 86 | [[package]] 87 | name = "core-foundation" 88 | version = "0.9.4" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 91 | dependencies = [ 92 | "core-foundation-sys", 93 | "libc", 94 | ] 95 | 96 | [[package]] 97 | name = "core-foundation-sys" 98 | version = "0.8.7" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 101 | 102 | [[package]] 103 | name = "displaydoc" 104 | version = "0.2.5" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 107 | dependencies = [ 108 | "proc-macro2", 109 | "quote", 110 | "syn", 111 | ] 112 | 113 | [[package]] 114 | name = "encoding_rs" 115 | version = "0.8.35" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 118 | dependencies = [ 119 | "cfg-if", 120 | ] 121 | 122 | [[package]] 123 | name = "equivalent" 124 | version = "1.0.1" 125 | source = "registry+https://github.com/rust-lang/crates.io-index" 126 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 127 | 128 | [[package]] 129 | name = "errno" 130 | version = "0.3.10" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 133 | dependencies = [ 134 | "libc", 135 | "windows-sys 0.59.0", 136 | ] 137 | 138 | [[package]] 139 | name = "fastrand" 140 | version = "2.2.0" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" 143 | 144 | [[package]] 145 | name = "fnv" 146 | version = "1.0.7" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 149 | 150 | [[package]] 151 | name = "foreign-types" 152 | version = "0.3.2" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 155 | dependencies = [ 156 | "foreign-types-shared", 157 | ] 158 | 159 | [[package]] 160 | name = "foreign-types-shared" 161 | version = "0.1.1" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 164 | 165 | [[package]] 166 | name = "form_urlencoded" 167 | version = "1.2.1" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 170 | dependencies = [ 171 | "percent-encoding", 172 | ] 173 | 174 | [[package]] 175 | name = "futures-channel" 176 | version = "0.3.31" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 179 | dependencies = [ 180 | "futures-core", 181 | ] 182 | 183 | [[package]] 184 | name = "futures-core" 185 | version = "0.3.31" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 188 | 189 | [[package]] 190 | name = "futures-sink" 191 | version = "0.3.31" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 194 | 195 | [[package]] 196 | name = "futures-task" 197 | version = "0.3.31" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 200 | 201 | [[package]] 202 | name = "futures-util" 203 | version = "0.3.31" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 206 | dependencies = [ 207 | "futures-core", 208 | "futures-task", 209 | "pin-project-lite", 210 | "pin-utils", 211 | ] 212 | 213 | [[package]] 214 | name = "getrandom" 215 | version = "0.2.15" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 218 | dependencies = [ 219 | "cfg-if", 220 | "libc", 221 | "wasi", 222 | ] 223 | 224 | [[package]] 225 | name = "gimli" 226 | version = "0.31.1" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 229 | 230 | [[package]] 231 | name = "h2" 232 | version = "0.4.7" 233 | source = "registry+https://github.com/rust-lang/crates.io-index" 234 | checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" 235 | dependencies = [ 236 | "atomic-waker", 237 | "bytes", 238 | "fnv", 239 | "futures-core", 240 | "futures-sink", 241 | "http", 242 | "indexmap", 243 | "slab", 244 | "tokio", 245 | "tokio-util", 246 | "tracing", 247 | ] 248 | 249 | [[package]] 250 | name = "hashbrown" 251 | version = "0.15.2" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 254 | 255 | [[package]] 256 | name = "hello-tls" 257 | version = "0.1.0" 258 | dependencies = [ 259 | "reqwest", 260 | "tokio", 261 | ] 262 | 263 | [[package]] 264 | name = "http" 265 | version = "1.1.0" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 268 | dependencies = [ 269 | "bytes", 270 | "fnv", 271 | "itoa", 272 | ] 273 | 274 | [[package]] 275 | name = "http-body" 276 | version = "1.0.1" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 279 | dependencies = [ 280 | "bytes", 281 | "http", 282 | ] 283 | 284 | [[package]] 285 | name = "http-body-util" 286 | version = "0.1.2" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 289 | dependencies = [ 290 | "bytes", 291 | "futures-util", 292 | "http", 293 | "http-body", 294 | "pin-project-lite", 295 | ] 296 | 297 | [[package]] 298 | name = "httparse" 299 | version = "1.9.5" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" 302 | 303 | [[package]] 304 | name = "hyper" 305 | version = "1.5.1" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" 308 | dependencies = [ 309 | "bytes", 310 | "futures-channel", 311 | "futures-util", 312 | "h2", 313 | "http", 314 | "http-body", 315 | "httparse", 316 | "itoa", 317 | "pin-project-lite", 318 | "smallvec", 319 | "tokio", 320 | "want", 321 | ] 322 | 323 | [[package]] 324 | name = "hyper-rustls" 325 | version = "0.27.3" 326 | source = "registry+https://github.com/rust-lang/crates.io-index" 327 | checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" 328 | dependencies = [ 329 | "futures-util", 330 | "http", 331 | "hyper", 332 | "hyper-util", 333 | "rustls", 334 | "rustls-pki-types", 335 | "tokio", 336 | "tokio-rustls", 337 | "tower-service", 338 | ] 339 | 340 | [[package]] 341 | name = "hyper-tls" 342 | version = "0.6.0" 343 | source = "registry+https://github.com/rust-lang/crates.io-index" 344 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 345 | dependencies = [ 346 | "bytes", 347 | "http-body-util", 348 | "hyper", 349 | "hyper-util", 350 | "native-tls", 351 | "tokio", 352 | "tokio-native-tls", 353 | "tower-service", 354 | ] 355 | 356 | [[package]] 357 | name = "hyper-util" 358 | version = "0.1.10" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 361 | dependencies = [ 362 | "bytes", 363 | "futures-channel", 364 | "futures-util", 365 | "http", 366 | "http-body", 367 | "hyper", 368 | "pin-project-lite", 369 | "socket2", 370 | "tokio", 371 | "tower-service", 372 | "tracing", 373 | ] 374 | 375 | [[package]] 376 | name = "icu_collections" 377 | version = "1.5.0" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 380 | dependencies = [ 381 | "displaydoc", 382 | "yoke", 383 | "zerofrom", 384 | "zerovec", 385 | ] 386 | 387 | [[package]] 388 | name = "icu_locid" 389 | version = "1.5.0" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 392 | dependencies = [ 393 | "displaydoc", 394 | "litemap", 395 | "tinystr", 396 | "writeable", 397 | "zerovec", 398 | ] 399 | 400 | [[package]] 401 | name = "icu_locid_transform" 402 | version = "1.5.0" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 405 | dependencies = [ 406 | "displaydoc", 407 | "icu_locid", 408 | "icu_locid_transform_data", 409 | "icu_provider", 410 | "tinystr", 411 | "zerovec", 412 | ] 413 | 414 | [[package]] 415 | name = "icu_locid_transform_data" 416 | version = "1.5.0" 417 | source = "registry+https://github.com/rust-lang/crates.io-index" 418 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 419 | 420 | [[package]] 421 | name = "icu_normalizer" 422 | version = "1.5.0" 423 | source = "registry+https://github.com/rust-lang/crates.io-index" 424 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 425 | dependencies = [ 426 | "displaydoc", 427 | "icu_collections", 428 | "icu_normalizer_data", 429 | "icu_properties", 430 | "icu_provider", 431 | "smallvec", 432 | "utf16_iter", 433 | "utf8_iter", 434 | "write16", 435 | "zerovec", 436 | ] 437 | 438 | [[package]] 439 | name = "icu_normalizer_data" 440 | version = "1.5.0" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 443 | 444 | [[package]] 445 | name = "icu_properties" 446 | version = "1.5.1" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 449 | dependencies = [ 450 | "displaydoc", 451 | "icu_collections", 452 | "icu_locid_transform", 453 | "icu_properties_data", 454 | "icu_provider", 455 | "tinystr", 456 | "zerovec", 457 | ] 458 | 459 | [[package]] 460 | name = "icu_properties_data" 461 | version = "1.5.0" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 464 | 465 | [[package]] 466 | name = "icu_provider" 467 | version = "1.5.0" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 470 | dependencies = [ 471 | "displaydoc", 472 | "icu_locid", 473 | "icu_provider_macros", 474 | "stable_deref_trait", 475 | "tinystr", 476 | "writeable", 477 | "yoke", 478 | "zerofrom", 479 | "zerovec", 480 | ] 481 | 482 | [[package]] 483 | name = "icu_provider_macros" 484 | version = "1.5.0" 485 | source = "registry+https://github.com/rust-lang/crates.io-index" 486 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 487 | dependencies = [ 488 | "proc-macro2", 489 | "quote", 490 | "syn", 491 | ] 492 | 493 | [[package]] 494 | name = "idna" 495 | version = "1.0.3" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 498 | dependencies = [ 499 | "idna_adapter", 500 | "smallvec", 501 | "utf8_iter", 502 | ] 503 | 504 | [[package]] 505 | name = "idna_adapter" 506 | version = "1.2.0" 507 | source = "registry+https://github.com/rust-lang/crates.io-index" 508 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 509 | dependencies = [ 510 | "icu_normalizer", 511 | "icu_properties", 512 | ] 513 | 514 | [[package]] 515 | name = "indexmap" 516 | version = "2.7.0" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 519 | dependencies = [ 520 | "equivalent", 521 | "hashbrown", 522 | ] 523 | 524 | [[package]] 525 | name = "ipnet" 526 | version = "2.10.1" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" 529 | 530 | [[package]] 531 | name = "itoa" 532 | version = "1.0.14" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 535 | 536 | [[package]] 537 | name = "js-sys" 538 | version = "0.3.74" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "a865e038f7f6ed956f788f0d7d60c541fff74c7bd74272c5d4cf15c63743e705" 541 | dependencies = [ 542 | "once_cell", 543 | "wasm-bindgen", 544 | ] 545 | 546 | [[package]] 547 | name = "libc" 548 | version = "0.2.167" 549 | source = "registry+https://github.com/rust-lang/crates.io-index" 550 | checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" 551 | 552 | [[package]] 553 | name = "linux-raw-sys" 554 | version = "0.4.14" 555 | source = "registry+https://github.com/rust-lang/crates.io-index" 556 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 557 | 558 | [[package]] 559 | name = "litemap" 560 | version = "0.7.4" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" 563 | 564 | [[package]] 565 | name = "log" 566 | version = "0.4.22" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 569 | 570 | [[package]] 571 | name = "memchr" 572 | version = "2.7.4" 573 | source = "registry+https://github.com/rust-lang/crates.io-index" 574 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 575 | 576 | [[package]] 577 | name = "mime" 578 | version = "0.3.17" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 581 | 582 | [[package]] 583 | name = "miniz_oxide" 584 | version = "0.8.0" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 587 | dependencies = [ 588 | "adler2", 589 | ] 590 | 591 | [[package]] 592 | name = "mio" 593 | version = "1.0.3" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 596 | dependencies = [ 597 | "libc", 598 | "wasi", 599 | "windows-sys 0.52.0", 600 | ] 601 | 602 | [[package]] 603 | name = "native-tls" 604 | version = "0.2.12" 605 | source = "registry+https://github.com/rust-lang/crates.io-index" 606 | checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" 607 | dependencies = [ 608 | "libc", 609 | "log", 610 | "openssl", 611 | "openssl-probe", 612 | "openssl-sys", 613 | "schannel", 614 | "security-framework", 615 | "security-framework-sys", 616 | "tempfile", 617 | ] 618 | 619 | [[package]] 620 | name = "object" 621 | version = "0.36.5" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" 624 | dependencies = [ 625 | "memchr", 626 | ] 627 | 628 | [[package]] 629 | name = "once_cell" 630 | version = "1.20.2" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 633 | 634 | [[package]] 635 | name = "openssl" 636 | version = "0.10.68" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" 639 | dependencies = [ 640 | "bitflags", 641 | "cfg-if", 642 | "foreign-types", 643 | "libc", 644 | "once_cell", 645 | "openssl-macros", 646 | "openssl-sys", 647 | ] 648 | 649 | [[package]] 650 | name = "openssl-macros" 651 | version = "0.1.1" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 654 | dependencies = [ 655 | "proc-macro2", 656 | "quote", 657 | "syn", 658 | ] 659 | 660 | [[package]] 661 | name = "openssl-probe" 662 | version = "0.1.5" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 665 | 666 | [[package]] 667 | name = "openssl-src" 668 | version = "300.4.1+3.4.0" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" 671 | dependencies = [ 672 | "cc", 673 | ] 674 | 675 | [[package]] 676 | name = "openssl-sys" 677 | version = "0.9.104" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" 680 | dependencies = [ 681 | "cc", 682 | "libc", 683 | "openssl-src", 684 | "pkg-config", 685 | "vcpkg", 686 | ] 687 | 688 | [[package]] 689 | name = "percent-encoding" 690 | version = "2.3.1" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 693 | 694 | [[package]] 695 | name = "pin-project-lite" 696 | version = "0.2.15" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" 699 | 700 | [[package]] 701 | name = "pin-utils" 702 | version = "0.1.0" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 705 | 706 | [[package]] 707 | name = "pkg-config" 708 | version = "0.3.31" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" 711 | 712 | [[package]] 713 | name = "proc-macro2" 714 | version = "1.0.92" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 717 | dependencies = [ 718 | "unicode-ident", 719 | ] 720 | 721 | [[package]] 722 | name = "quote" 723 | version = "1.0.37" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 726 | dependencies = [ 727 | "proc-macro2", 728 | ] 729 | 730 | [[package]] 731 | name = "reqwest" 732 | version = "0.12.9" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" 735 | dependencies = [ 736 | "base64", 737 | "bytes", 738 | "encoding_rs", 739 | "futures-core", 740 | "futures-util", 741 | "h2", 742 | "http", 743 | "http-body", 744 | "http-body-util", 745 | "hyper", 746 | "hyper-rustls", 747 | "hyper-tls", 748 | "hyper-util", 749 | "ipnet", 750 | "js-sys", 751 | "log", 752 | "mime", 753 | "native-tls", 754 | "once_cell", 755 | "percent-encoding", 756 | "pin-project-lite", 757 | "rustls-pemfile", 758 | "serde", 759 | "serde_json", 760 | "serde_urlencoded", 761 | "sync_wrapper", 762 | "system-configuration", 763 | "tokio", 764 | "tokio-native-tls", 765 | "tower-service", 766 | "url", 767 | "wasm-bindgen", 768 | "wasm-bindgen-futures", 769 | "web-sys", 770 | "windows-registry", 771 | ] 772 | 773 | [[package]] 774 | name = "ring" 775 | version = "0.17.8" 776 | source = "registry+https://github.com/rust-lang/crates.io-index" 777 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 778 | dependencies = [ 779 | "cc", 780 | "cfg-if", 781 | "getrandom", 782 | "libc", 783 | "spin", 784 | "untrusted", 785 | "windows-sys 0.52.0", 786 | ] 787 | 788 | [[package]] 789 | name = "rustc-demangle" 790 | version = "0.1.24" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 793 | 794 | [[package]] 795 | name = "rustix" 796 | version = "0.38.41" 797 | source = "registry+https://github.com/rust-lang/crates.io-index" 798 | checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" 799 | dependencies = [ 800 | "bitflags", 801 | "errno", 802 | "libc", 803 | "linux-raw-sys", 804 | "windows-sys 0.52.0", 805 | ] 806 | 807 | [[package]] 808 | name = "rustls" 809 | version = "0.23.19" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" 812 | dependencies = [ 813 | "once_cell", 814 | "rustls-pki-types", 815 | "rustls-webpki", 816 | "subtle", 817 | "zeroize", 818 | ] 819 | 820 | [[package]] 821 | name = "rustls-pemfile" 822 | version = "2.2.0" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 825 | dependencies = [ 826 | "rustls-pki-types", 827 | ] 828 | 829 | [[package]] 830 | name = "rustls-pki-types" 831 | version = "1.10.0" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" 834 | 835 | [[package]] 836 | name = "rustls-webpki" 837 | version = "0.102.8" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 840 | dependencies = [ 841 | "ring", 842 | "rustls-pki-types", 843 | "untrusted", 844 | ] 845 | 846 | [[package]] 847 | name = "ryu" 848 | version = "1.0.18" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 851 | 852 | [[package]] 853 | name = "schannel" 854 | version = "0.1.27" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 857 | dependencies = [ 858 | "windows-sys 0.59.0", 859 | ] 860 | 861 | [[package]] 862 | name = "security-framework" 863 | version = "2.11.1" 864 | source = "registry+https://github.com/rust-lang/crates.io-index" 865 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 866 | dependencies = [ 867 | "bitflags", 868 | "core-foundation", 869 | "core-foundation-sys", 870 | "libc", 871 | "security-framework-sys", 872 | ] 873 | 874 | [[package]] 875 | name = "security-framework-sys" 876 | version = "2.12.1" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" 879 | dependencies = [ 880 | "core-foundation-sys", 881 | "libc", 882 | ] 883 | 884 | [[package]] 885 | name = "serde" 886 | version = "1.0.215" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" 889 | dependencies = [ 890 | "serde_derive", 891 | ] 892 | 893 | [[package]] 894 | name = "serde_derive" 895 | version = "1.0.215" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" 898 | dependencies = [ 899 | "proc-macro2", 900 | "quote", 901 | "syn", 902 | ] 903 | 904 | [[package]] 905 | name = "serde_json" 906 | version = "1.0.133" 907 | source = "registry+https://github.com/rust-lang/crates.io-index" 908 | checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" 909 | dependencies = [ 910 | "itoa", 911 | "memchr", 912 | "ryu", 913 | "serde", 914 | ] 915 | 916 | [[package]] 917 | name = "serde_urlencoded" 918 | version = "0.7.1" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 921 | dependencies = [ 922 | "form_urlencoded", 923 | "itoa", 924 | "ryu", 925 | "serde", 926 | ] 927 | 928 | [[package]] 929 | name = "shlex" 930 | version = "1.3.0" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 933 | 934 | [[package]] 935 | name = "slab" 936 | version = "0.4.9" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 939 | dependencies = [ 940 | "autocfg", 941 | ] 942 | 943 | [[package]] 944 | name = "smallvec" 945 | version = "1.13.2" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 948 | 949 | [[package]] 950 | name = "socket2" 951 | version = "0.5.8" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 954 | dependencies = [ 955 | "libc", 956 | "windows-sys 0.52.0", 957 | ] 958 | 959 | [[package]] 960 | name = "spin" 961 | version = "0.9.8" 962 | source = "registry+https://github.com/rust-lang/crates.io-index" 963 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 964 | 965 | [[package]] 966 | name = "stable_deref_trait" 967 | version = "1.2.0" 968 | source = "registry+https://github.com/rust-lang/crates.io-index" 969 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 970 | 971 | [[package]] 972 | name = "subtle" 973 | version = "2.6.1" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 976 | 977 | [[package]] 978 | name = "syn" 979 | version = "2.0.90" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 982 | dependencies = [ 983 | "proc-macro2", 984 | "quote", 985 | "unicode-ident", 986 | ] 987 | 988 | [[package]] 989 | name = "sync_wrapper" 990 | version = "1.0.2" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 993 | dependencies = [ 994 | "futures-core", 995 | ] 996 | 997 | [[package]] 998 | name = "synstructure" 999 | version = "0.13.1" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 1002 | dependencies = [ 1003 | "proc-macro2", 1004 | "quote", 1005 | "syn", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "system-configuration" 1010 | version = "0.6.1" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 1013 | dependencies = [ 1014 | "bitflags", 1015 | "core-foundation", 1016 | "system-configuration-sys", 1017 | ] 1018 | 1019 | [[package]] 1020 | name = "system-configuration-sys" 1021 | version = "0.6.0" 1022 | source = "registry+https://github.com/rust-lang/crates.io-index" 1023 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 1024 | dependencies = [ 1025 | "core-foundation-sys", 1026 | "libc", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "tempfile" 1031 | version = "3.14.0" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" 1034 | dependencies = [ 1035 | "cfg-if", 1036 | "fastrand", 1037 | "once_cell", 1038 | "rustix", 1039 | "windows-sys 0.59.0", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "tinystr" 1044 | version = "0.7.6" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 1047 | dependencies = [ 1048 | "displaydoc", 1049 | "zerovec", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "tokio" 1054 | version = "1.41.1" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" 1057 | dependencies = [ 1058 | "backtrace", 1059 | "bytes", 1060 | "libc", 1061 | "mio", 1062 | "pin-project-lite", 1063 | "socket2", 1064 | "tokio-macros", 1065 | "windows-sys 0.52.0", 1066 | ] 1067 | 1068 | [[package]] 1069 | name = "tokio-macros" 1070 | version = "2.4.0" 1071 | source = "registry+https://github.com/rust-lang/crates.io-index" 1072 | checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 1073 | dependencies = [ 1074 | "proc-macro2", 1075 | "quote", 1076 | "syn", 1077 | ] 1078 | 1079 | [[package]] 1080 | name = "tokio-native-tls" 1081 | version = "0.3.1" 1082 | source = "registry+https://github.com/rust-lang/crates.io-index" 1083 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1084 | dependencies = [ 1085 | "native-tls", 1086 | "tokio", 1087 | ] 1088 | 1089 | [[package]] 1090 | name = "tokio-rustls" 1091 | version = "0.26.0" 1092 | source = "registry+https://github.com/rust-lang/crates.io-index" 1093 | checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" 1094 | dependencies = [ 1095 | "rustls", 1096 | "rustls-pki-types", 1097 | "tokio", 1098 | ] 1099 | 1100 | [[package]] 1101 | name = "tokio-util" 1102 | version = "0.7.12" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" 1105 | dependencies = [ 1106 | "bytes", 1107 | "futures-core", 1108 | "futures-sink", 1109 | "pin-project-lite", 1110 | "tokio", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "tower-service" 1115 | version = "0.3.3" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1118 | 1119 | [[package]] 1120 | name = "tracing" 1121 | version = "0.1.41" 1122 | source = "registry+https://github.com/rust-lang/crates.io-index" 1123 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1124 | dependencies = [ 1125 | "pin-project-lite", 1126 | "tracing-core", 1127 | ] 1128 | 1129 | [[package]] 1130 | name = "tracing-core" 1131 | version = "0.1.33" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1134 | dependencies = [ 1135 | "once_cell", 1136 | ] 1137 | 1138 | [[package]] 1139 | name = "try-lock" 1140 | version = "0.2.5" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1143 | 1144 | [[package]] 1145 | name = "unicode-ident" 1146 | version = "1.0.14" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 1149 | 1150 | [[package]] 1151 | name = "untrusted" 1152 | version = "0.9.0" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1155 | 1156 | [[package]] 1157 | name = "url" 1158 | version = "2.5.4" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1161 | dependencies = [ 1162 | "form_urlencoded", 1163 | "idna", 1164 | "percent-encoding", 1165 | ] 1166 | 1167 | [[package]] 1168 | name = "utf16_iter" 1169 | version = "1.0.5" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 1172 | 1173 | [[package]] 1174 | name = "utf8_iter" 1175 | version = "1.0.4" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1178 | 1179 | [[package]] 1180 | name = "vcpkg" 1181 | version = "0.2.15" 1182 | source = "registry+https://github.com/rust-lang/crates.io-index" 1183 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1184 | 1185 | [[package]] 1186 | name = "want" 1187 | version = "0.3.1" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1190 | dependencies = [ 1191 | "try-lock", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "wasi" 1196 | version = "0.11.0+wasi-snapshot-preview1" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1199 | 1200 | [[package]] 1201 | name = "wasm-bindgen" 1202 | version = "0.2.97" 1203 | source = "registry+https://github.com/rust-lang/crates.io-index" 1204 | checksum = "d15e63b4482863c109d70a7b8706c1e364eb6ea449b201a76c5b89cedcec2d5c" 1205 | dependencies = [ 1206 | "cfg-if", 1207 | "once_cell", 1208 | "wasm-bindgen-macro", 1209 | ] 1210 | 1211 | [[package]] 1212 | name = "wasm-bindgen-backend" 1213 | version = "0.2.97" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "8d36ef12e3aaca16ddd3f67922bc63e48e953f126de60bd33ccc0101ef9998cd" 1216 | dependencies = [ 1217 | "bumpalo", 1218 | "log", 1219 | "once_cell", 1220 | "proc-macro2", 1221 | "quote", 1222 | "syn", 1223 | "wasm-bindgen-shared", 1224 | ] 1225 | 1226 | [[package]] 1227 | name = "wasm-bindgen-futures" 1228 | version = "0.4.47" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "9dfaf8f50e5f293737ee323940c7d8b08a66a95a419223d9f41610ca08b0833d" 1231 | dependencies = [ 1232 | "cfg-if", 1233 | "js-sys", 1234 | "once_cell", 1235 | "wasm-bindgen", 1236 | "web-sys", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "wasm-bindgen-macro" 1241 | version = "0.2.97" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "705440e08b42d3e4b36de7d66c944be628d579796b8090bfa3471478a2260051" 1244 | dependencies = [ 1245 | "quote", 1246 | "wasm-bindgen-macro-support", 1247 | ] 1248 | 1249 | [[package]] 1250 | name = "wasm-bindgen-macro-support" 1251 | version = "0.2.97" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | checksum = "98c9ae5a76e46f4deecd0f0255cc223cfa18dc9b261213b8aa0c7b36f61b3f1d" 1254 | dependencies = [ 1255 | "proc-macro2", 1256 | "quote", 1257 | "syn", 1258 | "wasm-bindgen-backend", 1259 | "wasm-bindgen-shared", 1260 | ] 1261 | 1262 | [[package]] 1263 | name = "wasm-bindgen-shared" 1264 | version = "0.2.97" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "6ee99da9c5ba11bd675621338ef6fa52296b76b83305e9b6e5c77d4c286d6d49" 1267 | 1268 | [[package]] 1269 | name = "web-sys" 1270 | version = "0.3.74" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "a98bc3c33f0fe7e59ad7cd041b89034fa82a7c2d4365ca538dda6cdaf513863c" 1273 | dependencies = [ 1274 | "js-sys", 1275 | "wasm-bindgen", 1276 | ] 1277 | 1278 | [[package]] 1279 | name = "windows-registry" 1280 | version = "0.2.0" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" 1283 | dependencies = [ 1284 | "windows-result", 1285 | "windows-strings", 1286 | "windows-targets", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "windows-result" 1291 | version = "0.2.0" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 1294 | dependencies = [ 1295 | "windows-targets", 1296 | ] 1297 | 1298 | [[package]] 1299 | name = "windows-strings" 1300 | version = "0.1.0" 1301 | source = "registry+https://github.com/rust-lang/crates.io-index" 1302 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 1303 | dependencies = [ 1304 | "windows-result", 1305 | "windows-targets", 1306 | ] 1307 | 1308 | [[package]] 1309 | name = "windows-sys" 1310 | version = "0.52.0" 1311 | source = "registry+https://github.com/rust-lang/crates.io-index" 1312 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1313 | dependencies = [ 1314 | "windows-targets", 1315 | ] 1316 | 1317 | [[package]] 1318 | name = "windows-sys" 1319 | version = "0.59.0" 1320 | source = "registry+https://github.com/rust-lang/crates.io-index" 1321 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1322 | dependencies = [ 1323 | "windows-targets", 1324 | ] 1325 | 1326 | [[package]] 1327 | name = "windows-targets" 1328 | version = "0.52.6" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1331 | dependencies = [ 1332 | "windows_aarch64_gnullvm", 1333 | "windows_aarch64_msvc", 1334 | "windows_i686_gnu", 1335 | "windows_i686_gnullvm", 1336 | "windows_i686_msvc", 1337 | "windows_x86_64_gnu", 1338 | "windows_x86_64_gnullvm", 1339 | "windows_x86_64_msvc", 1340 | ] 1341 | 1342 | [[package]] 1343 | name = "windows_aarch64_gnullvm" 1344 | version = "0.52.6" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1347 | 1348 | [[package]] 1349 | name = "windows_aarch64_msvc" 1350 | version = "0.52.6" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1353 | 1354 | [[package]] 1355 | name = "windows_i686_gnu" 1356 | version = "0.52.6" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1359 | 1360 | [[package]] 1361 | name = "windows_i686_gnullvm" 1362 | version = "0.52.6" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1365 | 1366 | [[package]] 1367 | name = "windows_i686_msvc" 1368 | version = "0.52.6" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1371 | 1372 | [[package]] 1373 | name = "windows_x86_64_gnu" 1374 | version = "0.52.6" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1377 | 1378 | [[package]] 1379 | name = "windows_x86_64_gnullvm" 1380 | version = "0.52.6" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1383 | 1384 | [[package]] 1385 | name = "windows_x86_64_msvc" 1386 | version = "0.52.6" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1389 | 1390 | [[package]] 1391 | name = "write16" 1392 | version = "1.0.0" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 1395 | 1396 | [[package]] 1397 | name = "writeable" 1398 | version = "0.5.5" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 1401 | 1402 | [[package]] 1403 | name = "yoke" 1404 | version = "0.7.5" 1405 | source = "registry+https://github.com/rust-lang/crates.io-index" 1406 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 1407 | dependencies = [ 1408 | "serde", 1409 | "stable_deref_trait", 1410 | "yoke-derive", 1411 | "zerofrom", 1412 | ] 1413 | 1414 | [[package]] 1415 | name = "yoke-derive" 1416 | version = "0.7.5" 1417 | source = "registry+https://github.com/rust-lang/crates.io-index" 1418 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 1419 | dependencies = [ 1420 | "proc-macro2", 1421 | "quote", 1422 | "syn", 1423 | "synstructure", 1424 | ] 1425 | 1426 | [[package]] 1427 | name = "zerofrom" 1428 | version = "0.1.5" 1429 | source = "registry+https://github.com/rust-lang/crates.io-index" 1430 | checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" 1431 | dependencies = [ 1432 | "zerofrom-derive", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "zerofrom-derive" 1437 | version = "0.1.5" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" 1440 | dependencies = [ 1441 | "proc-macro2", 1442 | "quote", 1443 | "syn", 1444 | "synstructure", 1445 | ] 1446 | 1447 | [[package]] 1448 | name = "zeroize" 1449 | version = "1.8.1" 1450 | source = "registry+https://github.com/rust-lang/crates.io-index" 1451 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1452 | 1453 | [[package]] 1454 | name = "zerovec" 1455 | version = "0.10.4" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 1458 | dependencies = [ 1459 | "yoke", 1460 | "zerofrom", 1461 | "zerovec-derive", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "zerovec-derive" 1466 | version = "0.10.3" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 1469 | dependencies = [ 1470 | "proc-macro2", 1471 | "quote", 1472 | "syn", 1473 | ] 1474 | -------------------------------------------------------------------------------- /tests/hello-tls/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello-tls" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | reqwest = { version = "0.12.9", features = ["native-tls-vendored"] } 10 | tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } 11 | -------------------------------------------------------------------------------- /tests/hello-tls/src/main.rs: -------------------------------------------------------------------------------- 1 | #[tokio::main] 2 | async fn main() { 3 | let response = reqwest::Client::new() 4 | .get("http://www.baidu.com") 5 | .send() 6 | .await 7 | .expect("send"); 8 | println!("Response status {}", response.status()); 9 | } 10 | -------------------------------------------------------------------------------- /tests/hello-windows/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | target = "x86_64-pc-windows-msvc" 3 | -------------------------------------------------------------------------------- /tests/hello-windows/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "hello-windows" 7 | version = "0.1.0" 8 | dependencies = [ 9 | "winapi", 10 | "windows-sys", 11 | ] 12 | 13 | [[package]] 14 | name = "winapi" 15 | version = "0.3.9" 16 | source = "registry+https://github.com/rust-lang/crates.io-index" 17 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 18 | dependencies = [ 19 | "winapi-i686-pc-windows-gnu", 20 | "winapi-x86_64-pc-windows-gnu", 21 | ] 22 | 23 | [[package]] 24 | name = "winapi-i686-pc-windows-gnu" 25 | version = "0.4.0" 26 | source = "registry+https://github.com/rust-lang/crates.io-index" 27 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 28 | 29 | [[package]] 30 | name = "winapi-x86_64-pc-windows-gnu" 31 | version = "0.4.0" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 34 | 35 | [[package]] 36 | name = "windows-sys" 37 | version = "0.59.0" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 40 | dependencies = [ 41 | "windows-targets", 42 | ] 43 | 44 | [[package]] 45 | name = "windows-targets" 46 | version = "0.52.6" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 49 | dependencies = [ 50 | "windows_aarch64_gnullvm", 51 | "windows_aarch64_msvc", 52 | "windows_i686_gnu", 53 | "windows_i686_gnullvm", 54 | "windows_i686_msvc", 55 | "windows_x86_64_gnu", 56 | "windows_x86_64_gnullvm", 57 | "windows_x86_64_msvc", 58 | ] 59 | 60 | [[package]] 61 | name = "windows_aarch64_gnullvm" 62 | version = "0.52.6" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 65 | 66 | [[package]] 67 | name = "windows_aarch64_msvc" 68 | version = "0.52.6" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 71 | 72 | [[package]] 73 | name = "windows_i686_gnu" 74 | version = "0.52.6" 75 | source = "registry+https://github.com/rust-lang/crates.io-index" 76 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 77 | 78 | [[package]] 79 | name = "windows_i686_gnullvm" 80 | version = "0.52.6" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 83 | 84 | [[package]] 85 | name = "windows_i686_msvc" 86 | version = "0.52.6" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 89 | 90 | [[package]] 91 | name = "windows_x86_64_gnu" 92 | version = "0.52.6" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 95 | 96 | [[package]] 97 | name = "windows_x86_64_gnullvm" 98 | version = "0.52.6" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 101 | 102 | [[package]] 103 | name = "windows_x86_64_msvc" 104 | version = "0.52.6" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 107 | -------------------------------------------------------------------------------- /tests/hello-windows/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello-windows" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | winapi = { version = "0.3.9", features = ["sysinfoapi"] } 10 | windows-sys = { version = "0.59.0", features = ["Win32_System_SystemInformation"] } 11 | -------------------------------------------------------------------------------- /tests/hello-windows/src/main.rs: -------------------------------------------------------------------------------- 1 | use winapi::um::sysinfoapi::GetVersion as WinApiGetVersion; 2 | use windows_sys::Win32::System::SystemInformation::GetVersion as WindowsSysGetVersion; 3 | 4 | fn main() { 5 | let v1 = unsafe { WinApiGetVersion() }; 6 | println!("version from winapi: {}", v1); 7 | 8 | let v2 = unsafe { WindowsSysGetVersion() }; 9 | println!("version from windows-sys: {}", v2); 10 | 11 | assert_eq!(v1, v2); 12 | } 13 | 14 | #[cfg(test)] 15 | mod test { 16 | use winapi::um::sysinfoapi::GetVersion as WinApiGetVersion; 17 | use windows_sys::Win32::System::SystemInformation::GetVersion as WindowsSysGetVersion; 18 | 19 | #[test] 20 | fn test_winapi_get_version() { 21 | let v1 = unsafe { WinApiGetVersion() }; 22 | println!("version from winapi: {}", v1); 23 | } 24 | 25 | #[test] 26 | fn test_windows_sys_get_version() { 27 | let v2 = unsafe { WindowsSysGetVersion() }; 28 | println!("version from windows-sys: {}", v2); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /tests/libhello/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "hello" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /tests/libhello/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | edition = "2018" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [lib] 9 | crate-type = ["cdylib"] 10 | 11 | [dependencies] 12 | -------------------------------------------------------------------------------- /tests/libhello/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[no_mangle] 2 | pub extern "C" fn hello() { 3 | println!("hello"); 4 | } 5 | --------------------------------------------------------------------------------