Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cpython/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,7 @@ Python/frozen_modules/MANIFEST
# People's custom https://docs.anthropic.com/en/docs/claude-code/memory configs.
/.claude/
CLAUDE.local.md

build-native/
*.wasm
*.cwasm
13 changes: 13 additions & 0 deletions cpython/build_python_native.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -e

SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD="$SRC/build-native"

mkdir -p "$BUILD"
cd "$BUILD"

"$SRC/configure" --prefix="$BUILD/install"
make -j$(nproc 2>/dev/null || sysctl -n hw.ncpu)

echo "native python: $BUILD/python"
159 changes: 159 additions & 0 deletions cpython/build_python_wasm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#!/bin/bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APPS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

# Default LIND_WASM_ROOT to parent directory (layout: lind-wasm/lind-wasm-apps)
if [[ -z "${LIND_WASM_ROOT:-}" ]]; then
LIND_WASM_ROOT="$(cd "$APPS_ROOT/.." && pwd)"
fi
SYSROOT="${LIND_WASM_ROOT}/src/glibc/sysroot"
LINDFS="${LIND_WASM_ROOT}/lindfs"
LIND_BOOT="${LIND_WASM_ROOT}/src/lind-boot/target/debug/lind-boot"
WASM_OPT="${LIND_WASM_ROOT}/tools/binaryen/bin/wasm-opt"

CLANG_BIN="${LIND_WASM_ROOT}/clang+llvm-18.1.8-x86_64-linux-gnu-ubuntu-18.04/bin/clang"

cd $SCRIPT_DIR

# --- Clean Target ---
if [[ "${1:-}" == "clean" ]]; then
echo "=> Cleaning build environment..."

# Clean native and wasm build
rm -rf build-native
rm -rf build-wasm

# 3. Clean WASI placeholder libraries
rm -f "${SYSROOT}/lib/wasm32-wasi/libwasi-emulated-getpid.a"
rm -f "${SYSROOT}/lib/wasm32-wasi/libwasi-emulated-signal.a"
rm -f "${SYSROOT}/lib/wasm32-wasi/libwasi-emulated-process-clocks.a"



# Clean the Lind filesystem installation
# Remove the main library and include directories
sudo rm -rf "$LINDFS/usr/local/lib/python3.14"
sudo rm -rf "$LINDFS/usr/local/include/python3.14"

# Remove the static library
sudo rm -f "$LINDFS/usr/local/lib/libpython3.14.a"

# Remove the pkg-config files
sudo rm -f "$LINDFS/usr/local/lib/pkgconfig/python3.pc"
sudo rm -f "$LINDFS/usr/local/lib/pkgconfig/python-3.14-embed.pc"
sudo rm -f "$LINDFS/usr/local/lib/pkgconfig/python3-embed.pc"
sudo rm -f "$LINDFS/usr/local/lib/pkgconfig/python-3.14.pc"

# Remove the manual pages
sudo rm -f "$LINDFS/usr/local/share/man/man1/python3.1"*

# Remove the executables
sudo rm -f "$LINDFS/usr/local/bin/python3.14"*
sudo rm -f "$LINDFS/usr/local/bin/python3-config"*



echo "=> Clean complete."
exit 0
fi

echo "Starting python build process..."

# build native python if not exist
if [ ! -f "./build-native/python" ]; then
echo "Building native python"
./build_python_native.sh
fi

# create wasi related placeholder library
llvm-ar crs "${SYSROOT}/lib/wasm32-wasi/libwasi-emulated-getpid.a"
llvm-ar crs "${SYSROOT}/lib/wasm32-wasi/libwasi-emulated-signal.a"
llvm-ar crs "${SYSROOT}/lib/wasm32-wasi/libwasi-emulated-process-clocks.a"

mkdir -p build-wasm
cd build-wasm

# run configure if Makefile does not exist
if [ ! -f "Makefile" ]; then
../configure \
--host=wasm32-unknown-wasi \
--build=x86_64-unknown-linux-gnu \
--with-build-python=../build-native/python \
CC="${CLANG_BIN} \
-pthread \
--target=wasm32-unknown-wasi \
--sysroot ${SYSROOT} \
-Wl,--import-memory,--export-memory,--max-memory=67108864,--export=__stack_pointer,--export=__stack_low -D _FILE_OFFSET_BITS=64 -D __USE_LARGEFILE64 -g -O0 -fPIC" \
ac_cv_func_working_mktime=yes \
ac_cv_func_mmap_fixed_mapped=yes \
bash_cv_func_sigsetjmp=no \
ac_cv_func_localeconv=no \
ac_cv_func_uselocale=no \
ac_cv_func_setlocale=no \
ac_cv_func_newlocale=no \
ac_cv_have_chflags=no \
ax_cv_c_float_words_bigendian=no \
ac_cv_file__dev_ptmx=no \
ac_cv_file__dev_ptc=no \
ac_cv_func_memfd_create=no \
ac_cv_func_eventfd=no \
ac_cv_func_timerfd_create=no \
--verbose
fi

# build python
make AR="llvm-ar" ARFLAGS="crs"

# install nescessary files into lind filesystem
sudo make install DESTDIR="${LINDFS}"

# apply wasm-opt
# /home/lind/lind-wasm/tools/binaryen/bin/wasm-opt --epoch-injection --asyncify -O2 --debuginfo python.wasm -o python.wasm
# /home/lind/lind-wasm/src/wasmtime/target/debug/wasmtime compile python.wasm -o python.cwasm

# 6. Apply wasm-opt (best-effort)
###############################################################################
PYTHON_WASM="python.wasm"

if [[ -x "$WASM_OPT" ]]; then
echo "=> running wasm-opt (best-effort)..."
OPT_WASM="python.opt.wasm"
"$WASM_OPT" --epoch-injection --asyncify -O2 --debuginfo \
"$PYTHON_WASM" -o "$OPT_WASM"

# Point the working variable to the optimized binary for the next step
PYTHON_WASM="$OPT_WASM"
else
echo "=> NOTE: wasm-opt not found; skipping optimization step."
fi

# 7. cwasm generation via lind-boot (best-effort)
###############################################################################
if [[ -x "$LIND_BOOT" ]]; then
echo "=> generating cwasm via lind-boot --precompile..."

# Pass the (potentially optimized) Wasm file to lind-boot
if "$LIND_BOOT" --precompile "$PYTHON_WASM"; then

# lind-boot appends .cwasm. If we passed python.opt.wasm, it made python.opt.cwasm.
# We want to strip out the '.opt' so the final file is always python.cwasm.
OPT_CWASM="${PYTHON_WASM%.wasm}.cwasm"
CLEAN_CWASM="${OPT_CWASM/.opt/}"

if [[ "$OPT_CWASM" != "$CLEAN_CWASM" && -f "$OPT_CWASM" ]]; then
mv "$OPT_CWASM" "$CLEAN_CWASM"
fi
echo "=> Successfully generated ${CLEAN_CWASM}"

else
echo "=> WARNING: lind-boot --precompile failed; skipping cwasm generation."
fi
else
echo "=> NOTE: lind-boot not found at '$LIND_BOOT'; skipping cwasm generation."
fi

echo
echo "=> Build complete. Outputs generated in current directory."
ls -lh python*.wasm python*.cwasm 2>/dev/null || true
112 changes: 112 additions & 0 deletions cpython/build_shared_python_wasm.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/bin/bash
set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
APPS_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

if [[ -z "${LIND_WASM_ROOT:-}" ]]; then
LIND_WASM_ROOT="$(cd "$APPS_ROOT/.." && pwd)"
fi

LINDFS_ROOT="${LINDFS_ROOT:-$LIND_WASM_ROOT/lindfs}"

BUILD_WASM="$SCRIPT_DIR/build-wasm"
SYSROOT="$LIND_WASM_ROOT/src/glibc/sysroot"
LIND_BOOT="${LIND_WASM_ROOT}/src/lind-boot/target/debug/lind-boot"

# compile shared libpython
clang \
--target=wasm32-unknown-wasi \
-fPIC \
--sysroot "$SYSROOT" \
-fvisibility=default \
-Wl,--import-memory \
-Wl,--shared-memory \
-Wl,--export-dynamic \
-Wl,--experimental-pic \
-Wl,--unresolved-symbols=import-dynamic \
-Wl,-shared \
-Wl,--whole-archive \
"$BUILD_WASM/libpython3.14.a" \
-Wl,--no-whole-archive \
-g -O0 -o "$BUILD_WASM/libpython3.14.wasm" "$LIND_WASM_ROOT/src/glibc/build/lind_debug.o"

#Apply relocations and copy the shared library to lindfs
mkdir -p "$LINDFS_ROOT/lib"
$LIND_WASM_ROOT/scripts/append_tls_relocs_export.sh $BUILD_WASM/libpython3.14.wasm $LINDFS_ROOT/lib/libpython3.14.so

#compile shared python
clang \
-pthread \
-fPIC \
--target=wasm32-unknown-wasi \
--sysroot "$SYSROOT" \
-Wl,-pie \
-Wl,--import-table \
-Wl,--import-memory \
-Wl,--export-memory \
-Wl,--max-memory=67108864 \
-Wl,--export=__stack_pointer \
-Wl,--export=__stack_low \
-Wl,--allow-undefined \
-Wl,--unresolved-symbols=import-dynamic \
-D _FILE_OFFSET_BITS=64 \
-D __USE_LARGEFILE64 \
-g -O0 \
-z stack-size=16777216 \
-Wl,--initial-memory=41943040 \
-o "$BUILD_WASM/python_shared.wasm" \
"$BUILD_WASM/Programs/python.o" \
"$BUILD_WASM/Modules/_hacl/libHacl_Hash_SHA2.a" \
"$BUILD_WASM/Modules/_hacl/libHacl_Hash_SHA1.a" \
"$BUILD_WASM/Modules/expat/libexpat.a" \
"$BUILD_WASM/Modules/_hacl/libHacl_Hash_MD5.a" \
"$BUILD_WASM/Modules/_hacl/libHacl_Hash_BLAKE2.a" \
"$BUILD_WASM/Modules/_decimal/libmpdec/libmpdec.a" \
"$BUILD_WASM/Modules/_hacl/libHacl_HMAC.a" \
"$BUILD_WASM/Modules/_hacl/libHacl_Hash_SHA3.a" \
-ldl -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks -lpthread -lm

echo "=> Copying python_shared.wasm to lindfs..."
mkdir -p "$LINDFS_ROOT/bin"
cp "$BUILD_WASM/python_shared.wasm" "$LINDFS_ROOT/bin/python.wasm"


# --- Optimization & Precompilation Pipeline ---
echo "=> Running wasm-opt (best-effort)..."
TARGET_WASM="python_shared.wasm"
WASM_OPT="$LIND_WASM_ROOT/tools/binaryen/bin/wasm-opt"
if [[ -x "$WASM_OPT" ]]; then
"$WASM_OPT" --epoch-injection --asyncify -O2 --debuginfo \
"$BUILD_WASM/python_shared.wasm" -o "$BUILD_WASM/python_shared.opt.wasm"

TARGET_WASM="python_shared.opt.wasm"
else
echo "=> NOTE: wasm-opt not found at '$WASM_OPT'; skipping optimization step."
fi


echo "=> Generating cwasm via lind-boot --precompile..."
if [[ -x "$LIND_BOOT" ]]; then
pushd "$BUILD_WASM" > /dev/null

if "$LIND_BOOT" --precompile "$TARGET_WASM"; then
OPT_CWASM="${TARGET_WASM%.wasm}.cwasm"
CLEAN_CWASM="${OPT_CWASM/.opt/}"

if [[ "$OPT_CWASM" != "$CLEAN_CWASM" && -f "$OPT_CWASM" ]]; then
mv "$OPT_CWASM" "$CLEAN_CWASM"
fi

echo "=> Successfully generated $CLEAN_CWASM"
cp "$CLEAN_CWASM" "$LINDFS_ROOT/bin/python.cwasm"
else
echo "=> WARNING: lind-boot --precompile failed."
fi

popd > /dev/null
else
echo "=> NOTE: lind-boot not found at '$LIND_BOOT'; skipping cwasm generation."
fi

echo "=> Shared build and installation complete!"
1 change: 1 addition & 0 deletions cpython/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/home/lind/lind-wasm/src/wasmtime/target/debug/wasmtime run --wasi threads=y --wasi preview2=n --preload env=/lib/libc.so --preload env=/lib/libm.so --preload env=/lib/libpython3.14.so python.wasm pytests/add.py