Skip to content

Commit d985e56

Browse files
committed
Python cross-compiling script and ABI3
Signed-off-by: Yuki Kishimoto <yukikishimoto@protonmail.com>
1 parent 094b4a3 commit d985e56

File tree

6 files changed

+129
-5
lines changed

6 files changed

+129
-5
lines changed

justfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ aar:
4747
jar:
4848
@cd jvm && bash assemble.sh
4949

50+
# Assemble the python wheels
51+
py:
52+
@cd python && bash assemble.sh
53+
5054
# Assemble the C# package
5155
csharp:
5256
@cd csharp && bash assemble.sh
@@ -61,6 +65,11 @@ publish-aar: aar
6165
publish-jar: jar
6266
cd jvm && ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache
6367

68+
# Publish Wheels
69+
[confirm]
70+
publish-py: py
71+
cd python && twine upload dist/*
72+
6473
# Compile and build Swift Package
6574
[macos]
6675
swift:

python/Dockerfile

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FROM python:3.9-slim
2+
3+
# Set up working directory
4+
WORKDIR /build
5+
6+
# Create directories for mounting volumes
7+
RUN mkdir -p python binding binaries dist
8+
9+
# Copy source
10+
COPY src/nostr-sdk/__init__.py python/src/nostr-sdk/
11+
COPY LICENSE python/
12+
COPY MANIFEST.in python/
13+
COPY pyproject.toml python/
14+
COPY README.md python/
15+
COPY requirements.txt python/
16+
COPY setup.py python/
17+
18+
# Copy the build script
19+
COPY --chown=1000:1000 buildwheel.sh .
20+
RUN chmod +x buildwheel.sh
21+
22+
# Install Python build tools
23+
RUN pip install -r python/requirements.txt
24+
25+
# Update permissions
26+
RUN chown -R 1000:1000 /build
27+
RUN chmod -R 777 /build
28+
29+
# Change user
30+
USER 1000
31+
32+
# Set the entrypoint to our build script
33+
ENTRYPOINT ["/build/buildwheel.sh"]

python/assemble.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
set -exuo pipefail
4+
5+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6+
DIST_DIR="${SCRIPT_DIR}/dist"
7+
SRC_DIR="${SCRIPT_DIR}/src/nostr-sdk"
8+
FFI_DIR="${SCRIPT_DIR}/../ffi"
9+
10+
# Clean
11+
rm -rf "${DIST_DIR}"
12+
rm -rf "${SRC_DIR}/*.so"
13+
rm -rf "${SRC_DIR}/nostr_sdk.py"
14+
15+
# Make dir
16+
mkdir -p "${DIST_DIR}"
17+
18+
# Build docker image
19+
docker build -t wheel-builder "${SCRIPT_DIR}"
20+
21+
# Generate bindings
22+
cargo run -p nostr-sdk-ffi --features uniffi-cli --bin uniffi-bindgen generate --library "${FFI_DIR}/apple/macos/x86_64/libnostr_sdk_ffi.dylib" --language python --no-format -o "${SRC_DIR}"
23+
24+
# Build linux wheels
25+
docker run --rm -v "${FFI_DIR}/linux/x86/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="manylinux_2_17_i686" wheel-builder
26+
docker run --rm -v "${FFI_DIR}/linux/x86_64/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="manylinux_2_17_x86_64" wheel-builder
27+
docker run --rm -v "${FFI_DIR}/linux/aarch64/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="manylinux_2_17_aarch64" wheel-builder
28+
29+
# Build macos wheels
30+
docker run --rm -v "${FFI_DIR}/apple/macos/x86_64/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="macosx_11_0_x86_64" wheel-builder
31+
docker run --rm -v "${FFI_DIR}/apple/macos/aarch64/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="macosx_11_0_arm64" wheel-builder
32+
33+
# Build win wheels
34+
docker run --rm -v "${FFI_DIR}/win/x86/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="win32" wheel-builder
35+
docker run --rm -v "${FFI_DIR}/win/x86_64/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="win_amd64" wheel-builder
36+
docker run --rm -v "${FFI_DIR}/win/aarch64/:/build/binaries" -v "${SRC_DIR}:/build/binding" -v "$(pwd)/dist:/build/dist" -e PLAT_NAME="win_arm64" wheel-builder

python/buildwheel.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/bin/bash
2+
3+
# Build a wheel. This script is used from the Dockerfile!
4+
5+
set -exuo pipefail
6+
7+
# Check if required arguments are provided
8+
if [ -z "$PLAT_NAME" ]; then
9+
echo "ERROR: PLAT_NAME environment variable is required"
10+
exit 1
11+
fi
12+
13+
echo "Building wheel for platform: $PLAT_NAME"
14+
15+
ls -l /build/python
16+
17+
# Copy binaries to python directory if they exist
18+
if [ "$(ls -A /build/binaries)" ]; then
19+
cp -r /build/binaries/* /build/python/src/nostr-sdk/
20+
echo "Copied binaries to Python package directory"
21+
else
22+
echo "No binaries found in /build/binaries"
23+
exit 1
24+
fi
25+
26+
# Copy generated binding file to the correct location if it exists
27+
if [ -f "/build/binding/nostr_sdk.py" ]; then
28+
# Make sure the target directory exists
29+
cp /build/binding/nostr_sdk.py /build/python/src/nostr-sdk/
30+
echo "Copied binding file (nostr_sdk.py) to src/nostr-sdk/ directory"
31+
else
32+
echo "WARNING: Binding file (nostr_sdk.py) not found in /build/binding"
33+
exit 1
34+
fi
35+
36+
37+
# Enter Python package directory
38+
cd /build/python
39+
40+
# Build the wheel with Python 3.9 ABI3 compatibility
41+
python setup.py bdist_wheel --plat-name "$PLAT_NAME" --python-tag cp39.abi3
42+
43+
# Copy wheel to the output directory
44+
cp dist/*.whl /build/dist/

python/setup.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,10 @@
2222
# This is required to ensure the library name includes the python version, abi, and platform tags
2323
# See issue #350 for more information
2424
has_ext_modules=lambda: True,
25+
# This enables abi3 compatibility
26+
options={
27+
"bdist_wheel": {
28+
"py_limited_api": "cp39", # Support Python 3.9+
29+
}
30+
},
2531
)

scripts/macos.sh

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
set -exuo pipefail
66

77
CDYLIB="libnostr_sdk_ffi.dylib"
8-
STATIC_LIB="libnostr_sdk_ffi.a"
98
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
109
TARGET_DIR="${SCRIPT_DIR}/../target"
1110
MANIFEST_PATH="${SCRIPT_DIR}/../Cargo.toml"
@@ -38,7 +37,4 @@ cp "${TARGET_DIR}/x86_64-apple-darwin/release/${CDYLIB}" "${FFI_APPLE_DIR}/macos
3837
cp "${TARGET_DIR}/aarch64-apple-darwin/release/${CDYLIB}" "${FFI_APPLE_DIR}/macos/aarch64"
3938
cp "${TARGET_DIR}/universal2-apple-darwin/release/${CDYLIB}" "${FFI_APPLE_DIR}/macos/universal"
4039

41-
# Copy static libraries
42-
cp "${TARGET_DIR}/x86_64-apple-darwin/release/${STATIC_LIB}" "${FFI_APPLE_DIR}/macos/x86_64"
43-
cp "${TARGET_DIR}/aarch64-apple-darwin/release/${STATIC_LIB}" "${FFI_APPLE_DIR}/macos/aarch64"
44-
cp "${TARGET_DIR}/universal2-apple-darwin/release/${STATIC_LIB}" "${FFI_APPLE_DIR}/macos/universal"
40+
# NOTE: if the static lib are required for something, copy them in another directory, not in the same of the dylib!!!

0 commit comments

Comments
 (0)