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

Rust/PyO3 proof of concept #2081

Closed
wants to merge 10 commits into from
Closed
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
6 changes: 6 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,12 @@ jobs:
- -pkg1-v20220303-{{ checksum "Makefile.envs" }}
- -pkg1-v20220303

- run:
name: install rust
command: |
wget https://sh.rustup.rs -O /rustup.sh
sh /rustup.sh -y

- run:
name: build packages
no_output_timeout: 30m
Expand Down
61 changes: 61 additions & 0 deletions emsdk/patches/0001-fix-up-rust-linker-errors.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
From db60466a899dab0c9d008b7ab27f4d4c11fe60da Mon Sep 17 00:00:00 2001
From: Hood Chatham <roberthoodchatham@gmail.com>
Date: Thu, 6 Jan 2022 09:40:39 -0800
Subject: [PATCH] fix up rust linker errors

This fixes a few problems that come up when linking rust programs:
1. Rust .rlib archives contain an extra metadata file called lib.rmeta. The
linker is not happy about these archives. Modifying the archive in place
breaks Cargo. Instead, copy the archive to a temp file, remove lib.rmeta
from the temp file, and link the modified copy.
2. We need to run ranlib on the archive.
3. libcompiler_builtins.rlib contains invalid wasm. I'm not sure why. Nothing
too bad *seems* to go wrong if we just drop it.
---
tools/building.py | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/tools/building.py b/tools/building.py
index 512561c69..8b534e548 100644
--- a/tools/building.py
+++ b/tools/building.py
@@ -464,8 +464,34 @@ def link_lld(args, target, external_symbols=None):
if '--relocatable' not in args and '-r' not in args:
cmd += lld_flags_for_executable(external_symbols)

- cmd = get_command_with_possible_response_file(cmd)
- check_call(cmd)
+ if "EMSCRIPTEN_LINKING_RUST" in os.environ:
+ from tempfile import mkstemp
+ from pathlib import Path
+ tempfiles = []
+ new_cmd = []
+ try:
+ for arg in cmd:
+ if arg == "-lc":
+ continue
+ if not arg.endswith(".rlib"):
+ new_cmd.append(arg)
+ continue
+ fd, temp_path = mkstemp()
+ shutil.copy2(arg, temp_path)
+ tempfiles.append(Path(temp_path))
+ subprocess.call(["ar", "-d", temp_path, "lib.rmeta"])
+ subprocess.call(["emranlib", temp_path])
+ new_cmd.append(temp_path)
+ cmd = new_cmd
+ cmd = get_command_with_possible_response_file(cmd)
+ check_call(cmd)
+ finally:
+ for file in tempfiles:
+ file.unlink()
+ else:
+ cmd = get_command_with_possible_response_file(cmd)
+ check_call(cmd)
+


def link_bitcode(args, target, force_archive_contents=False):
--
2.25.1

29 changes: 29 additions & 0 deletions packages/pyo3_samples/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package:
name: pyo3_samples
version: 0.1.0
source:
# url: https://github.com/hoodmane/pyo3_samples/tarball/main
# sha256: 5a402fc5323365cd2fce3379a7a619e6dba28083bf7eed1ec554820c1551dce2
path: src
build:
sharedlibrary: true
script: |
source $HOME/.cargo/env
rustup update nightly
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which features do you need nightly for, last stable release doesn't work?

Copy link
Member Author

@hoodmane hoodmane Jan 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's needed to build the standard library with -Z build-std. Ideally we could figure out how to build the standard library as a separate shared library. I think it's several megabytes big and we will eventually have more than one rust package if we get this working so it'd be better not to duplicate that anyways. But I haven't looked into how to do this.

rustup component add rust-src --toolchain nightly-x86_64-unknown-linux-gnu
export EMSCRIPTEN_LINKING_RUST=1
export RUSTFLAGS="\
-C relocation-model=pic\
-C target-feature=+mutable-globals\
-C link-arg=-s\
-C link-arg=SIDE_MODULE=1\
"
export PYO3_CONFIG_FILE=$PYODIDE_ROOT/packages/pyo3_samples/pyo3_config.ini
cargo +nightly -Z build-std build --target=wasm32-unknown-emscripten --release
echo "hi?"
mkdir -p dist
cp target/wasm32-unknown-emscripten/release/pyo3_samples.wasm dist/pyo3_samples.so

test:
imports:
- pyo3_samples
9 changes: 9 additions & 0 deletions packages/pyo3_samples/pyo3_config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
implementation=CPython
version=3.9
shared=true
abi3=false
lib_name=python3.9
lib_dir=/home/hood/Documents/programming/pyodide/cpython/installs/python-3.9.5/lib/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not used then if it works in CI?

Copy link
Member Author

@hoodmane hoodmane Jan 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently not. I am pretty unclear on which of these are used -- without this file it definitely doesn't work, but some of the entries seem to have no effect. It isn't documented what any of this does.

pointer_width=32
build_flags=WITH_THREAD
suppress_build_script_link_lines=false
Loading