Vendor deps.
This commit is contained in:
1 parent
294527085e
commit
91e18fde3a
1714 files changed
+556667
-7
No files matched your search
@@ -0,0 +1 @@
|
||||
{"files":{".cargo_vcs_info.json":"62631cffb4cec2302abe114e9a2b63fbe62a197585488228d9bfc14310172311","Cargo.lock":"5d1ddc2379c2967275986ca1d92d27f377e197b1bc674a6641489e4d061a4be7","Cargo.toml":"f8dcc21ccccfb2ba65fa980b5d0a24b637eabb1532efceebc29daa667fe04ad3","Cargo.toml.orig":"5a1bac59ad9c6bb92745b5f88087e096931fa4f4915c7a317cf1f84945902960","LICENSE-APACHE":"32c76dbe0e73d79100d5ece77c158399f2e2541bc5c78548a4ba45c1cb53c5c9","LICENSE-MIT":"afcbe3b2e6b37172b5a9ca869ee4c0b8cdc09316e5d4384864154482c33e5af6","src/errors.rs":"64cf02f4dcc9a512bef51e01252f01b24a4d7a147570aa66593112212d7257e9","src/impl_.rs":"3a34d57a0c9ec4d017b9ed08966e1f21b312b32a818a4a44b1ac6b7d836264a6","src/lib.rs":"bc122441147b2e5e3e13bf35e2306ba2b86fd5c7a6a3c1af77b8e7025a63038f"},"package":"f41027e41b4bd03f6e60f9f417fe24a6341a6bb744edd62b6f709f2a52ea30e9"}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"git": {
|
||||
"sha1": "a70d17f898df41b3d1632ee987f624f5222d8d39"
|
||||
},
|
||||
"path_in_vcs": "pyo3-build-config"
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.29.2"
|
||||
dependencies = [
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2021"
|
||||
rust-version = "1.83"
|
||||
name = "pyo3-build-config"
|
||||
version = "0.29.2"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||
build = false
|
||||
autolib = false
|
||||
autobins = false
|
||||
autoexamples = false
|
||||
autotests = false
|
||||
autobenches = false
|
||||
description = "Build configuration for the PyO3 ecosystem"
|
||||
homepage = "https://github.com/pyo3/pyo3"
|
||||
readme = false
|
||||
keywords = [
|
||||
"pyo3",
|
||||
"python",
|
||||
"cpython",
|
||||
"ffi",
|
||||
]
|
||||
categories = [
|
||||
"api-bindings",
|
||||
"development-tools::ffi",
|
||||
]
|
||||
license = "MIT OR Apache-2.0"
|
||||
repository = "https://github.com/pyo3/pyo3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
extension-module = []
|
||||
generate-import-lib = []
|
||||
resolve-config = []
|
||||
|
||||
[lib]
|
||||
name = "pyo3_build_config"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.target-lexicon]
|
||||
version = "0.13.3"
|
||||
|
||||
[build-dependencies.target-lexicon]
|
||||
version = "0.13.3"
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.29.2"
|
||||
description = "Build configuration for the PyO3 ecosystem"
|
||||
authors = ["PyO3 Project and Contributors <https://github.com/PyO3>"]
|
||||
keywords = ["pyo3", "python", "cpython", "ffi"]
|
||||
homepage = "https://github.com/pyo3/pyo3"
|
||||
repository = "https://github.com/pyo3/pyo3"
|
||||
categories = ["api-bindings", "development-tools::ffi"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
edition = "2021"
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
target-lexicon = "0.13.3"
|
||||
|
||||
[build-dependencies]
|
||||
target-lexicon = "0.13.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
# deprecated
|
||||
resolve-config = []
|
||||
extension-module = []
|
||||
generate-import-lib = []
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
Copyright (c) 2017-present PyO3 Project and Contributors. https://github.com/PyO3
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
Vendored
+25
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2023-present PyO3 Project and Contributors. https://github.com/PyO3
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/// A simple macro for returning an error. Resembles anyhow::bail.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! bail {
|
||||
($($args: tt)+) => { return Err(format!($($args)+).into()) };
|
||||
}
|
||||
|
||||
/// A simple macro for checking a condition. Resembles anyhow::ensure.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! ensure {
|
||||
($condition:expr, $($args: tt)+) => { if !($condition) { bail!($($args)+) } };
|
||||
}
|
||||
|
||||
/// Show warning.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! warn {
|
||||
($($args: tt)+) => {
|
||||
println!("{}", $crate::format_warn!($($args)+))
|
||||
};
|
||||
}
|
||||
|
||||
/// Format warning into string.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! format_warn {
|
||||
($($args: tt)+) => {
|
||||
format!("cargo:warning={}", format_args!($($args)+))
|
||||
};
|
||||
}
|
||||
|
||||
/// A simple error implementation which allows chaining of errors, inspired somewhat by anyhow.
|
||||
#[derive(Debug)]
|
||||
pub struct Error {
|
||||
value: String,
|
||||
source: Option<Box<dyn std::error::Error>>,
|
||||
}
|
||||
|
||||
/// Error report inspired by
|
||||
/// <https://blog.rust-lang.org/inside-rust/2021/07/01/What-the-error-handling-project-group-is-working-towards.html#2-error-reporter>
|
||||
pub struct ErrorReport<'a>(&'a Error);
|
||||
|
||||
impl Error {
|
||||
pub fn report(&self) -> ErrorReport<'_> {
|
||||
ErrorReport(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {
|
||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||
self.source.as_deref()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ErrorReport<'_> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use std::error::Error;
|
||||
self.0.fmt(f)?;
|
||||
let mut source = self.0.source();
|
||||
if source.is_some() {
|
||||
writeln!(f, "\ncaused by:")?;
|
||||
let mut index = 0;
|
||||
while let Some(some_source) = source {
|
||||
writeln!(f, " - {index}: {some_source}")?;
|
||||
source = some_source.source();
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Error {
|
||||
fn from(value: String) -> Self {
|
||||
Self {
|
||||
value,
|
||||
source: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&'_ str> for Error {
|
||||
fn from(value: &str) -> Self {
|
||||
value.to_string().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<std::convert::Infallible> for Error {
|
||||
fn from(value: std::convert::Infallible) -> Self {
|
||||
match value {}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
pub trait Context<T> {
|
||||
fn context(self, message: impl Into<String>) -> Result<T>;
|
||||
fn with_context(self, message: impl FnOnce() -> String) -> Result<T>;
|
||||
}
|
||||
|
||||
impl<T, E> Context<T> for Result<T, E>
|
||||
where
|
||||
E: std::error::Error + 'static,
|
||||
{
|
||||
fn context(self, message: impl Into<String>) -> Result<T> {
|
||||
self.map_err(|error| Error {
|
||||
value: message.into(),
|
||||
source: Some(Box::new(error)),
|
||||
})
|
||||
}
|
||||
|
||||
fn with_context(self, message: impl FnOnce() -> String) -> Result<T> {
|
||||
self.map_err(|error| Error {
|
||||
value: message(),
|
||||
source: Some(Box::new(error)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn error_report() {
|
||||
let error: Result<()> = Err(Error::from("there was an internal error"))
|
||||
.with_context(|| format!("failed to do {}", "something difficult"))
|
||||
.context("things went wrong");
|
||||
|
||||
assert_eq!(
|
||||
error
|
||||
.unwrap_err()
|
||||
.report()
|
||||
.to_string()
|
||||
.split('\n')
|
||||
.collect::<Vec<&str>>(),
|
||||
vec![
|
||||
"things went wrong",
|
||||
"caused by:",
|
||||
" - 0: failed to do something difficult",
|
||||
" - 1: there was an internal error",
|
||||
""
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
+4418
File diff suppressed because it is too large.
Load diff
Vendored
+458
@@ -0,0 +1,458 @@
|
||||
//! Configuration used by PyO3 for conditional support of varying Python versions.
|
||||
//!
|
||||
//! This crate exposes functionality to be called from build scripts to simplify building crates
|
||||
//! which depend on PyO3.
|
||||
//!
|
||||
//! It used internally by the PyO3 crate's build script to apply the same configuration.
|
||||
|
||||
#![warn(elided_lifetimes_in_paths, unused_lifetimes)]
|
||||
|
||||
mod errors;
|
||||
mod impl_;
|
||||
|
||||
use std::{env, process::Command, str::FromStr, sync::LazyLock};
|
||||
|
||||
pub use impl_::{
|
||||
cross_compiling_from_to, find_all_sysconfigdata, parse_sysconfigdata, BuildFlag, BuildFlags,
|
||||
CrossCompileConfig, GilUsed, InterpreterConfig, InterpreterConfigBuilder, PythonAbi,
|
||||
PythonAbiBuilder, PythonAbiKind, PythonImplementation, PythonVersion, StableAbi, Triple,
|
||||
};
|
||||
|
||||
use target_lexicon::{Architecture, OperatingSystem};
|
||||
|
||||
/// Adds all the [`#[cfg]` flags](index.html) to the current compilation.
|
||||
///
|
||||
/// This should be called from a build script.
|
||||
///
|
||||
/// The full list of attributes added are the following:
|
||||
///
|
||||
/// | Flag | Description |
|
||||
/// | ---- | ----------- |
|
||||
/// | `#[cfg(Py_3_8)]`, `#[cfg(Py_3_9)]`, `#[cfg(Py_3_10)]`, `#[cfg(Py_3_11)]`, ... | These attributes mark code only for a given Python version and up. For example, `#[cfg(Py_3_8)]` marks code which can run on Python 3.8 **and newer**. There is one attribute for each Python version currently supported by PyO3. |
|
||||
/// | `#[cfg(Py_LIMITED_API)]` | This marks code which is run when compiling with PyO3's `abi3` or abi3t feature enabled. |
|
||||
/// | `#[cfg(Py_GIL_DISABLED)]` | This marks code which is run on the free-threaded interpreter. |
|
||||
/// | `#[cfg(PyPy)]` | This marks code which is run when compiling for PyPy. |
|
||||
/// | `#[cfg(GraalPy)]` | This marks code which is run when compiling for GraalPy. |
|
||||
///
|
||||
/// For examples of how to use these attributes,
|
||||
#[doc = concat!("[see PyO3's guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution/multiple-python-versions.html)")]
|
||||
/// .
|
||||
pub fn use_pyo3_cfgs() {
|
||||
print_expected_cfgs();
|
||||
for cargo_command in get().build_script_outputs() {
|
||||
println!("{cargo_command}")
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds linker arguments suitable for linking an extension module.
|
||||
///
|
||||
/// This should be called from a build script.
|
||||
///
|
||||
/// The following link flags are added:
|
||||
/// - macOS: `-undefined dynamic_lookup`
|
||||
/// - wasm32-unknown-emscripten: for Rust <= 1.95, `-sSIDE_MODULE=2 -sWASM_BIGINT`
|
||||
///
|
||||
/// All other platforms currently are no-ops, however this may change as necessary
|
||||
/// in future.
|
||||
pub fn add_extension_module_link_args() {
|
||||
_add_extension_module_link_args(
|
||||
&impl_::target_triple_from_env(),
|
||||
std::io::stdout(),
|
||||
rustc_minor_version(),
|
||||
)
|
||||
}
|
||||
|
||||
fn _add_extension_module_link_args(
|
||||
triple: &Triple,
|
||||
mut writer: impl std::io::Write,
|
||||
rustc_minor_version: Option<u32>,
|
||||
) {
|
||||
if matches!(triple.operating_system, OperatingSystem::Darwin(_)) {
|
||||
writeln!(writer, "cargo:rustc-cdylib-link-arg=-undefined").unwrap();
|
||||
writeln!(writer, "cargo:rustc-cdylib-link-arg=dynamic_lookup").unwrap();
|
||||
} else if triple == &Triple::from_str("wasm32-unknown-emscripten").unwrap()
|
||||
&& rustc_minor_version.is_some_and(|version| version < 95)
|
||||
{
|
||||
writeln!(writer, "cargo:rustc-cdylib-link-arg=-sSIDE_MODULE=2").unwrap();
|
||||
writeln!(writer, "cargo:rustc-cdylib-link-arg=-sWASM_BIGINT").unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds linker arguments to set rpath when embedding Python within a Rust binary.
|
||||
///
|
||||
/// When running tests or binaries built with PyO3, the Python dynamic library needs
|
||||
/// to be found at runtime.
|
||||
///
|
||||
/// This can be done by setting environment variables like `DYLD_LIBRARY_PATH` on macOS,
|
||||
/// `LD_LIBRARY_PATH` on Linux, or `PATH` on Windows.
|
||||
///
|
||||
/// Altrnatively (as per this function) rpath can be set at link time to point to the
|
||||
/// directory containing the Python dynamic library. This avoids the need to set environment
|
||||
/// variables, so can be convenient, however may not be appropriate for binaries packaged
|
||||
/// for distribution.
|
||||
///
|
||||
#[doc = concat!("[See PyO3's guide](https://pyo3.rs/v", env!("CARGO_PKG_VERSION"), "/building-and-distribution#dynamically-embedding-the-python-interpreter)")]
|
||||
/// for more details.
|
||||
pub fn add_libpython_rpath_link_args() {
|
||||
let target = impl_::target_triple_from_env();
|
||||
pyo3_build_script_impl::print_libpython_rpath_link_args(&target, get());
|
||||
}
|
||||
|
||||
/// Adds linker arguments suitable for linking against the Python framework on macOS.
|
||||
///
|
||||
/// This should be called from a build script.
|
||||
///
|
||||
/// The following link flags are added:
|
||||
/// - macOS: `-Wl,-rpath,<framework_prefix>`
|
||||
///
|
||||
/// All other platforms currently are no-ops.
|
||||
pub fn add_python_framework_link_args() {
|
||||
let target = impl_::target_triple_from_env();
|
||||
_add_python_framework_link_args(
|
||||
get(),
|
||||
&target,
|
||||
impl_::is_linking_libpython_for_target(&target),
|
||||
std::io::stdout(),
|
||||
)
|
||||
}
|
||||
|
||||
fn _add_python_framework_link_args(
|
||||
interpreter_config: &InterpreterConfig,
|
||||
triple: &Triple,
|
||||
link_libpython: bool,
|
||||
mut writer: impl std::io::Write,
|
||||
) {
|
||||
if matches!(triple.operating_system, OperatingSystem::Darwin(_)) && link_libpython {
|
||||
if let Some(framework_prefix) = interpreter_config.python_framework_prefix() {
|
||||
writeln!(writer, "cargo:rustc-link-arg=-Wl,-rpath,{framework_prefix}").unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads the configuration determined from the build environment.
|
||||
///
|
||||
/// This function must be called from a build script, and requires a direct dependency on at
|
||||
/// least one of `pyo3` or `pyo3-ffi`.
|
||||
pub fn get() -> &'static InterpreterConfig {
|
||||
static CONFIG: LazyLock<InterpreterConfig> = LazyLock::new(get_inner);
|
||||
&CONFIG
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn get_inner() -> InterpreterConfig {
|
||||
let Some(interpreter_config) = InterpreterConfig::from_cargo_dep_env() else {
|
||||
panic!("`pyo3_build_config::get()` requires a direct dependency on `pyo3` or `pyo3-ffi`")
|
||||
};
|
||||
interpreter_config.expect("failed to parse PyO3 config")
|
||||
}
|
||||
|
||||
/// Registers `pyo3`s config names as reachable cfg expressions
|
||||
///
|
||||
/// - <https://github.com/rust-lang/cargo/pull/13571>
|
||||
/// - <https://doc.rust-lang.org/nightly/cargo/reference/build-scripts.html#rustc-check-cfg>
|
||||
#[doc(hidden)]
|
||||
pub fn print_expected_cfgs() {
|
||||
println!("cargo:rustc-check-cfg=cfg(Py_LIMITED_API)");
|
||||
println!("cargo:rustc-check-cfg=cfg(Py_GIL_DISABLED)");
|
||||
println!("cargo:rustc-check-cfg=cfg(PyPy)");
|
||||
println!("cargo:rustc-check-cfg=cfg(GraalPy)");
|
||||
println!("cargo:rustc-check-cfg=cfg(RustPython)");
|
||||
println!("cargo:rustc-check-cfg=cfg(py_sys_config, values(\"Py_DEBUG\", \"Py_REF_DEBUG\", \"Py_TRACE_REFS\", \"COUNT_ALLOCS\"))");
|
||||
|
||||
// allow `Py_3_*` cfgs from the minimum supported version up to the
|
||||
// maximum minor version (+1 for development for the next)
|
||||
for i in impl_::MINIMUM_SUPPORTED_VERSION.minor..=impl_::STABLE_ABI_MAX_MINOR + 1 {
|
||||
println!("cargo:rustc-check-cfg=cfg(Py_3_{i})");
|
||||
}
|
||||
}
|
||||
|
||||
/// Private exports used in PyO3's build.rs
|
||||
///
|
||||
/// Please don't use these - they could change at any time.
|
||||
#[doc(hidden)]
|
||||
pub mod pyo3_build_script_impl {
|
||||
use crate::{
|
||||
errors::Result,
|
||||
impl_::{make_cross_compile_config, make_interpreter_config},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
pub mod errors {
|
||||
pub use crate::errors::*;
|
||||
}
|
||||
pub use crate::impl_::{
|
||||
cargo_env_var, env_var, is_linking_libpython_for_target, target_triple_from_env,
|
||||
InterpreterConfig, PythonAbi, PythonAbiKind, PythonVersion, StableAbi,
|
||||
};
|
||||
pub enum BuildConfigSource {
|
||||
/// Config was provided by `PYO3_CONFIG_FILE`.
|
||||
ConfigFile,
|
||||
/// Config was found by an interpreter on the host system.
|
||||
Host,
|
||||
/// Config was configured by cross-compilation settings.
|
||||
CrossCompile,
|
||||
}
|
||||
|
||||
pub struct BuildConfig {
|
||||
pub interpreter_config: InterpreterConfig,
|
||||
pub source: BuildConfigSource,
|
||||
}
|
||||
|
||||
/// Gets the configuration for use from `pyo3-ffi`'s build script.
|
||||
pub fn resolve_build_config(target: &Triple) -> Result<BuildConfig> {
|
||||
#[allow(
|
||||
clippy::const_is_empty,
|
||||
reason = "CONFIG_FILE is generated in build.rs, content can vary"
|
||||
)]
|
||||
if let Some(interpreter_config) =
|
||||
InterpreterConfig::from_pyo3_config_file_env(target).transpose()?
|
||||
{
|
||||
Ok(BuildConfig {
|
||||
interpreter_config,
|
||||
source: BuildConfigSource::ConfigFile,
|
||||
})
|
||||
} else if let Some(interpreter_config) = make_cross_compile_config(target)? {
|
||||
Ok(BuildConfig {
|
||||
interpreter_config,
|
||||
source: BuildConfigSource::CrossCompile,
|
||||
})
|
||||
} else {
|
||||
// No config file, and no cross compile config, so fall back to trying to find an interpreter on the host system.
|
||||
let host_config = make_interpreter_config();
|
||||
Ok(BuildConfig {
|
||||
interpreter_config: host_config?,
|
||||
source: BuildConfigSource::Host,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper to generate an error message when the configured Python version is newer
|
||||
/// than PyO3's current supported version.
|
||||
pub struct MaximumVersionExceeded {
|
||||
message: String,
|
||||
}
|
||||
|
||||
impl MaximumVersionExceeded {
|
||||
pub fn new(
|
||||
interpreter_config: &InterpreterConfig,
|
||||
supported_version: PythonVersion,
|
||||
) -> Self {
|
||||
let implementation = match interpreter_config.target_abi().implementation() {
|
||||
PythonImplementation::CPython => "Python",
|
||||
PythonImplementation::PyPy => "PyPy",
|
||||
PythonImplementation::GraalPy => "GraalPy",
|
||||
PythonImplementation::RustPython => "RustPython",
|
||||
};
|
||||
let version = &interpreter_config.target_abi().version();
|
||||
let message = format!(
|
||||
"the configured {implementation} version ({version}) is newer than PyO3's maximum supported version ({supported_version})\n\
|
||||
= help: this package is being built with PyO3 version {current_version}\n\
|
||||
= help: check https://crates.io/crates/pyo3 for the latest PyO3 version available\n\
|
||||
= help: updating this package to the latest version of PyO3 may provide compatibility with this {implementation} version",
|
||||
current_version = env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
Self { message }
|
||||
}
|
||||
|
||||
pub fn add_help(&mut self, help: &str) {
|
||||
self.message.push_str("\n= help: ");
|
||||
self.message.push_str(help);
|
||||
}
|
||||
|
||||
pub fn finish(self) -> String {
|
||||
self.message
|
||||
}
|
||||
}
|
||||
|
||||
/// Detects features which `pyo3` and `pyo3-ffi` depend upon internally, and prints the appropriate
|
||||
/// `cargo:rustc-cfg` and `cargo:rustc-check-cfg` directives to enable them.
|
||||
pub fn print_feature_cfgs() {
|
||||
print_feature_cfg(84, "const_is_null");
|
||||
print_feature_cfg(85, "fn_ptr_eq");
|
||||
print_feature_cfg(86, "from_bytes_with_nul_error");
|
||||
print_feature_cfg(95, "cfg_select");
|
||||
}
|
||||
|
||||
/// Helper to print a feature cfg with a minimum rust version required.
|
||||
fn print_feature_cfg(minor_version_required: u32, cfg: &str) {
|
||||
println!("cargo:rustc-check-cfg=cfg({cfg})");
|
||||
|
||||
let minor_version = rustc_minor_version().unwrap_or(0);
|
||||
if minor_version >= minor_version_required {
|
||||
println!("cargo:rustc-cfg={cfg}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit libpython rpath link args if appropriate for the target and interpreter config.
|
||||
///
|
||||
/// This form exists for pyo3-ffi where `get()` cannot be called.
|
||||
pub fn print_libpython_rpath_link_args(
|
||||
target: &Triple,
|
||||
interpreter_config: &InterpreterConfig,
|
||||
) {
|
||||
let is_linking_libpython = is_linking_libpython_for_target(target);
|
||||
let is_wasm = matches!(
|
||||
target.architecture,
|
||||
Architecture::Wasm32 | Architecture::Wasm64
|
||||
);
|
||||
let is_emscripten = target.operating_system == OperatingSystem::Emscripten;
|
||||
let is_cygwin = target.operating_system == OperatingSystem::Cygwin;
|
||||
let is_windows = target.operating_system == OperatingSystem::Windows;
|
||||
// webassembly targets generally don't support rpath, emscripten is the only exception currently aware of:
|
||||
// https://github.com/emscripten-core/emscripten/issues/22126
|
||||
if is_linking_libpython && !is_windows && !is_cygwin && (!is_wasm || is_emscripten) {
|
||||
if let Some(lib_dir) = interpreter_config.lib_dir() {
|
||||
println!("cargo:rustc-link-arg=-Wl,-rpath,{lib_dir}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
static RUSTC_MINOR_VERSION: LazyLock<Option<u32>> = LazyLock::new(|| {
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let output = Command::new(rustc).arg("--version").output().ok()?;
|
||||
let version = core::str::from_utf8(&output.stdout).ok()?;
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
pieces.next()?.parse().ok()
|
||||
});
|
||||
*RUSTC_MINOR_VERSION
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[expect(deprecated, reason = "accessing config directly")]
|
||||
mod tests {
|
||||
use crate::impl_::escape;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn extension_module_link_args() {
|
||||
let mut buf = Vec::new();
|
||||
|
||||
// Does nothing on non-mac
|
||||
_add_extension_module_link_args(
|
||||
&Triple::from_str("x86_64-pc-windows-msvc").unwrap(),
|
||||
&mut buf,
|
||||
None,
|
||||
);
|
||||
assert_eq!(buf, Vec::new());
|
||||
|
||||
_add_extension_module_link_args(
|
||||
&Triple::from_str("x86_64-apple-darwin").unwrap(),
|
||||
&mut buf,
|
||||
None,
|
||||
);
|
||||
assert_eq!(
|
||||
std::str::from_utf8(&buf).unwrap(),
|
||||
"cargo:rustc-cdylib-link-arg=-undefined\n\
|
||||
cargo:rustc-cdylib-link-arg=dynamic_lookup\n"
|
||||
);
|
||||
|
||||
buf.clear();
|
||||
_add_extension_module_link_args(
|
||||
&Triple::from_str("wasm32-unknown-emscripten").unwrap(),
|
||||
&mut buf,
|
||||
Some(94),
|
||||
);
|
||||
assert_eq!(
|
||||
std::str::from_utf8(&buf).unwrap(),
|
||||
"cargo:rustc-cdylib-link-arg=-sSIDE_MODULE=2\n\
|
||||
cargo:rustc-cdylib-link-arg=-sWASM_BIGINT\n"
|
||||
);
|
||||
buf.clear();
|
||||
_add_extension_module_link_args(
|
||||
&Triple::from_str("wasm32-unknown-emscripten").unwrap(),
|
||||
&mut buf,
|
||||
Some(95),
|
||||
);
|
||||
assert_eq!(std::str::from_utf8(&buf).unwrap(), "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn python_framework_link_args() {
|
||||
let mut buf = Vec::new();
|
||||
let implementation = PythonImplementation::CPython;
|
||||
let version = PythonVersion::PY313;
|
||||
let interpreter_config = InterpreterConfigBuilder::new(implementation, version)
|
||||
.python_framework_prefix(
|
||||
"/Applications/Xcode.app/Contents/Developer/Library/Frameworks".to_string(),
|
||||
)
|
||||
.finalize()
|
||||
.unwrap();
|
||||
|
||||
// Does nothing on non-mac
|
||||
_add_python_framework_link_args(
|
||||
&interpreter_config,
|
||||
&Triple::from_str("x86_64-pc-windows-msvc").unwrap(),
|
||||
true,
|
||||
&mut buf,
|
||||
);
|
||||
assert_eq!(buf, Vec::new());
|
||||
|
||||
_add_python_framework_link_args(
|
||||
&interpreter_config,
|
||||
&Triple::from_str("x86_64-apple-darwin").unwrap(),
|
||||
true,
|
||||
&mut buf,
|
||||
);
|
||||
assert_eq!(
|
||||
std::str::from_utf8(&buf).unwrap(),
|
||||
"cargo:rustc-link-arg=-Wl,-rpath,/Applications/Xcode.app/Contents/Developer/Library/Frameworks\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_maximum_version_exceeded_formatting() {
|
||||
let implementation = PythonImplementation::CPython;
|
||||
let version = PythonVersion::PY313;
|
||||
let interpreter_config = InterpreterConfigBuilder::new(implementation, version)
|
||||
.finalize()
|
||||
.unwrap();
|
||||
let mut error = pyo3_build_script_impl::MaximumVersionExceeded::new(
|
||||
&interpreter_config,
|
||||
PythonVersion::PY312,
|
||||
);
|
||||
error.add_help("this is a help message");
|
||||
let error = error.finish();
|
||||
let expected = concat!("\
|
||||
the configured Python version (3.13) is newer than PyO3's maximum supported version (3.12)\n\
|
||||
= help: this package is being built with PyO3 version ", env!("CARGO_PKG_VERSION"), "\n\
|
||||
= help: check https://crates.io/crates/pyo3 for the latest PyO3 version available\n\
|
||||
= help: updating this package to the latest version of PyO3 may provide compatibility with this Python version\n\
|
||||
= help: this is a help message"
|
||||
);
|
||||
assert_eq!(error, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_interpreter_config_from_cargo_env() {
|
||||
// There should be no other tests or config in the environment
|
||||
assert!(InterpreterConfig::from_cargo_dep_env().is_none());
|
||||
|
||||
let interpreter_config =
|
||||
InterpreterConfigBuilder::new(PythonImplementation::CPython, PythonVersion::PY313)
|
||||
.finalize()
|
||||
.unwrap();
|
||||
let mut buf = Vec::new();
|
||||
interpreter_config.to_writer(&mut buf).unwrap();
|
||||
let config_string = escape(&buf);
|
||||
// SAFETY: no other tests use `crate::get()`
|
||||
unsafe { std::env::set_var(InterpreterConfig::PYO3_FFI_CONFIG_ENV_VAR, &config_string) };
|
||||
|
||||
assert_eq!(get_inner(), interpreter_config);
|
||||
|
||||
// Repeat with PyO3 env var
|
||||
// SAFETY: no other tests use `crate::get()`
|
||||
unsafe {
|
||||
std::env::remove_var(InterpreterConfig::PYO3_FFI_CONFIG_ENV_VAR);
|
||||
std::env::set_var(InterpreterConfig::PYO3_CONFIG_ENV_VAR, &config_string)
|
||||
}
|
||||
|
||||
assert_eq!(get_inner(), interpreter_config);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user