2fd39a6143
Well yes, as a byproduct of passing emscripten test suite, you can use close-to-upstream emscripten-llvm clang to build native Android binaries. Starting LLVM 15, I stopped building libunwind as the build method no longer works (most likely not supported anymore) and its unknown how much differs from the one shipped in NDK. You can still build native executables by installing ndk-sysroot which includes libunwind. emscripten-llvm will not hard depend on ndk-sysroot as the focus is WebAssembly.
302 lines
11 KiB
Bash
302 lines
11 KiB
Bash
TERMUX_PKG_HOMEPAGE=https://emscripten.org
|
|
TERMUX_PKG_DESCRIPTION="Emscripten: An LLVM-to-WebAssembly Compiler"
|
|
TERMUX_PKG_LICENSE="MIT"
|
|
TERMUX_PKG_MAINTAINER="@truboxl"
|
|
TERMUX_PKG_VERSION=3.1.6
|
|
TERMUX_PKG_SRCURL=https://github.com/emscripten-core/emscripten.git
|
|
TERMUX_PKG_GIT_BRANCH=$TERMUX_PKG_VERSION
|
|
TERMUX_PKG_PLATFORM_INDEPENDENT=true
|
|
TERMUX_PKG_RECOMMENDS="emscripten-llvm, emscripten-binaryen, python, nodejs-lts | nodejs"
|
|
TERMUX_PKG_BUILD_IN_SRC=true
|
|
TERMUX_PKG_HOSTBUILD=true
|
|
TERMUX_PKG_NO_STATICSPLIT=true
|
|
|
|
# remove files according to emsdk/upstream directory after running
|
|
# ./emsdk install latest
|
|
TERMUX_PKG_RM_AFTER_INSTALL="
|
|
opt/emscripten-llvm/bin/clang-check
|
|
opt/emscripten-llvm/bin/clang-cl
|
|
opt/emscripten-llvm/bin/clang-cpp
|
|
opt/emscripten-llvm/bin/clang-extdef-mapping
|
|
opt/emscripten-llvm/bin/clang-format
|
|
opt/emscripten-llvm/bin/clang-func-mapping
|
|
opt/emscripten-llvm/bin/clang-import-test
|
|
opt/emscripten-llvm/bin/clang-linker-wrapper
|
|
opt/emscripten-llvm/bin/clang-nvlink-wrapper
|
|
opt/emscripten-llvm/bin/clang-offload-bundler
|
|
opt/emscripten-llvm/bin/clang-offload-wrapper
|
|
opt/emscripten-llvm/bin/clang-pseudo
|
|
opt/emscripten-llvm/bin/clang-refactor
|
|
opt/emscripten-llvm/bin/clang-rename
|
|
opt/emscripten-llvm/bin/clang-repl
|
|
opt/emscripten-llvm/bin/clang-scan-deps
|
|
opt/emscripten-llvm/bin/diagtool
|
|
opt/emscripten-llvm/bin/git-clang-format
|
|
opt/emscripten-llvm/bin/hmaptool
|
|
opt/emscripten-llvm/bin/ld.lld
|
|
opt/emscripten-llvm/bin/ld64.lld
|
|
opt/emscripten-llvm/bin/ld64.lld.darwin*
|
|
opt/emscripten-llvm/bin/lld-link
|
|
opt/emscripten-llvm/bin/llvm-cov
|
|
opt/emscripten-llvm/bin/llvm-lib
|
|
opt/emscripten-llvm/bin/llvm-ml
|
|
opt/emscripten-llvm/bin/llvm-pdbutil
|
|
opt/emscripten-llvm/bin/llvm-profdata
|
|
opt/emscripten-llvm/bin/llvm-rc
|
|
opt/emscripten-llvm/bin/llvm-strip
|
|
opt/emscripten-llvm/lib/libclang.so*
|
|
opt/emscripten-llvm/share
|
|
opt/emscripten/LICENSE
|
|
"
|
|
|
|
# https://github.com/emscripten-core/emscripten/blob/main/docs/packaging.md
|
|
# https://github.com/archlinux/svntogit-community/tree/packages/emscripten/trunk
|
|
# below generates commit hash for the deps according to emscripten releases
|
|
#RELEASES_TAGS=$(curl -s https://raw.githubusercontent.com/emscripten-core/emsdk/main/emscripten-releases-tags.json)
|
|
#RELEASE_TAG=$(echo $RELEASES_TAGS | python3 -c "import json,sys;print(json.load(sys.stdin)[\"releases\"][\"$TERMUX_PKG_VERSION\"])")
|
|
#DEPS_REVISION=$(curl -s https://chromium.googlesource.com/emscripten-releases/+/$RELEASE_TAG/DEPS?format=text | base64 -d | grep "_revision':" | sed -e "s|'|\"|g")
|
|
#DEPS_JSON=$(echo -e "{\n${DEPS_REVISION}EOL" | sed -e "s|,EOL|\n}|")
|
|
#LLVM_COMMIT=$(echo $DEPS_JSON | python3 -c "import json,sys;print(json.load(sys.stdin)[\"llvm_project_revision\"])")
|
|
#BINARYEN_COMMIT=$(echo $DEPS_JSON | python3 -c "import json,sys;print(json.load(sys.stdin)[\"binaryen_revision\"])")
|
|
#curl -LOC - https://github.com/llvm/llvm-project/archive/$LLVM_COMMIT.tar.gz
|
|
#curl -LOC - https://github.com/WebAssembly/binaryen/archive/$BINARYEN_COMMIT.tar.gz
|
|
#sha256sum $LLVM_COMMIT.tar.gz $BINARYEN_COMMIT.tar.gz
|
|
|
|
# https://github.com/emscripten-core/emscripten/issues/11362
|
|
# can switch to stable LLVM to save space once above is fixed
|
|
LLVM_COMMIT=6eec4835844439ab932515ff4ac857773c639171
|
|
LLVM_TGZ_SHA256=e0b3d8f0b204f477558c0cd76d6ea90eeae6f38e8732c1269db6b4dde0b1ac96
|
|
|
|
# https://github.com/emscripten-core/emscripten/issues/12252
|
|
# upstream says better bundle the right binaryen revision for now
|
|
BINARYEN_COMMIT=11ada63fbb7ba982c92f22fa1fb0e39cebe3f194
|
|
BINARYEN_TGZ_SHA256=4cb55ca73ae252fc8541c05fb049ce0a265ad615e62697e368de7337f58bcde0
|
|
|
|
# https://github.com/emscripten-core/emsdk/blob/main/emsdk.py
|
|
# https://chromium.googlesource.com/emscripten-releases/+/refs/heads/main/src/build.py
|
|
# https://github.com/llvm/llvm-project
|
|
LLVM_BUILD_ARGS="
|
|
-DCMAKE_BUILD_TYPE=MinSizeRel
|
|
-DCMAKE_CROSSCOMPILING=ON
|
|
-DCMAKE_INSTALL_PREFIX=$TERMUX_PREFIX/opt/emscripten-llvm
|
|
|
|
-DDEFAULT_SYSROOT=$(dirname $TERMUX_PREFIX)
|
|
-DGENERATOR_IS_MULTI_CONFIG=ON
|
|
-DLLVM_ENABLE_ASSERTIONS=ON
|
|
-DLLVM_ENABLE_BINDINGS=OFF
|
|
-DLLVM_ENABLE_LIBEDIT=OFF
|
|
-DLLVM_ENABLE_LIBPFM=OFF
|
|
-DLLVM_ENABLE_LIBXML2=OFF
|
|
-DLLVM_ENABLE_PROJECTS=clang;compiler-rt;lld
|
|
-DLLVM_ENABLE_TERMINFO=OFF
|
|
-DLLVM_INCLUDE_EXAMPLES=OFF
|
|
-DLLVM_INCLUDE_TESTS=OFF
|
|
-DLLVM_INSTALL_TOOLCHAIN_ONLY=ON
|
|
-DLLVM_LINK_LLVM_DYLIB=ON
|
|
-DLLVM_TABLEGEN=$TERMUX_PKG_HOSTBUILD_DIR/bin/llvm-tblgen
|
|
|
|
-DCLANG_DEFAULT_LINKER=lld
|
|
-DCLANG_ENABLE_ARCMT=OFF
|
|
-DCLANG_ENABLE_STATIC_ANALYZER=OFF
|
|
-DCLANG_TABLEGEN=$TERMUX_PKG_HOSTBUILD_DIR/bin/clang-tblgen
|
|
|
|
-DCOMPILER_RT_BUILD_CRT=OFF
|
|
-DCOMPILER_RT_BUILD_LIBFUZZER=OFF
|
|
-DCOMPILER_RT_BUILD_MEMPROF=OFF
|
|
-DCOMPILER_RT_BUILD_PROFILE=OFF
|
|
-DCOMPILER_RT_BUILD_SANITIZERS=OFF
|
|
-DCOMPILER_RT_BUILD_XRAY=OFF
|
|
-DCOMPILER_RT_INCLUDE_TESTS=OFF
|
|
"
|
|
|
|
# https://github.com/WebAssembly/binaryen/blob/main/CMakeLists.txt
|
|
BINARYEN_BUILD_ARGS="
|
|
-DCMAKE_INSTALL_PREFIX=$TERMUX_PREFIX/opt/emscripten-binaryen
|
|
-DENABLE_GTEST=OFF
|
|
"
|
|
|
|
termux_step_post_get_source() {
|
|
termux_download \
|
|
"https://github.com/llvm/llvm-project/archive/$LLVM_COMMIT.tar.gz" \
|
|
"$TERMUX_PKG_CACHEDIR/llvm.tar.gz" \
|
|
"$LLVM_TGZ_SHA256"
|
|
termux_download \
|
|
"https://github.com/WebAssembly/binaryen/archive/$BINARYEN_COMMIT.tar.gz" \
|
|
"$TERMUX_PKG_CACHEDIR/binaryen.tar.gz" \
|
|
"$BINARYEN_TGZ_SHA256"
|
|
tar -xf "$TERMUX_PKG_CACHEDIR/llvm.tar.gz" -C "$TERMUX_PKG_CACHEDIR"
|
|
tar -xf "$TERMUX_PKG_CACHEDIR/binaryen.tar.gz" -C "$TERMUX_PKG_CACHEDIR"
|
|
|
|
cd "$TERMUX_PKG_CACHEDIR/llvm-project-$LLVM_COMMIT"
|
|
for patch in $TERMUX_PKG_BUILDER_DIR/llvm-project-*.patch.diff; do
|
|
patch -p1 -i "$patch"
|
|
done
|
|
|
|
cd "$TERMUX_PKG_CACHEDIR/binaryen-$BINARYEN_COMMIT"
|
|
for patch in $TERMUX_PKG_BUILDER_DIR/binaryen-*.patch.diff; do
|
|
patch -p1 -i "$patch"
|
|
done
|
|
}
|
|
|
|
termux_step_host_build() {
|
|
termux_setup_cmake
|
|
termux_setup_ninja
|
|
|
|
cmake \
|
|
-G Ninja \
|
|
-S "$TERMUX_PKG_CACHEDIR/llvm-project-$LLVM_COMMIT/llvm" \
|
|
-DLLVM_ENABLE_PROJECTS=clang
|
|
cmake \
|
|
--build "$TERMUX_PKG_HOSTBUILD_DIR" \
|
|
-j "$TERMUX_MAKE_PROCESSES" \
|
|
--target llvm-tblgen clang-tblgen
|
|
}
|
|
|
|
termux_step_make() {
|
|
termux_setup_cmake
|
|
termux_setup_ninja
|
|
|
|
# from packages/libllvm/build.sh
|
|
export LLVM_DEFAULT_TARGET_TRIPLE=${CCTERMUX_HOST_PLATFORM/-/-unknown-}
|
|
export LLVM_TARGET_ARCH
|
|
if [ $TERMUX_ARCH = "arm" ]; then
|
|
LLVM_TARGET_ARCH=ARM
|
|
elif [ $TERMUX_ARCH = "aarch64" ]; then
|
|
LLVM_TARGET_ARCH=AArch64
|
|
elif [ $TERMUX_ARCH = "i686" ] || [ $TERMUX_ARCH = "x86_64" ]; then
|
|
LLVM_TARGET_ARCH=X86
|
|
else
|
|
termux_error_exit "Invalid arch: $TERMUX_ARCH"
|
|
fi
|
|
|
|
LLVM_BUILD_ARGS+=" -DLLVM_TARGET_ARCH=$LLVM_TARGET_ARCH"
|
|
LLVM_BUILD_ARGS+=" -DLLVM_TARGETS_TO_BUILD=WebAssembly;$LLVM_TARGET_ARCH"
|
|
LLVM_BUILD_ARGS+=" -DLLVM_HOST_TRIPLE=$LLVM_DEFAULT_TARGET_TRIPLE"
|
|
|
|
cmake \
|
|
-G Ninja \
|
|
-S "$TERMUX_PKG_CACHEDIR/llvm-project-$LLVM_COMMIT/llvm" \
|
|
-B "$TERMUX_PKG_CACHEDIR/build-llvm" \
|
|
$LLVM_BUILD_ARGS
|
|
cmake \
|
|
--build "$TERMUX_PKG_CACHEDIR/build-llvm" \
|
|
-j "$TERMUX_MAKE_PROCESSES" \
|
|
--target install
|
|
|
|
cmake \
|
|
-G Ninja \
|
|
-S "$TERMUX_PKG_CACHEDIR/binaryen-$BINARYEN_COMMIT" \
|
|
-B "$TERMUX_PKG_CACHEDIR/build-binaryen" \
|
|
$BINARYEN_BUILD_ARGS
|
|
cmake \
|
|
--build "$TERMUX_PKG_CACHEDIR/build-binaryen" \
|
|
-j "$TERMUX_MAKE_PROCESSES" \
|
|
--target install
|
|
}
|
|
|
|
termux_step_make_install() {
|
|
# https://github.com/emscripten-core/emscripten/pull/15840
|
|
sed -e "s|-git||" -i "$TERMUX_PKG_SRCDIR/emscripten-version.txt"
|
|
|
|
# skip using Makefile which does host npm install
|
|
rm -fr "$TERMUX_PREFIX/opt/emscripten"
|
|
./tools/install.py "$TERMUX_PREFIX/opt/emscripten"
|
|
|
|
# subpackage optional third party test suite files
|
|
cp -fr "$TERMUX_PKG_SRCDIR/tests/third_party" "$TERMUX_PREFIX/opt/emscripten/tests/third_party"
|
|
|
|
# first run generates .emscripten and exits immediately
|
|
rm -f "$TERMUX_PKG_SRCDIR/.emscripten"
|
|
./emcc --generate-config
|
|
sed -i .emscripten -e "s|^EMSCRIPTEN_ROOT.*|EMSCRIPTEN_ROOT = '$TERMUX_PREFIX/opt/emscripten' # directory|"
|
|
sed -i .emscripten -e "s|^LLVM_ROOT.*|LLVM_ROOT = '$TERMUX_PREFIX/opt/emscripten-llvm/bin' # directory|"
|
|
sed -i .emscripten -e "s|^BINARYEN_ROOT.*|BINARYEN_ROOT = '$TERMUX_PREFIX/opt/emscripten-binaryen' # directory|"
|
|
sed -i .emscripten -e "s|^NODE_JS.*|NODE_JS = '$TERMUX_PREFIX/bin/node' # executable|"
|
|
grep "$TERMUX_PREFIX" "$TERMUX_PKG_SRCDIR/.emscripten"
|
|
install -Dm644 "$TERMUX_PKG_SRCDIR/.emscripten" "$TERMUX_PREFIX/opt/emscripten/.emscripten"
|
|
|
|
# add emscripten directory to PATH var
|
|
cat <<- EOF > "$TERMUX_PKG_TMPDIR/emscripten.sh"
|
|
#!$TERMUX_PREFIX/bin/sh
|
|
export PATH=\$PATH:$TERMUX_PREFIX/opt/emscripten
|
|
EOF
|
|
install -Dm644 "$TERMUX_PKG_TMPDIR/emscripten.sh" "$TERMUX_PREFIX/etc/profile.d/emscripten.sh"
|
|
|
|
# add useful tools not installed by LLVM_INSTALL_TOOLCHAIN_ONLY=ON
|
|
for tool in llc llvm-{addr2line,dwarfdump,dwp,link,mc,nm,objdump,ranlib,readobj,size} opt; do
|
|
install -Dm755 "$TERMUX_PKG_CACHEDIR/build-llvm/bin/$tool" "$TERMUX_PREFIX/opt/emscripten-llvm/bin/$tool"
|
|
done
|
|
|
|
# wasm32 triplets
|
|
ln -fsT "clang" "$TERMUX_PREFIX/opt/emscripten-llvm/bin/wasm32-clang"
|
|
ln -fsT "clang++" "$TERMUX_PREFIX/opt/emscripten-llvm/bin/wasm32-clang++"
|
|
ln -fsT "clang" "$TERMUX_PREFIX/opt/emscripten-llvm/bin/wasm32-wasi-clang"
|
|
ln -fsT "clang++" "$TERMUX_PREFIX/opt/emscripten-llvm/bin/wasm32-wasi-clang++"
|
|
ln -fsT "lld" "$TERMUX_PREFIX/opt/emscripten-llvm/bin/wasm-ld"
|
|
|
|
# unable to determine the reason why different linker searches for
|
|
# libclang_rt.builtins-*-android.a in different paths even after adding
|
|
# the patches from libllvm (also which one is more correct?)
|
|
#
|
|
# binutils LD searches lib/clang/15.0.0/lib/linux (exist)
|
|
# LLVM LD.LLD searches lib/clang/15.0.0/lib/android (not exist)
|
|
ln -fsT "linux" "$TERMUX_PREFIX/opt/emscripten-llvm/lib/clang/15.0.0/lib/android"
|
|
}
|
|
|
|
termux_step_create_debscripts() {
|
|
# emscripten's package-lock.json is generated with nodejs v12.13.0
|
|
# which comes with npm v6 which used lockfile version 1
|
|
# which isn't compatible with lockfile version 2 used in npm v7 and v8
|
|
cat <<- EOF > postinst
|
|
#!$TERMUX_PREFIX/bin/bash
|
|
if [ -n "\$(command -v npm)" ]; then
|
|
cd "$TERMUX_PREFIX/opt/emscripten"
|
|
NPM_VERSION=\$(npm --version)
|
|
NPM_MAJOR_VERSION=\${NPM_VERSION:0:1}
|
|
if [ 6 = \$NPM_MAJOR_VERSION ]; then
|
|
echo 'Running "npm ci --no-optional --production" in $TERMUX_PREFIX/opt/emscripten ...'
|
|
npm ci --no-optional --production
|
|
else
|
|
echo 'Running "npm install --no-optional --production" in $TERMUX_PREFIX/opt/emscripten ...'
|
|
rm package-lock.json
|
|
npm install --no-optional --production
|
|
fi
|
|
else
|
|
echo 'Warning: npm is not installed! Emscripten may not work properly without installing node modules!' >&2
|
|
fi
|
|
echo '
|
|
====================
|
|
Post-install notice:
|
|
If this is the first time installing Emscripten,
|
|
please start a new session to take effect.
|
|
If you are upgrading, you may want to clear the
|
|
cache by running the command below to fix issues.
|
|
|
|
emcc --clear-cache
|
|
|
|
===================='
|
|
EOF
|
|
|
|
cat <<- EOF > postrm
|
|
#!$TERMUX_PREFIX/bin/sh
|
|
case "\$1" in
|
|
purge|remove)
|
|
rm -fr "$TERMUX_PREFIX/opt/emscripten"
|
|
esac
|
|
EOF
|
|
}
|
|
|
|
# Emscripten Test Suite (Optional)
|
|
# Some preparations need to be made in Emscripten directory before running
|
|
# test suite on Android / Termux. Refer docs below:
|
|
# https://emscripten.org/docs/getting_started/test-suite.html
|
|
# https://github.com/emscripten-core/emscripten/pull/13493
|
|
# https://github.com/emscripten-core/emscripten/issues/9098
|
|
#
|
|
# Steps:
|
|
# - pkg install emscripten-tests-third-party ndk-sysroot openjdk-17
|
|
# - cd $PREFIX/opt/emscripten
|
|
# - npm install --no-optional
|
|
# - export EMTEST_SKIP_V8=1
|
|
# - tests/runner {test_name}
|