Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cryptography 42 and rust #1261

Merged
merged 10 commits into from
Oct 17, 2024
1 change: 1 addition & 0 deletions server/pypi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ these can be installed using your distribution. Some of them have special entrie
[here](https://github.com/mzakharo/android-gfortran/releases/tag/r21e). Create a
`fortran` subdirectory in the same directory as this README, and unpack the .bz2 files
into it.
* `rust`: `rustup` must be on the PATH.


## Building a package
Expand Down
29 changes: 27 additions & 2 deletions server/pypi/build-wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def main(self):
normalize_version(self.version))

self.non_python_build_reqs = set()
for name in ["cmake", "fortran"]:
for name in ["cmake", "fortran", "rust"]:
try:
self.meta["requirements"]["build"].remove(name)
except ValueError:
Expand Down Expand Up @@ -611,6 +611,10 @@ def get_common_env_vars(self, env):
env["CPPFLAGS"] = ""
env["LDSHARED"] = f"{env['CC']} -shared"

if exists(f"{self.host_env}/chaquopy/lib/libssl.so"):
# `cryptography` requires this variable.
env["OPENSSL_DIR"] = f"{self.host_env}/chaquopy"

def get_python_env_vars(self, env, pypi_env):
# Adding host_env to PYTHONPATH allows setup.py to import requirements, for
# example to call numpy.get_include().
Expand All @@ -633,7 +637,26 @@ def get_python_env_vars(self, env, pypi_env):

# Overrides sysconfig.get_platform and distutils.util.get_platform.
# TODO: consider replacing this with crossenv.
env["_PYTHON_HOST_PLATFORM"] = f"linux_{ABIS[self.abi].uname_machine}"
env["_PYTHON_HOST_PLATFORM"] = f"linux-{ABIS[self.abi].uname_machine}"

def get_rust_env_vars(self, env):
tool_prefix = ABIS[self.abi].tool_prefix
run(f"rustup target add {tool_prefix}")
env.update({
"RUSTFLAGS": f"-C linker={env['CC']} -L native={self.host_env}/chaquopy/lib",
"CARGO_BUILD_TARGET": tool_prefix,

# Normally PyO3 requires sysconfig modules, which are not currently
# available in the `target` packages for Python 3.12 and older. However,
# since PyO3 0.16.4, it's possible to compile abi3 modules without sysconfig
# modules. This only requires packages to specify the minimum python
# compatibility version via one of the "abi3-py*" features (e.g.
# abi3-py310). Doing this requires the "-L native" flag in RUSTFLAGS above.
# https://pyo3.rs/main/building-and-distribution#building-abi3-extensions-without-a-python-interpreter
"PYO3_NO_PYTHON": "1",
"PYO3_CROSS": "1",
"PYO3_CROSS_PYTHON_VERSION": self.python,
})

@contextmanager
def env_vars(self):
Expand All @@ -649,6 +672,8 @@ def env_vars(self):

if self.needs_python:
self.get_python_env_vars(env, pypi_env)
if "rust" in self.non_python_build_reqs:
self.get_rust_env_vars(env)

env.update({
# TODO: make everything use HOST instead, and remove this.
Expand Down
6 changes: 5 additions & 1 deletion server/pypi/compiler-wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@
valid_dirs = [abspath(f"{dirname(sys.argv[0])}/../..")]

def is_valid(dir, prefix):
if any(commonpath([vd, abspath(dir)]) == vd for vd in valid_dirs):
absdir = abspath(dir)
if (
any(commonpath([vd, absdir]) == vd for vd in valid_dirs)
or (".cargo" in absdir) or (".rustup" in absdir)
):
return True
else:
print(f"Chaquopy: ignored invalid {prefix} directory: {dir!r}", file=sys.stderr)
Expand Down
2 changes: 1 addition & 1 deletion server/pypi/packages/cffi/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package:
name: cffi
version: "1.16.0"
version: "1.17.1"

build:
number: 0
Expand Down
22 changes: 0 additions & 22 deletions server/pypi/packages/cryptography/build-with-static-openssl.sh

This file was deleted.

33 changes: 2 additions & 31 deletions server/pypi/packages/cryptography/meta.yaml
Original file line number Diff line number Diff line change
@@ -1,38 +1,9 @@
package:
name: cryptography
version: "3.4.8"

build:
number: 2
script_env:
- CRYPTOGRAPHY_DONT_BUILD_RUST=1
version: "42.0.8"

requirements:
build:
- cffi 1.15.1
- setuptools-rust 0.11.6
- rust
host:
# This version of cryptography isn't compatible with OpenSSL 3. So to build it for
# Python 3.9 and 3.10, we link it against OpenSSL 1.1.
#
# We don't do this by supplying an OpenSSL 1.1 wheel with a shared library, because
# the Chaquopy runtime (perhaps unnecessarily) loads non-Python libraries using
# RTLD_GLOBAL, which could cause conflicts with the OpenSSL 3 library which Chaquopy
# loads on startup.
#
# Instead, we link against OpenSSL 1.1 statically, as follows:
# * Download an OpenSSL 1.1 build from
# https://github.com/beeware/cpython-android-source-deps/releases.
# * For each combination of Python version and ABI, run build-with-static-openssl.sh
# in this directory.
#
# Although this may cause some of OpenSSL's symbols to be exported by crytography's
# Python modules, that's safe because Python modules are loaded using RTLD_LOCAL. And
# although the GLOBAL/LOCAL distinction is only respected from API level 23, older
# versions wouldn't include earlier libraries in the symbol search order for later
# libraries anyway, unless they were listed in DT_NEEDED.
#
# More information:
# * https://github.com/aosp-mirror/platform_bionic/blob/master/android-changes-for-ndk-developers.md
# * https://github.com/android/ndk/issues/1244
- openssl
16 changes: 16 additions & 0 deletions server/pypi/packages/cryptography/patches/openssl_no_legacy.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
--- src-original/src/rust/src/lib.rs
+++ src/src/rust/src/lib.rs
@@ -45,9 +45,10 @@
// serialization), RC4, Blowfish, IDEA, SEED, etc. These things
// are ugly legacy, but we aren't going to get rid of them
// any time soon.
- let load_legacy = env::var("CRYPTOGRAPHY_OPENSSL_NO_LEGACY")
- .map(|v| v.is_empty() || v == "0")
- .unwrap_or(true);
+
+ // Chaquopy: the legacy provider is not available.
+ let load_legacy = false;
+
let legacy = if load_legacy {
let legacy_result = provider::Provider::load(None, "legacy");
_legacy_provider_error(legacy_result.is_ok())?;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--- src-original/src/rust/Cargo.toml
+++ src/src/rust/Cargo.toml
@@ -10,7 +10,10 @@
[dependencies]
once_cell = "1"
cfg-if = "1"
-pyo3 = { version = "0.20", features = ["abi3"] }
+
+# Chaquopy: added abi3-py10 - see needs_rust in build-wheel.py.
+pyo3 = { version = "0.20", features = ["abi3", "abi3-py310"] }
+
asn1 = { version = "0.15.5", default-features = false }
cryptography-cffi = { path = "cryptography-cffi" }
cryptography-key-parsing = { path = "cryptography-key-parsing" }