├── .cirrus.yml
├── .codespellrc
├── .config
└── nextest.toml
├── .devcontainer
├── devcontainer.json
└── post_create.sh
├── .dockerignore
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── config.yml
│ └── feature_request.md
├── bors.toml
├── dependabot.yml
└── workflows
│ ├── clear-cache.yml
│ ├── docker.yml
│ ├── downstream.yml
│ ├── release.yml
│ ├── test.yml
│ └── update-auditwheel.yml
├── .gitignore
├── .pre-commit-config.yaml
├── Cargo.lock
├── Cargo.toml
├── Changelog.md
├── Code-of-Conduct.md
├── Dockerfile
├── MANIFEST.in
├── README.md
├── clippy.toml
├── deny.toml
├── guide
├── .gitignore
├── book.toml
├── src
│ ├── SUMMARY.md
│ ├── assets
│ │ └── sponsors
│ │ │ ├── astral.png
│ │ │ ├── bytewax.png
│ │ │ ├── frontend-masters.png
│ │ │ ├── prefect.png
│ │ │ ├── pydantic.png
│ │ │ ├── quansightlabs.jpeg
│ │ │ ├── rerun.png
│ │ │ ├── sentry.png
│ │ │ └── tsy-capital.png
│ ├── bindings.md
│ ├── changelog.md
│ ├── config.md
│ ├── contributing.md
│ ├── distribution.md
│ ├── environment-variables.md
│ ├── import_hook.md
│ ├── index.md
│ ├── installation.md
│ ├── local_development.md
│ ├── metadata.md
│ ├── migration.md
│ ├── platform_support.md
│ ├── project_layout.md
│ ├── sphinx.md
│ └── tutorial.md
└── tweak.css
├── license-apache
├── license-mit
├── maturin.schema.json
├── maturin
├── __init__.py
├── __main__.py
└── bootstrap.py
├── netlify.toml
├── noxfile.py
├── pyproject.toml
├── setup.py
├── src
├── auditwheel
│ ├── audit.rs
│ ├── manylinux-policy.json
│ ├── mod.rs
│ ├── musllinux-policy.json
│ ├── musllinux.rs
│ ├── patchelf.rs
│ ├── platform_tag.rs
│ ├── policy.rs
│ └── repair.rs
├── bridge.rs
├── build_context.rs
├── build_options.rs
├── cargo_toml.rs
├── ci.rs
├── compile.rs
├── cross_compile.rs
├── develop.rs
├── generate_json_schema.rs
├── lib.rs
├── main.rs
├── metadata.rs
├── module_writer.rs
├── new_project.rs
├── project_layout.rs
├── pyproject_toml.rs
├── python_interpreter
│ ├── config.rs
│ ├── get_interpreter_metadata.py
│ └── mod.rs
├── source_distribution.rs
├── target.rs
├── templates
│ ├── .gitignore.j2
│ ├── Cargo.toml.j2
│ ├── __init__.py.j2
│ ├── build.rs.j2
│ ├── example.udl.j2
│ ├── lib.rs.j2
│ ├── main.rs.j2
│ ├── pyproject.toml.j2
│ └── test_all.py.j2
└── upload.rs
├── sysconfig
├── Readme.md
├── cpython-aix-3.9.txt
├── cpython-android-3.8-aarch64.txt
├── cpython-dragonfly-3.8.txt
├── cpython-freebsd-11.2.txt
├── cpython-freebsd-13.0-aarch64.txt
├── cpython-freebsd-13.0-powerpc64.txt
├── cpython-freebsd-13.0-powerpc64le.txt
├── cpython-freebsd-13.1-armv7.txt
├── cpython-freebsd-14.0-riscv64.txt
├── cpython-gnu-3.12.txt
├── cpython-haiku-3.9.txt
├── cpython-linux-3.7.txt
├── cpython-linux-3.8-aarch64.txt
├── cpython-linux-3.8.txt
├── cpython-linux-3.9.txt
├── cpython-linux-armv5te-3.11.txt
├── cpython-linux-mips64-3.11.txt
├── cpython-linux-mips64el-3.10.txt
├── cpython-macos-3.9-arm64.txt
├── cpython-netbsd-3.9.txt
├── cpython-omnios-3.9.txt
├── cpython-openbsd-3.8-aarch64.txt
├── cpython-openbsd-3.8.txt
├── cpython-wasi-3.12.txt
├── cpython-win-3.7.txt
├── cpython-win-3.9-aarch64.txt
├── cpython-win-mingw64-3.9.txt
├── graalpy-macos-3.8-arm64.txt
├── nogil-linux-3.9.txt
├── pypy-linux-3.7-7.3.txt
├── pypy-linux-ppc64le-3.7-7.3.txt
├── pypy-linux-ppc64le-3.8-7.3.txt
├── pypy-linux-ppc64le-3.9-7.3.txt
├── pypy-linux-s390x-3.7-7.3.txt
├── pypy-linux-s390x-3.8-7.3.txt
├── pypy-linux-s390x-3.9-7.3.txt
├── pypy-macos-3.7-7.3.txt
├── pypy-windows-3.7-7.3.txt
└── pyston-3.8.txt
├── test-crates
├── cargo-mock
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── cargo-update.sh
├── cffi-mixed
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── Readme.md
│ ├── cffi_mixed
│ │ ├── __init__.py
│ │ └── line.py
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── requirements_test.txt
│ ├── src
│ │ └── lib.rs
│ ├── test_cffi_mixed.py
│ └── tox.ini
├── cffi-pure
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── Readme.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── requirements_test.txt
│ ├── src
│ │ └── lib.rs
│ ├── test_cffi_pure.py
│ └── tox.ini
├── hello-world
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ └── src
│ │ ├── bin
│ │ └── foo.rs
│ │ └── main.rs
├── lib_with_disallowed_lib
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── pyproject.toml
│ └── src
│ │ └── lib.rs
├── lib_with_path_dep
│ ├── Cargo.toml
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ └── test.sh
├── license-test
│ ├── AUTHORS.txt
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── LICENCE.txt
│ ├── LICENSE
│ ├── NOTICE.md
│ ├── _vendor
│ │ ├── AUTHORS.txt
│ │ ├── COPYING.md
│ │ ├── LICENCE
│ │ ├── LICENSE-APACHE.txt
│ │ ├── NOTICE
│ │ └── nested
│ │ │ ├── LICENSE-BSD
│ │ │ └── NOTICE.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ └── src
│ │ └── main.rs
├── pyo3-abi3-without-version
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ │ └── lib.rs
├── pyo3-bin
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── check_installed
│ │ └── check_installed.py
│ └── src
│ │ └── main.rs
├── pyo3-feature
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── Readme.md
│ └── src
│ │ └── lib.rs
├── pyo3-ffi-pure
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── LICENSE
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ └── test_pyo3_ffi_pure.py
├── pyo3-mixed-implicit
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── python
│ │ └── pyo3_mixed_implicit
│ │ │ └── some_rust
│ │ │ ├── __init__.py
│ │ │ └── double.py
│ ├── src
│ │ └── lib.rs
│ ├── tests
│ │ └── test_pyo3_mixed_implicit.py
│ └── tox.ini
├── pyo3-mixed-include-exclude
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyo3_mixed_include_exclude
│ │ ├── .gitignore
│ │ ├── __init__.py
│ │ ├── exclude_this_file
│ │ ├── include_this_file
│ │ └── python_module
│ │ │ ├── __init__.py
│ │ │ └── double.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ ├── tests
│ │ └── test_pyo3_mixed_include_exclude.py
│ └── tox.ini
├── pyo3-mixed-py-subdir
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── python
│ │ └── pyo3_mixed_py_subdir
│ │ │ ├── __init__.py
│ │ │ └── python_module
│ │ │ ├── __init__.py
│ │ │ └── double.py
│ ├── src
│ │ └── lib.rs
│ ├── test_pyo3_mixed.py
│ └── tox.ini
├── pyo3-mixed-src
│ ├── .gitignore
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── rust
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── lib.rs
│ ├── src
│ │ ├── pyo3_mixed_src
│ │ │ ├── __init__.py
│ │ │ └── python_module
│ │ │ │ ├── __init__.py
│ │ │ │ └── double.py
│ │ └── tests
│ │ │ └── test_pyo3_mixed.py
│ └── tox.ini
├── pyo3-mixed-submodule
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyo3_mixed_submodule
│ │ ├── __init__.py
│ │ ├── python_module
│ │ │ ├── __init__.py
│ │ │ └── double.py
│ │ └── rust_module
│ │ │ └── __init__.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ ├── tests
│ │ └── test_pyo3_mixed_submodule.py
│ └── tox.ini
├── pyo3-mixed-with-path-dep
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyo3_mixed_with_path_dep
│ │ └── __init__.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ ├── tests
│ │ └── test_pyo3_mixed_with_path_dep.py
│ └── tox.ini
├── pyo3-mixed-workspace
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── rust
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── pyo3-mixed-workspace
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ │ └── lib.rs
│ │ └── python
│ │ │ └── pyo3-mixed-workspace-py
│ │ │ ├── Cargo.toml
│ │ │ └── src
│ │ │ └── lib.rs
│ ├── src
│ │ ├── pyo3_mixed_workspace
│ │ │ ├── __init__.py
│ │ │ └── python_module
│ │ │ │ ├── __init__.py
│ │ │ │ └── double.py
│ │ └── tests
│ │ │ └── test_pyo3_mixed.py
│ └── tox.ini
├── pyo3-mixed
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyo3-config.txt
│ ├── pyo3_mixed
│ │ ├── __init__.py
│ │ ├── assets
│ │ │ └── asset.txt
│ │ └── python_module
│ │ │ ├── __init__.py
│ │ │ └── double.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ ├── tests
│ │ └── test_pyo3_mixed.py
│ └── tox.ini
├── pyo3-no-extension-module
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ │ └── lib.rs
├── pyo3-pure
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── LICENSE
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── local-test
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── lib.rs
│ ├── pyo3_pure.pyi
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ ├── tests
│ │ └── test_pyo3_pure.py
│ └── tox.ini
├── readme-duplication
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── readme-py
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── pyproject.toml
│ │ └── src
│ │ │ └── lib.rs
│ └── readme-rs
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── lib.rs
├── sdist_with_path_dep
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── pyproject.toml
│ └── src
│ │ └── lib.rs
├── sdist_with_target_path_dep
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── pyproject.toml
│ └── src
│ │ └── lib.rs
├── some_path_dep
│ ├── Cargo.toml
│ └── src
│ │ └── lib.rs
├── transitive_path_dep
│ ├── Cargo.toml
│ └── src
│ │ └── lib.rs
├── uniffi-mixed
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── src
│ │ ├── lib.rs
│ │ └── math.udl
│ ├── test_uniffi_mixed.py
│ └── uniffi_mixed
│ │ └── __init__.py
├── uniffi-multiple-binding-files
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── check_installed
│ │ └── check_installed.py
│ ├── mylib
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── lib.rs
│ ├── src
│ │ └── lib.rs
│ └── uniffi.toml
├── uniffi-pure-proc-macro
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ ├── test_uniffi_pure.py
│ ├── uniffi-bindgen.rs
│ └── uniffi.toml
├── uniffi-pure
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── src
│ │ ├── lib.rs
│ │ └── math.udl
│ ├── test_uniffi_pure.py
│ └── uniffi.toml
├── update_readme.py
├── with-data
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── check_installed
│ │ └── check_installed.py
│ ├── pyproject.toml
│ ├── src
│ │ └── lib.rs
│ └── with_data.data
│ │ ├── data
│ │ └── data_subdir
│ │ │ └── hello.txt
│ │ └── headers
│ │ └── empty.h
├── workspace-inheritance
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── generic_lib
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── lib.rs
│ └── python
│ │ ├── Cargo.toml
│ │ ├── pyproject.toml
│ │ └── src
│ │ └── lib.rs
├── workspace-inverted-order
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── check_installed
│ │ └── check_installed.py
│ ├── path-dep-with-root
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── pyproject.toml
│ │ └── src
│ │ │ └── lib.rs
│ ├── pyproject.toml
│ └── src
│ │ └── lib.rs
├── workspace
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── Readme.md
│ └── py
│ │ ├── Cargo.toml
│ │ ├── pyproject.toml
│ │ └── src
│ │ └── main.rs
├── workspace_with_path_dep
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── dont_include_in_sdist
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── main.rs
│ ├── generic_lib
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── lib.rs
│ ├── python
│ │ ├── Cargo.toml
│ │ ├── pyproject.toml
│ │ └── src
│ │ │ └── lib.rs
│ └── transitive_lib
│ │ ├── Cargo.toml
│ │ └── src
│ │ └── lib.rs
└── wrong-python-source
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── pyproject.toml
│ ├── python
│ └── run_this
│ │ └── __init__.py
│ └── src
│ ├── bin
│ └── run_this.rs
│ └── lib.rs
├── test-data
├── Readme.md
└── py.exe
├── test-dockerfile.sh
└── tests
├── cli.rs
├── cmd
├── build.stderr
├── build.stdout
├── build.toml
├── develop.stderr
├── develop.stdout
├── develop.toml
├── generate-ci.stderr
├── generate-ci.stdout
├── generate-ci.toml
├── init.stderr
├── init.stdout
├── init.toml
├── list-python.stderr
├── list-python.stdout
├── list-python.toml
├── maturin.stderr
├── maturin.stdout
├── maturin.toml
├── new.stderr
├── new.stdout
├── new.toml
├── publish.stderr
├── publish.stdout
├── publish.toml
├── sdist.stderr
├── sdist.stdout
├── sdist.toml
├── upload.stderr
├── upload.stdout
└── upload.toml
├── common
├── develop.rs
├── errors.rs
├── integration.rs
├── mod.rs
└── other.rs
├── emscripten_runner.js
├── manylinux_compliant.sh
├── manylinux_incompliant.sh
└── run.rs
/.cirrus.yml:
--------------------------------------------------------------------------------
1 | env:
2 | RUST_BACKTRACE: 1
3 | CARGO_INCREMENTAL: 0
4 | CARGO_TERM_COLOR: always
5 | CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse
6 |
7 | build_and_test:
8 | &BUILD_AND_TEST # only run tasks on pull request or github merge queue branches
9 | only_if: $CIRRUS_BRANCH =~ 'gh-readonly-queue/.*' || $CIRRUS_PR != ""
10 | setup_script:
11 | - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
12 | - rustup target add wasm32-wasip1
13 | - python3 -m pip install --upgrade cffi virtualenv
14 | build_script:
15 | - cargo build
16 | test_script:
17 | - cargo test
18 |
19 | freebsd_task:
20 | name: Test (x86_64 FreeBSD)
21 | freebsd_instance:
22 | image_family: freebsd-14-2
23 | env:
24 | PATH: $HOME/.cargo/bin:$PATH
25 | target_cache:
26 | folder: target
27 | fingerprint_script:
28 | - echo $CIRRUS_OS
29 | - cat Cargo.lock
30 | install_script:
31 | - pkg install -y bash git python
32 | - python3 -m ensurepip
33 | <<: *BUILD_AND_TEST
34 |
--------------------------------------------------------------------------------
/.codespellrc:
--------------------------------------------------------------------------------
1 | [codespell]
2 | ignore-words-list = crate,socio-economic
3 | skip = ./.git,./target,./test-crates/venvs,./guide/book
4 |
--------------------------------------------------------------------------------
/.config/nextest.toml:
--------------------------------------------------------------------------------
1 | [profile.default]
2 | # Terminate slow tests after 30 minutes
3 | slow-timeout = { period = "60s", terminate-after = 30 }
4 |
5 | [[profile.default.overrides]]
6 | # See https://nexte.st/book/threads-required.html
7 | filter = 'test(/_uniffi_/)'
8 | threads-required = "num-cpus"
9 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "maturin",
3 | "image": "mcr.microsoft.com/devcontainers/rust:bullseye",
4 | "postCreateCommand": "bash .devcontainer/post_create.sh",
5 | "customizations": {
6 | "vscode": {
7 | "extensions": [
8 | "ms-python.black-formatter",
9 | "rust-lang.rust-analyzer",
10 | "charliermarsh.ruff"
11 | ],
12 | "settings": {
13 | "editor.formatOnSave": true
14 | }
15 | }
16 | },
17 | "features": {
18 | "ghcr.io/devcontainers/features/sshd:1": {
19 | "version": "latest"
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.devcontainer/post_create.sh:
--------------------------------------------------------------------------------
1 | set -euxo pipefail
2 |
3 | sudo apt-get update
4 | sudo apt-get install -y python3-dev python3-pip python3-venv libclang-dev
5 | sudo python3 -m pip install cffi virtualenv pipx
6 |
7 | pipx ensurepath
8 | pipx install uniffi-bindgen
9 | pipx install cargo-deny
10 |
11 | rustup target add wasm32-wasip1
12 | curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
13 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | **/.pytest_cache
2 | **/.tox
3 | **/__pycache__
4 | **/target
5 | **/venv*
6 | .dockerignore
7 | .git
8 | .idea
9 | .travis.yml
10 | .venv
11 | Dockerfile*
12 | appveyor.yml
13 | ci
14 | sysconfig
15 | test-crates
16 | test-data
17 | test-dockerfile.sh
18 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: messense
2 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | name: 🐛 Bug Report
2 | description: Create a bug report
3 | labels: [bug]
4 | body:
5 | - type: markdown
6 | attributes:
7 | value: |
8 | Thank you for taking the time to fill out this bug report!
9 | Please fill out the form below...
10 | - type: textarea
11 | id: description
12 | attributes:
13 | label: Bug Description
14 | description: Please provide a clear and concise description of what the bug is.
15 | placeholder: The bug is...
16 | validations:
17 | required: true
18 | - type: input
19 | id: maturin_version
20 | attributes:
21 | label: Your maturin version (`maturin --version`)
22 | placeholder: ex. 0.14.1
23 | validations:
24 | required: true
25 | - type: input
26 | id: py_version
27 | attributes:
28 | label: Your Python version (`python -V`)
29 | placeholder: ex. Python 3.10.0
30 | validations:
31 | required: true
32 | - type: input
33 | id: pip_version
34 | attributes:
35 | label: Your pip version (`pip -V`)
36 | placeholder: ex. pip 21.1.3
37 | validations:
38 | required: true
39 | - type: dropdown
40 | id: bindings
41 | attributes:
42 | label: What bindings you're using
43 | options:
44 | - "pyo3"
45 | - "cffi"
46 | - "uniffi"
47 | - "bin"
48 | validations:
49 | required: false
50 | - type: checkboxes
51 | id: cargo-build
52 | attributes:
53 | label: Does `cargo build` work?
54 | options:
55 | - label: Yes, it works
56 | required: false
57 | - type: checkboxes
58 | id: windows-unix-path
59 | attributes:
60 | label: If on windows, have you checked that you aren't accidentally using unix path (those with the forward slash `/`)?
61 | options:
62 | - label: "Yes"
63 | required: false
64 | - type: textarea
65 | id: reproduce
66 | attributes:
67 | label: Steps to Reproduce
68 | description: Please list the exact steps required to reproduce your error with all command output and if possible with a repository. Please run maturin with `RUST_LOG=maturin=debug` being set, e.g. `RUST_LOG=maturin=debug maturin build` and share the output, either in a codeblock or as a [gist](https://gist.github.com/)
69 | placeholder: |
70 | 1.
71 | 2.
72 | 3.
73 | validations:
74 | required: true
75 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: ❓ Question
4 | url: https://github.com/PyO3/maturin/discussions
5 | about: Ask and answer questions about maturin on Discussions
6 | - name: 🔧 Troubleshooting
7 | url: https://github.com/PyO3/maturin/discussions
8 | about: For troubleshooting help, see the Discussions
9 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 💡 Feature request
3 | about: Suggest an idea for this project
4 | labels: [enhancement]
5 | ---
6 |
7 |
15 |
--------------------------------------------------------------------------------
/.github/bors.toml:
--------------------------------------------------------------------------------
1 | delete_merged_branches = true
2 | required_approvals = 0
3 | use_codeowners = false
4 | status = [
5 | # GitHub Actions
6 | "conclusion",
7 | # Cirrus CI
8 | "Test (x86_64 FreeBSD)",
9 | "Test (arm64 macOS)",
10 | "Test (arm64 Linux)"
11 | ]
12 | timeout_sec = 21600
13 |
--------------------------------------------------------------------------------
/.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: "cargo" # See documentation for possible values
9 | directory: "/" # Location of package manifests
10 | schedule:
11 | interval: "monthly"
12 | groups:
13 | crates-io:
14 | patterns:
15 | - "*"
16 |
17 | - package-ecosystem: "github-actions"
18 | directory: "/"
19 | schedule:
20 | interval: "monthly"
21 |
--------------------------------------------------------------------------------
/.github/workflows/clear-cache.yml:
--------------------------------------------------------------------------------
1 | name: Clear Actions Cache
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | permissions:
7 | actions: write
8 |
9 | jobs:
10 | clear-cache:
11 | name: Clean Cache
12 | runs-on: ubuntu-latest
13 | env:
14 | GH_TOKEN: ${{ github.token }}
15 | steps:
16 | - name: Clear cache
17 | run: |
18 | gh cache delete --all --repo "$GITHUB_REPOSITORY"
19 | echo "cache cleared"
20 |
--------------------------------------------------------------------------------
/.github/workflows/docker.yml:
--------------------------------------------------------------------------------
1 | name: Docker Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | tags: [ 'v*' ]
8 |
9 | jobs:
10 | publish-docker:
11 | name: Publish Docker Images
12 | runs-on: ubuntu-latest
13 | environment:
14 | name: Docker Hub
15 | url: https://ghcr.io/pyo3/maturin
16 | steps:
17 | - uses: actions/checkout@v4
18 | - uses: dorny/paths-filter@v3
19 | id: changes
20 | with:
21 | filters: |
22 | changed:
23 | - 'Cargo.toml'
24 | - 'Cargo.lock'
25 | - 'src/**'
26 | - 'Dockerfile'
27 | - '.github/workflows/docker.yml'
28 | - '.dockerignore'
29 | - name: Setup QEMU
30 | if: ${{ steps.changes.outputs.changed == 'true' || startsWith(github.ref, 'refs/tags/') }}
31 | uses: dbhi/qus/action@main
32 | - uses: docker/setup-buildx-action@v3
33 | if: ${{ steps.changes.outputs.changed == 'true' || startsWith(github.ref, 'refs/tags/') }}
34 | - uses: docker/metadata-action@v5
35 | if: ${{ steps.changes.outputs.changed == 'true' || startsWith(github.ref, 'refs/tags/') }}
36 | id: meta
37 | with:
38 | images: ghcr.io/pyo3/maturin
39 | - name: Login to GitHub Container Registry
40 | if: ${{ steps.changes.outputs.changed == 'true' || startsWith(github.ref, 'refs/tags/') }}
41 | uses: docker/login-action@v3
42 | with:
43 | registry: ghcr.io
44 | username: ${{ github.actor }}
45 | password: ${{ secrets.GITHUB_TOKEN }}
46 | - name: Build and push
47 | if: ${{ steps.changes.outputs.changed == 'true' || startsWith(github.ref, 'refs/tags/') }}
48 | uses: docker/build-push-action@v6
49 | with:
50 | context: .
51 | platforms: linux/amd64,linux/arm64
52 | push: true
53 | tags: ${{ steps.meta.outputs.tags }}
54 | labels: ${{ steps.meta.outputs.labels }}
55 | # https://github.com/docker/build-push-action/blob/master/docs/advanced/cache.md#registry-cache
56 | cache-from: type=registry,ref=ghcr.io/pyo3/maturin:buildcache
57 | cache-to: type=registry,ref=ghcr.io/pyo3/maturin:buildcache,mode=max
58 |
--------------------------------------------------------------------------------
/.github/workflows/downstream.yml:
--------------------------------------------------------------------------------
1 | on:
2 | workflow_call:
3 | inputs:
4 | repository:
5 | required: true
6 | type: string
7 | manifest-dir:
8 | required: true
9 | type: string
10 |
11 | jobs:
12 | sdist:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Sccache Setup
17 | uses: mozilla-actions/sccache-action@v0.0.9
18 | with:
19 | version: "v0.10.0"
20 | - name: Build maturin
21 | env:
22 | RUST_BACKTRACE: "1"
23 | SCCACHE_GHA_ENABLED: "true"
24 | RUSTC_WRAPPER: "sccache"
25 | run: cargo build
26 | - uses: actions/checkout@v4
27 | with:
28 | repository: ${{ inputs.repository }}
29 | submodules: "recursive"
30 | path: downstream
31 | - name: maturin sdist
32 | working-directory: downstream
33 | run: |
34 | ../target/debug/maturin sdist --manifest-path ${{ inputs.manifest-dir }}/Cargo.toml -o target/sdist
35 | - name: Build from sdist
36 | working-directory: downstream
37 | run: |
38 | ../target/debug/maturin build --manifest-path ${{ inputs.manifest-dir }}/Cargo.toml
39 |
--------------------------------------------------------------------------------
/.github/workflows/update-auditwheel.yml:
--------------------------------------------------------------------------------
1 | name: Update auditwheel policies
2 |
3 | on:
4 | workflow_dispatch:
5 | schedule:
6 | # Run every week
7 | - cron: '0 0 * * 0'
8 |
9 | permissions: # added using https://github.com/step-security/secure-workflows
10 | contents: read
11 |
12 | jobs:
13 | update:
14 | permissions:
15 | contents: write # for peter-evans/create-pull-request to create branch
16 | pull-requests: write # for peter-evans/create-pull-request to create a PR
17 | name: Update auditwheel policies
18 | runs-on: ubuntu-latest
19 | steps:
20 | - uses: actions/checkout@v4
21 | - name: Fetch latest policy files
22 | run: |
23 | curl https://raw.githubusercontent.com/pypa/auditwheel/main/src/auditwheel/policy/manylinux-policy.json > src/auditwheel/manylinux-policy.json
24 | curl https://raw.githubusercontent.com/pypa/auditwheel/main/src/auditwheel/policy/musllinux-policy.json > src/auditwheel/musllinux-policy.json
25 | - name: Create Pull Request
26 | uses: peter-evans/create-pull-request@v7
27 | with:
28 | delete-branch: true
29 | add-paths: |
30 | src/auditwheel/*.json
31 | title: 'Update manylinux/musllinux policies to the latest main'
32 | commit-message: 'Update manylinux/musllinux policies to the latest main'
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | venv*/
3 | .venv/
4 | .pytest_cache/
5 | .tox/
6 | *.o
7 | *.so
8 | *.py[cdo]
9 | __pycache__/
10 | *.egg-info/
11 | *.egg
12 | dist/
13 | build
14 | dist
15 | tags
16 | test-crates/wheels/
17 | test-crates/targets/
18 | test-crates/venvs/
19 | node_modules
20 | .idea
21 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # run all hooks with:
2 | # pre-commit run --hook-stage manual --all
3 | ci:
4 | skip:
5 | # pre-commit.ci doesn't have Rust installed
6 | - cargo-fmt
7 | - cargo-deny
8 |
9 | repos:
10 | - repo: local
11 | hooks:
12 | - id: cargo-fmt # rustup component add rustfmt
13 | name: cargo fmt
14 | entry: cargo fmt --all --
15 | language: system
16 | types: [rust]
17 | pass_filenames: false
18 |
19 | - id: cargo-deny # cargo install --locked cargo-deny
20 | name: cargo deny
21 | entry: cargo deny --all-features check --
22 | language: system
23 | pass_filenames: false
24 |
25 | - id: cargo-check
26 | name: cargo check
27 | entry: cargo check --all-features --all-targets --
28 | language: system
29 | pass_filenames: false
30 | types: [rust]
31 | stages: [manual] # because it's slow
32 |
33 | - id: cargo-clippy # rustup component add clippy
34 | name: cargo clippy
35 | entry: cargo clippy --tests --all-features -- -D warnings
36 | language: system
37 | pass_filenames: false
38 | types: [rust]
39 | stages: [manual] # because it's slow
40 | - repo: https://github.com/pre-commit/pre-commit-hooks
41 | rev: v5.0.0
42 | hooks:
43 | - id: check-yaml
44 | - id: check-toml
45 | - id: end-of-file-fixer
46 | exclude: |
47 | (?x)(
48 | (^sysconfig/)|
49 | (.*\.stdout)
50 | )
51 | - id: trailing-whitespace
52 | exclude: |
53 | (?x)(
54 | (^sysconfig/)|
55 | (.*\.stdout)
56 | )
57 | - id: mixed-line-ending
58 | - repo: https://github.com/astral-sh/ruff-pre-commit
59 | rev: v0.11.11
60 | hooks:
61 | - id: ruff-format
62 | - id: ruff
63 | - repo: https://github.com/pre-commit/mirrors-mypy
64 | rev: v1.15.0
65 | hooks:
66 | - id: mypy
67 | entry: mypy maturin/
68 | pass_filenames: false
69 | - repo: https://github.com/codespell-project/codespell
70 | rev: v2.4.1
71 | hooks:
72 | - id: codespell
73 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # x86_64 base
2 | FROM quay.io/pypa/manylinux2014_x86_64 AS base-amd64
3 | # x86_64 builder
4 | FROM --platform=$BUILDPLATFORM ghcr.io/rust-cross/rust-musl-cross:x86_64-musl AS builder-amd64
5 |
6 | # aarch64 base
7 | FROM quay.io/pypa/manylinux2014_aarch64 AS base-arm64
8 | # aarch64 cross compile builder
9 | FROM --platform=$BUILDPLATFORM ghcr.io/rust-cross/rust-musl-cross:aarch64-musl AS builder-arm64
10 |
11 | ARG TARGETARCH
12 | FROM builder-$TARGETARCH AS builder
13 |
14 | ENV PATH=/root/.cargo/bin:$PATH
15 |
16 | # Compile dependencies only for build caching
17 | ADD Cargo.toml /maturin/Cargo.toml
18 | ADD Cargo.lock /maturin/Cargo.lock
19 | RUN --mount=type=cache,target=/root/.cargo/git \
20 | --mount=type=cache,target=/root/.cargo/registry \
21 | --mount=type=cache,target=/maturin/target,sharing=locked \
22 | mkdir /maturin/src && \
23 | touch /maturin/src/lib.rs && \
24 | echo 'fn main() { println!("Dummy") }' > /maturin/src/main.rs && \
25 | cargo rustc --target $CARGO_BUILD_TARGET --bin maturin --manifest-path /maturin/Cargo.toml --release --features password-storage -- -C link-arg=-s
26 |
27 | ADD . /maturin/
28 |
29 | # Manually update the timestamps as ADD keeps the local timestamps and cargo would then believe the cache is fresh
30 | RUN touch /maturin/src/lib.rs /maturin/src/main.rs
31 |
32 | RUN --mount=type=cache,target=/root/.cargo/git \
33 | --mount=type=cache,target=/root/.cargo/registry \
34 | --mount=type=cache,target=/maturin/target,sharing=locked \
35 | cargo rustc --target $CARGO_BUILD_TARGET --bin maturin --manifest-path /maturin/Cargo.toml --release --features password-storage -- -C link-arg=-s \
36 | && mv /maturin/target/$CARGO_BUILD_TARGET/release/maturin /usr/bin/maturin
37 |
38 | FROM base-$TARGETARCH
39 |
40 | ENV PATH=/root/.cargo/bin:$PATH
41 | # Add all supported python versions
42 | ENV PATH=/opt/python/cp39-cp39/bin:/opt/python/cp310-cp310/bin:/opt/python/cp311-cp311/bin:/opt/python/cp312-cp312/bin:/opt/python/cp313-cp313/bin/:/opt/python/cp313-cp313t/bin/:$PATH
43 | # Otherwise `cargo new` errors
44 | ENV USER=root
45 |
46 | RUN curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
47 | && yum install -y libffi-devel openssh-clients \
48 | && python3.8 -m pip install --no-cache-dir cffi \
49 | && python3.9 -m pip install --no-cache-dir cffi \
50 | && python3.10 -m pip install --no-cache-dir cffi \
51 | && python3.11 -m pip install --no-cache-dir cffi \
52 | && python3.12 -m pip install --no-cache-dir cffi \
53 | && mkdir /io
54 |
55 | COPY --from=builder /usr/bin/maturin /usr/bin/maturin
56 |
57 | WORKDIR /io
58 |
59 | ENTRYPOINT ["/usr/bin/maturin"]
60 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include Cargo.toml Cargo.lock
2 | include README.md
3 | include license-apache license-mit
4 | recursive-include src *.rs *.py
5 | recursive-include src/auditwheel *.json
6 | recursive-include src/python_interpreter *.py *.json
7 | recursive-include src/templates *.j2
8 |
--------------------------------------------------------------------------------
/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 | ]
30 |
--------------------------------------------------------------------------------
/guide/.gitignore:
--------------------------------------------------------------------------------
1 | book
2 |
--------------------------------------------------------------------------------
/guide/book.toml:
--------------------------------------------------------------------------------
1 | [book]
2 | authors = ["PyO3 Project and Contributors"]
3 | language = "en"
4 | src = "src"
5 | title = "Maturin User Guide"
6 |
7 | [output.html]
8 | additional-css = ["tweak.css"]
9 | git-repository-url = "https://github.com/PyO3/maturin/tree/main/guide"
10 | edit-url-template = "https://github.com/PyO3/maturin/edit/main/guide/{path}"
11 |
--------------------------------------------------------------------------------
/guide/src/SUMMARY.md:
--------------------------------------------------------------------------------
1 | # Summary
2 |
3 | [Introduction](index.md)
4 |
5 | ---
6 |
7 | - [Installation](./installation.md)
8 | - [Tutorial](./tutorial.md)
9 | - [Project Layout](./project_layout.md)
10 | - [Bindings](./bindings.md)
11 | - [Python Metadata](./metadata.md)
12 | - [Configuration](./config.md)
13 | - [Environment Variables](./environment-variables.md)
14 | - [Local Development](./local_development.md)
15 | - [Import Hook](./import_hook.md)
16 | - [Distribution](./distribution.md)
17 | - [Sphinx Integration](./sphinx.md)
18 |
19 | ---
20 |
21 | - [Migration Guide](./migration.md)
22 | - [Changelog](./changelog.md)
23 |
24 | ---
25 |
26 | - [Contributing](./contributing.md)
27 | - [Platform Support](./platform_support.md)
28 |
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/astral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/astral.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/bytewax.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/bytewax.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/frontend-masters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/frontend-masters.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/prefect.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/prefect.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/pydantic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/pydantic.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/quansightlabs.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/quansightlabs.jpeg
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/rerun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/rerun.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/sentry.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/sentry.png
--------------------------------------------------------------------------------
/guide/src/assets/sponsors/tsy-capital.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PyO3/maturin/b3e8be3986df7dd8622e0c285082848ab7c0159a/guide/src/assets/sponsors/tsy-capital.png
--------------------------------------------------------------------------------
/guide/src/changelog.md:
--------------------------------------------------------------------------------
1 | {{#include ../../Changelog.md}}
2 |
--------------------------------------------------------------------------------
/guide/src/environment-variables.md:
--------------------------------------------------------------------------------
1 | # Environment Variables
2 |
3 | Maturin reads a number of environment variables which you can use to configure the build process.
4 | Here is a list of all environment variables that are read by maturin:
5 |
6 | ## Cargo environment variables
7 |
8 | See [environment variables Cargo reads](https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-reads)
9 |
10 | ## Python environment variables
11 |
12 | * `VIRTUAL_ENV`: Path to a Python virtual environment
13 | * `CONDA_PREFIX`: Path to a conda environment
14 | * `MATURIN_PYTHON_SYSCONFIGDATA_DIR`: Path to a directory containing a `sysconfigdata*.py` file
15 | * `_PYTHON_SYSCONFIGDATA_NAME`: Name of a `sysconfigdata*.py` file
16 | * `MATURIN_PYPI_TOKEN`: PyPI token for uploading wheels
17 | * `MATURIN_PASSWORD`: PyPI password for uploading wheels
18 | * `MATURIN_PEP517_USE_BASE_PYTHON`: Use base Python executable instead of venv Python executable in PEP 517 build to avoid unnecessary rebuilds, should not be set when the sdist build requires packages installed in venv.
19 |
20 | ## `pyo3` environment variables
21 |
22 | * `PYO3_CROSS_PYTHON_VERSION`: Python version to use for cross compilation
23 | * `PYO3_CROSS_LIB_DIR`: This variable can be set to the directory containing the target's libpython DSO and the associated `_sysconfigdata*.py` file for Unix-like targets, or the Python DLL import libraries for the Windows target.This variable can be set to the directory containing the target's libpython DSO and the associated _sysconfigdata*.py file for Unix-like targets, or the Python DLL import libraries for the Windows target.
24 | * `PYO3_CONFIG_FILE`: Path to a [pyo3 config file](https://pyo3.rs/latest/building_and_distribution.html#advanced-config-files)
25 |
26 | ## Networking environment variables
27 |
28 | * `HTTP_PROXY` / `HTTPS_PROXY`: Proxy to use for HTTP/HTTPS requests
29 | * `REQUESTS_CA_BUNDLE` / `CURL_CA_BUNDLE`: Path to a CA bundle to use for HTTPS requests
30 |
31 | ## Other environment variables
32 |
33 | * `MACOSX_DEPLOYMENT_TARGET`: The minimum macOS version to target
34 | * `SOURCE_DATE_EPOCH`: The time to use for the timestamp in the wheel metadata
35 | * `MATURIN_EMSCRIPTEN_VERSION`: The version of emscripten to use for emscripten builds
36 | * `MATURIN_NO_MISSING_BUILD_BACKEND_WARNING`: Suppress missing build backend warning
37 | * `MATURIN_USE_XWIN`: Set to `1` to force to use `xwin` for cross compiling even on Windows that supports native compilation
38 | * `TARGET_SYSROOT`: The sysroot to use for auditwheel wheel when cross compiling
39 | * `ARCHFLAGS`: Flags to control the architecture of the build on macOS, for example you can use `ARCHFLAGS="-arch x86_64 -arch arm64"` to build universal2 wheels
40 |
--------------------------------------------------------------------------------
/guide/src/index.md:
--------------------------------------------------------------------------------
1 | # Maturin User Guide
2 |
3 | Welcome to the maturin user guide! It contains examples and documentation to explain all of maturin's use cases in detail.
4 |
5 | Please choose from the chapters on the left to jump to individual topics, or continue below to start with maturin's README.
6 |
7 | ## Sponsors
8 |
9 | Development of maturin is made possible by the following sponsors:
10 |
11 |
67 |
68 | And many more who kindly sponsor @messense on [GitHub Sponsors](https://github.com/sponsors/messense#sponsors).
69 |
70 | {{#include ../../README.md}}
71 |
--------------------------------------------------------------------------------
/guide/src/platform_support.md:
--------------------------------------------------------------------------------
1 | # Platform Support
2 |
3 | Being built on cargo and rustc, maturin is limited by [rust's platform support](https://doc.rust-lang.org/nightly/rustc/platform-support.html).
4 |
5 | ## Automated tests
6 |
7 | On GitHub actions, windows, macOS and linux are tested, all
8 | on 64-bit x86. FreeBSD is also tested though Cirrus CI, but might get removed at
9 | some point. Since CI is very time intensive to maintain, I'd like to stick to
10 | GitHub action and these three platforms.
11 |
12 | ## Releases
13 |
14 | The following targets are built into wheels and downloadable binaries:
15 |
16 | * Windows: 32-bit and 64-bit x86 as well as arm64
17 | * Linux: x86, x86_64, armv7, aarch64 and ppc64le (musl), as well as s390x (gnu)
18 | * macOS: x86_64 and aarch64
19 |
20 | ## Other Operating Systems
21 |
22 | It should be possible to build maturin and for maturin to build wheels on other platforms supported by rust.
23 | To add a new os, add it in target.rs and, if it doesn't behave like the other unixes, in
24 | `PythonInterpreter::get_tag`. Please also submit the output of `python -m sysconfig` as a file in the `sysconfig` folder.
25 | It's ok to edit setup.py to deactivate default features so `pip install` works, but new platforms should not
26 | require complex workaround in `compile.rs`.
27 |
28 | ## Architectures
29 |
30 | All architectures included in manylinux (aarch64, armv7l, ppc64le, ppc64, i686, x86_64, s390x) are supported.
31 | I'm not sure whether it makes sense to allow architectures that aren't even
32 | supported by [manylinux](https://github.com/pypa/manylinux).
33 |
34 | ## Python Support
35 |
36 | CPython 3.8 to 3.10 are supported and tested on CI, though the entire 3.x series should work.
37 | This will be changed as new python versions are released and others have their end of life.
38 |
39 | PyPy 3.6 and later also works, as does GraalPy 23.0 and later.
40 |
41 | ## Manylinux/Musllinux
42 |
43 | `manylinux2014` and its newer versions as well as `musllinux_1_1` and its newer versions
44 | are supported.
45 |
46 | Since Rust and the manylinux project drop support for old manylinux/musllinux versions sometimes,
47 | after maturin 1.0 manylinux version bumps will be minor versions rather than major versions.
48 |
--------------------------------------------------------------------------------
/guide/tweak.css:
--------------------------------------------------------------------------------
1 | .sponsors {
2 | display: flex;
3 | justify-content: left;
4 | flex-wrap: wrap;
5 | align-items: center;
6 | margin: 1rem 0;
7 | }
8 |
9 | .sponsors > div {
10 | text-align: center;
11 | width: 25%;
12 | padding-bottom: 20px;
13 | }
14 |
15 | .sponsors span {
16 | display: block;
17 | }
18 |
--------------------------------------------------------------------------------
/license-mit:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 konstin
2 |
3 | Permission is hereby granted, free of charge, to any
4 | person obtaining a copy of this software and associated
5 | documentation files (the "Software"), to deal in the
6 | Software without restriction, including without
7 | limitation the rights to use, copy, modify, merge,
8 | publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software
10 | is furnished to do so, subject to the following
11 | conditions:
12 |
13 | The above copyright notice and this permission notice
14 | shall be included in all copies or substantial portions
15 | of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 | DEALINGS IN THE SOFTWARE.
26 |
--------------------------------------------------------------------------------
/maturin/__main__.py:
--------------------------------------------------------------------------------
1 | from __future__ import annotations
2 |
3 | import os
4 | import sys
5 | from pathlib import Path
6 | import sysconfig
7 | from typing import Optional
8 |
9 |
10 | def get_maturin_path() -> Optional[Path]:
11 | SCRIPT_NAME = "maturin"
12 |
13 | def script_dir(scheme: str) -> str:
14 | return sysconfig.get_path("scripts", scheme)
15 |
16 | def script_exists(dir: str) -> bool:
17 | for _, _, files in os.walk(dir):
18 | for f in files:
19 | name, *_ = os.path.splitext(f)
20 | if name == SCRIPT_NAME:
21 | return True
22 |
23 | return False
24 |
25 | paths = list(
26 | filter(
27 | script_exists,
28 | filter(os.path.exists, map(script_dir, sysconfig.get_scheme_names())),
29 | )
30 | )
31 |
32 | if paths:
33 | return Path(paths[0]) / SCRIPT_NAME
34 |
35 | return None
36 |
37 |
38 | if __name__ == "__main__":
39 | maturin = get_maturin_path()
40 | if maturin is None:
41 | print("Unable to find `maturin` script")
42 | exit(1)
43 |
44 | if sys.platform == "win32":
45 | import subprocess
46 |
47 | code = subprocess.call([str(maturin)] + sys.argv[1:])
48 | sys.exit(code)
49 | else:
50 | os.execv(maturin, [str(maturin)] + sys.argv[1:])
51 |
--------------------------------------------------------------------------------
/maturin/bootstrap.py:
--------------------------------------------------------------------------------
1 | """Support installing rust before compiling (bootstrapping) maturin.
2 |
3 | Installing a package that uses maturin as build backend on a platform without maturin
4 | binaries, we install rust in a cache directory if the user doesn't have a rust
5 | installation already. Since this bootstrapping requires more dependencies but is only
6 | required if rust is missing, we check if cargo is present before requesting those
7 | dependencies.
8 |
9 | https://setuptools.pypa.io/en/stable/build_meta.html#dynamic-build-dependencies-and-other-build-meta-tweaks
10 | """
11 |
12 | from __future__ import annotations
13 |
14 | import os
15 | import shutil
16 | from typing import Any
17 |
18 | # noinspection PyUnresolvedReferences
19 | from setuptools.build_meta import * # noqa:F403
20 | from setuptools.build_meta import (
21 | get_requires_for_build_sdist as _orig_get_requires_for_build_sdist,
22 | )
23 | from setuptools.build_meta import (
24 | get_requires_for_build_wheel as _orig_get_requires_for_build_wheel,
25 | )
26 |
27 |
28 | def get_requires_for_build_wheel(config_settings: dict[str, Any] | None = None) -> list[str]:
29 | reqs = _orig_get_requires_for_build_wheel()
30 | if not os.environ.get("MATURIN_NO_INSTALL_RUST") and not shutil.which("cargo"):
31 | reqs.append("puccinialin>=0.1,<0.2")
32 | return reqs
33 |
34 |
35 | def get_requires_for_build_sdist(config_settings: dict[str, Any] | None = None) -> list[str]:
36 | reqs = _orig_get_requires_for_build_sdist()
37 | if not os.environ.get("MATURIN_NO_INSTALL_RUST") and not shutil.which("cargo"):
38 | reqs.append("puccinialin>=0.1,<0.2")
39 | return reqs
40 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | publish = "guide/book/"
3 | command = "curl -L https://github.com/rust-lang/mdBook/releases/download/v0.4.43/mdbook-v0.4.43-x86_64-unknown-linux-musl.tar.gz | tar xvz && ./mdbook build guide"
4 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | # Workaround to bootstrap maturin on non-manylinux platforms
2 | [build-system]
3 | requires = [
4 | "setuptools",
5 | "tomli>=1.1.0 ; python_version<'3.11'",
6 | "setuptools-rust>=1.11.0",
7 | ]
8 | backend-path = ["maturin"]
9 | build-backend = "bootstrap"
10 |
11 | [project]
12 | name = "maturin"
13 | description = "Build and publish crates with pyo3, cffi and uniffi bindings as well as rust binaries as python packages"
14 | authors = [{ name = "konstin", email = "konstin@mailbox.org" }]
15 | readme = { file = "README.md", content-type = "text/markdown" }
16 | requires-python = ">=3.7"
17 | license = { text = "MIT OR Apache-2.0" }
18 | classifiers = [
19 | "Topic :: Software Development :: Build Tools",
20 | "Programming Language :: Rust",
21 | "Programming Language :: Python :: Implementation :: CPython",
22 | "Programming Language :: Python :: Implementation :: PyPy",
23 | ]
24 | dependencies = ["tomli>=1.1.0 ; python_version<'3.11'"]
25 | dynamic = ["version"]
26 |
27 | [project.optional-dependencies]
28 | zig = ["ziglang>=0.10.0,<0.13.0"]
29 | patchelf = ["patchelf"]
30 |
31 | [project.urls]
32 | "Source Code" = "https://github.com/PyO3/maturin"
33 | Issues = "https://github.com/PyO3/maturin/issues"
34 | Documentation = "https://maturin.rs"
35 | Changelog = "https://maturin.rs/changelog.html"
36 |
37 | [tool.setuptools]
38 | packages = ["maturin"]
39 |
40 | [tool.maturin]
41 | bindings = "bin"
42 |
43 | [tool.black]
44 | target-version = ['py37']
45 | extend-exclude = '''
46 | # Ignore cargo-generate templates
47 | ^/src/templates
48 | '''
49 |
50 | [tool.ruff]
51 | line-length = 120
52 | target-version = "py37"
53 |
54 | [tool.mypy]
55 | disallow_untyped_defs = true
56 | disallow_incomplete_defs = true
57 | warn_no_return = true
58 | ignore_missing_imports = true
59 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # maturin is self bootstrapping, however on platforms like FreeBSD that aren't
2 | # manylinux/musllinux, pip will try installing maturin from the source distribution.
3 | # That source distribution obviously can't depend on maturin, so we're using
4 | # the always available setuptools.
5 | #
6 | # Note that this is really only a workaround for bootstrapping and not suited
7 | # for general purpose packaging, i.e. only building a wheel (as in
8 | # `python setup.py bdist_wheel`) and installing (as in
9 | # `pip install `) are supported. For creating a source distribution
10 | # for maturin itself use `maturin sdist`.
11 |
12 | import os
13 | import shlex
14 | import shutil
15 |
16 | try:
17 | import tomllib
18 | except ModuleNotFoundError:
19 | import tomli as tomllib
20 | from setuptools import setup
21 |
22 | from setuptools_rust import RustBin
23 |
24 | # Force the wheel to be platform specific
25 | # https://stackoverflow.com/a/45150383/3549270
26 | # There's also the much more concise solution in
27 | # https://stackoverflow.com/a/53463910/3549270,
28 | # but that would require python-dev
29 | try:
30 | # noinspection PyPackageRequirements,PyUnresolvedReferences
31 | from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
32 |
33 | # noinspection PyPep8Naming,PyAttributeOutsideInit
34 | class bdist_wheel(_bdist_wheel):
35 | def finalize_options(self):
36 | _bdist_wheel.finalize_options(self)
37 | self.root_is_pure = False
38 |
39 | except ImportError:
40 | bdist_wheel = None
41 |
42 | with open("Cargo.toml", "rb") as fp:
43 | version = tomllib.load(fp)["package"]["version"]
44 |
45 | # Use `--no-default-features` by default for a minimal build to support PEP 517.
46 | # `MATURIN_SETUP_ARGS` env var can be used to pass customized arguments to cargo.
47 | cargo_args = ["--no-default-features"]
48 | if os.getenv("MATURIN_SETUP_ARGS"):
49 | cargo_args = shlex.split(os.getenv("MATURIN_SETUP_ARGS", ""))
50 |
51 | if not os.environ.get("MATURIN_NO_INSTALL_RUST") and not shutil.which("cargo"):
52 | from puccinialin import setup_rust
53 |
54 | print("Rust not found, installing into a temporary directory")
55 | extra_env = setup_rust()
56 | env = {**os.environ, **extra_env}
57 | else:
58 | env = None
59 |
60 | setup(
61 | version=version,
62 | cmdclass={"bdist_wheel": bdist_wheel},
63 | rust_extensions=[RustBin("maturin", args=cargo_args, cargo_manifest_args=["--locked"], env=env)],
64 | zip_safe=False,
65 | )
66 |
--------------------------------------------------------------------------------
/src/auditwheel/mod.rs:
--------------------------------------------------------------------------------
1 | mod audit;
2 | mod musllinux;
3 | pub mod patchelf;
4 | mod platform_tag;
5 | mod policy;
6 | mod repair;
7 |
8 | pub use audit::*;
9 | pub use platform_tag::PlatformTag;
10 | pub use policy::Policy;
11 | pub use repair::find_external_libs;
12 |
--------------------------------------------------------------------------------
/src/auditwheel/musllinux-policy.json:
--------------------------------------------------------------------------------
1 | [
2 | {"name": "linux",
3 | "aliases": [],
4 | "priority": 0,
5 | "symbol_versions": {},
6 | "lib_whitelist": [],
7 | "blacklist": {}
8 | },
9 | {"name": "musllinux_1_1",
10 | "aliases": [],
11 | "priority": 100,
12 | "symbol_versions": {
13 | "i686": {
14 | },
15 | "x86_64": {
16 | },
17 | "aarch64": {
18 | },
19 | "ppc64le": {
20 | },
21 | "s390x": {
22 | },
23 | "armv7l": {
24 | },
25 | "riscv64": {
26 | }
27 | },
28 | "lib_whitelist": ["libc.so", "libz.so.1"],
29 | "blacklist": {
30 | "libz.so.1": ["_dist_code", "_length_code", "_tr_align", "_tr_flush_block", "_tr_init", "_tr_stored_block", "_tr_tally", "bi_windup", "crc32_vpmsum", "crc_fold_512to32", "crc_fold_copy", "crc_fold_init", "deflate_copyright", "deflate_medium", "fill_window", "flush_pending", "gzflags", "inflate_copyright", "inflate_fast", "inflate_table", "longest_match", "slide_hash_sse", "static_ltree", "uncompress2", "x86_check_features", "x86_cpu_has_pclmul", "x86_cpu_has_sse2", "x86_cpu_has_sse42", "z_errmsg", "zcalloc", "zcfree"]
31 | }},
32 | {"name": "musllinux_1_2",
33 | "aliases": [],
34 | "priority": 90,
35 | "symbol_versions": {
36 | "i686": {
37 | },
38 | "x86_64": {
39 | },
40 | "aarch64": {
41 | },
42 | "ppc64le": {
43 | },
44 | "s390x": {
45 | },
46 | "armv7l": {
47 | },
48 | "riscv64": {
49 | },
50 | "loongarch64": {
51 | }
52 | },
53 | "lib_whitelist": ["libc.so", "libz.so.1"],
54 | "blacklist": {
55 | "libz.so.1": ["_dist_code", "_length_code", "_tr_align", "_tr_flush_block", "_tr_init", "_tr_stored_block", "_tr_tally", "bi_windup", "crc32_vpmsum", "crc_fold_512to32", "crc_fold_copy", "crc_fold_init", "deflate_copyright", "deflate_medium", "fill_window", "flush_pending", "gzflags", "inflate_copyright", "inflate_fast", "inflate_table", "longest_match", "slide_hash_sse", "static_ltree", "uncompress2", "x86_check_features", "x86_cpu_has_pclmul", "x86_cpu_has_sse2", "x86_cpu_has_sse42", "z_errmsg", "zcalloc", "zcfree"]
56 | }}
57 | ]
58 |
--------------------------------------------------------------------------------
/src/auditwheel/musllinux.rs:
--------------------------------------------------------------------------------
1 | use anyhow::{Context, Result};
2 | use fs_err as fs;
3 | use goblin::elf::Elf;
4 | use regex::Regex;
5 | use std::path::{Path, PathBuf};
6 | use std::process::{Command, Stdio};
7 |
8 | /// Find musl libc path from executable's ELF header
9 | pub fn find_musl_libc() -> Result