Open colbyn opened 3 years ago
(But I’m having issues building such.)
What are the issues?
Hey @isuruf, well when I run this:
# FROM ubuntu:18.04
# FROM emscripten/emsdk
FROM emscripten/emsdk:2.0.5
# FROM emscripten/emsdk:1.40.1
RUN apt update -y
# RUN bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
RUN apt install -y \
build-essential \
git \
tree \
cmake \
make \
python3 \
python3-pip \
python3-setuptools \
python3-distutils \
libgmp-dev \
binutils-dev \
vim
RUN git clone https://github.com/symengine/symengine.git
# NOTE: Shouldn’t Emscripten provide this by default?
RUN python3 /emsdk/upstream/emscripten/embuilder.py build boost_headers
# ADD ./wasm/CMakeLists.txt symengine/CMakeLists.txt
# ADD ./wasm/UserOverride.cmake symengine/cmake/UserOverride.cmake
RUN cd symengine && mkdir build
# NOTE:
# -DINTEGER_CLASS:STRING=gmp
# Choose storage type for Integer. one of gmp, gmpxx, flint, piranha, boostmp
RUN cd symengine/build \
&& emcmake cmake \
-DWITH_BF=OFF \
-DWITH_SYMENGINE_ASSER=OFF \
-DWITH_SYMENGINE_RC=ON \
-DWITH_SYMENGINE_THREAD_SAF=OFF \
-DWITH_SYMENGINE_ASSERT=OFF \
-DWITH_EC=OFF \
-DWITH_PRIMESIEV=OFF \
-DWITH_FLIN=OFF \
-DWITH_AR=OFF \
-DWITH_TCMALLO=OFF \
-DWITH_OPENM=OFF \
-DWITH_PIRANH=OFF \
-DWITH_MPF=OFF \
-DWITH_MP=OFF \
-DWITH_LLV=OFF \
-DBUILD_TEST=OFF \
-DBUILD_BENCHMARK=OFF \
-DBUILD_BENCHMARKS_NONIU=OFF \
-DBUILD_BENCHMARKS_GOOGL=OFF \
-DINTEGER_CLASS=boostmp \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_INSTALL_RPATH_USE_LINK_PAT=OFF \
-DBOOST_INCLUDEDIR=/emsdk/upstream/emscripten/cache/ports/boost_headers \
-DBoost_INCLUDE_DIR=/emsdk/upstream/emscripten/cache/ports/boost_headers \
-DDISABLE_EXCEPTION_CATCHING=0 \
-DERROR_ON_UNDEFINED_SYMBOLS=0 \
..
RUN cd symengine/build \
&& emmake make
I get the following error:
#14 0.325 [ 1%] Generating CXX unity source symengine/cotire/symengine_CXX_unity.cxx
#14 0.369 [ 1%] Generating CXX prefix source symengine/cotire/symengine_CXX_prefix.cxx
#14 1.542 [ 2%] Generating CXX prefix header symengine/cotire/symengine_CXX_prefix.hxx
#14 1.574 [ 2%] Building CXX precompiled header symengine/cotire/symengine_CXX_prefix.hxx.pch
#14 6.577 Scanning dependencies of target symengine
#14 6.781 [ 2%] Building CXX object symengine/CMakeFiles/symengine.dir/add.cpp.o
#14 8.027 In file included from /src/symengine/symengine/add.cpp:1:
#14 8.027 In file included from /src/symengine/build/symengine/cotire/symengine_CXX_prefix.hxx:4:
#14 8.027 In file included from /src/symengine/build/symengine/cotire/symengine_CXX_prefix.cxx:14:
#14 8.027 /emsdk/upstream/emscripten/cache/ports/boost_headers/boost/multiprecision/cpp_int.hpp:1236:7: error: static_assert failed due to requirement 'cpp_int_base<0, 4294967295, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, std::__2::allocator<unsigned long long>, false>::internal_limb_count >= 2' "base_type::internal_limb_count >= 2"
#14 8.027 BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
#14 8.027 ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If I remove BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);
, then I run into undefined symbol: sigaltstack
.
I think the issue is with me and not using Emscripten properly.
I don't know if boost::multiprecision supports emscripten. You can try building gmp and use that instead.
@isuruf Okay I got it building 🙂
# FROM ubuntu:18.04
# FROM emscripten/emsdk
# FROM emscripten/emsdk:2.0.5
# FROM emscripten/emsdk:1.40.1
FROM emscripten/emsdk:2.0.15
RUN apt update -y
RUN apt install -y \
build-essential \
git \
tree \
cmake \
make \
python3 \
python3-pip \
python3-setuptools \
python3-distutils \
libgmp-dev \
binutils-dev \
nodejs \
wget \
lzip \
file \
wabt \
vim
# BUILD BOOST:
RUN python3 /emsdk/upstream/emscripten/embuilder.py build boost_headers
# REMOTE THIS ASSERT?
RUN sed --in-place '/ BOOST_STATIC_ASSERT(base_type::internal_limb_count >= 2);/d' /emsdk/upstream/emscripten/cache/ports/boost_headers/boost/multiprecision/cpp_int.hpp
RUN git clone https://github.com/symengine/symengine.git
RUN wget https://gmplib.org/download/gmp/gmp-6.1.2.tar.lz \
&& tar xf gmp-6.1.2.tar.lz \
&& cd gmp-6.1.2 \
&& emconfigure ./configure --disable-assembly --host none --enable-cxx --prefix=${HOME}/opt/gmp \
&& make \
&& make install
# RUST TOOLCHAIN
RUN curl https://sh.rustup.rs -o rustup.sh && sh rustup.sh --default-toolchain stable -y
ENV PATH="$PATH:/root/.cargo/bin"
RUN rustup default stable
# INSTALL WASM-NM TOOL
RUN cargo install wasm-nm
# INIT BUILD DIR
RUN cd symengine && mkdir build
ADD ./wasm/CMakeLists.txt symengine/CMakeLists.txt
ADD ./wasm/symengine/CMakeLists.txt symengine/symengine/CMakeLists.txt
# ADD ./wasm/UserOverride.cmake symengine/cmake/UserOverride.cmake
RUN cd symengine/build \
&& emcmake cmake \
-DWITH_BF=OFF \
-DWITH_SYMENGINE_ASSER=OFF \
-DWITH_SYMENGINE_RC=OFF \
-DWITH_SYMENGINE_THREAD_SAF=OFF \
-DWITH_EC=OFF \
-DWITH_PRIMESIEV=OFF \
-DWITH_FLIN=OFF \
-DWITH_AR=OFF \
-DWITH_TCMALLO=OFF \
-DWITH_OPENM=OFF \
-DWITH_PIRANH=OFF \
-DWITH_MPF=OFF \
-DWITH_MP=OFF \
-DWITH_LLV=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_BENCHMARK=OFF \
-DBUILD_BENCHMARKS=OFF \
-DBUILD_BENCHMARKS_NONIU=OFF \
-DBUILD_BENCHMARKS_GOOGL=OFF \
-DINTEGER_CLASS=gmp \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_RPATH_USE_LINK_PAT=OFF \
-DBOOST_INCLUDEDIR=/emsdk/upstream/emscripten/cache/ports/boost_headers \
-DBoost_INCLUDE_DIR=/emsdk/upstream/emscripten/cache/ports/boost_headers \
-DGMP_LIBRARY=/root/opt/gmp/lib/libgmp.a \
-DGMP_INCLUDE_DIR=/root/opt/gmp/include \
-DDISABLE_EXCEPTION_CATCHING=0 \
-DERROR_ON_UNDEFINED_SYMBOLS=0 \
-DCMAKE_CXX_FLAGS="-s STANDALONE_WASM -s LINKABLE=1 -s EXPORT_ALL=1" \
..
RUN cd symengine/build \
&& emmake make
For some reason, the output is .o
instead of .wasm
. E.g.
$ file ./symengine/CMakeFiles/symengine.dir/cwrapper.cpp.o
./symengine/CMakeFiles/symengine.dir/cwrapper.cpp.o: WebAssembly (wasm) binary module version 0x1 (MVP)
I'm still trying to figure out how to clean things up a bit, and get the linker (I believe) to output explicit WASM files.
@colbyn there's a CMake target property SUFFIX
exactly for that: https://cmake.org/cmake/help/latest/prop_tgt/SUFFIX.html
Though webassembly in CMake isn't super polished yet, and that isn't a problem of symengine's. For now, using the cmake hacks like SUFFIX
should suffice.
This looks interesting! @colbyn did you manage to call the generated wasm?
Perhaps we should create a symengine.wasm
repo with build scripts and perhaps some test code
Building in part on the discussion this thread, I've made progress in getting symengine (the library) and symengine.py to build emscripten binary packages for use with pyodide: https://github.com/materialsgenomefoundation/mgf-dist-pyodide/tree/6c8267a750e602f35f4d0a90821a1ebf5354ab92/packages
The GHA build workflow (based on pyodide's workflow): https://github.com/materialsgenomefoundation/mgf-dist-pyodide/blob/6c8267a750e602f35f4d0a90821a1ebf5354ab92/.github/workflows/main.yaml
Here's a built zip containing a pyodide distribution: https://github.com/materialsgenomefoundation/mgf-dist-pyodide/suites/6132834909/artifacts/213722216 (link will expire in less than 60 days, I'm working on stable artifact generation)
If you extract that zip to a folder, then serve up the root of that folder with python -m http.server 8000
, you can visit http://localhost:8000/console.html
and import symengine
.
Any thoughts on compiling this to web assembly?
Unlike most other CAS implementations that are tried to some high level runtime, this happens to be implemented in a language that -in theory- can target the web VIA e.g. Emscripten.
(Also I kinda wanna experiment with porting this over to Rust VIA an embedded WASM interpreter for the desktop.)
Anyway I started working on a docker file for this:
(But I’m having issues building such.)
Overall, any thoughts on how best to accommodate this (and on reducing dependencies)?