diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7f1af8f..b99681f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,42 +12,90 @@ defaults: jobs: build_engine: name: Build Engine - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 + strategy: + matrix: + build_type: [debug, release] + env: + WASI_SDK_VERSION: 25 + BUILD_TYPE: ${{ matrix.build_type }} steps: - uses: actions/checkout@v2 with: submodules: true - name: Cache SpiderMonkey tarball - uses: actions/cache@v2 + uses: actions/cache@v4 id: sm-cache with: path: | dist - key: cache-${{ hashFiles('build-engine.sh') }}-${{ hashFiles('gecko-revision') }}-${{ hashFiles('object-files.list') }} + key: cache-${{ matrix.build_type }}-${{ hashFiles('build-engine.sh') }}-${{ hashFiles('gecko-revision') }}-${{ hashFiles('object-files.list') }} - - name: "Build and bundle SpiderMonkey" + - name: Install dependencies + id: deps if: steps.sm-cache.outputs.cache-hit != 'true' run: | - mkdir dist + mkdir -p dist sudo apt-get update -y + + if ! command -v rustup &> /dev/null; then + echo "Rustup not found, installing..." + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + source $HOME/.cargo/env + fi + rustup target add wasm32-wasip1 + + cargo install cbindgen + + # Download wasi-sdk + sdk_dir_name="wasi-sdk-${WASI_SDK_VERSION}.0-$(uname -m)-linux" + sdk_url=https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/${sdk_dir_name}.tar.gz + curl --location --output wasi-sdk.tar.gz "${sdk_url}" + tar -xf wasi-sdk.tar.gz - bash ./build-engine.sh release - tar -a -cf dist/spidermonkey-wasm-static-lib_release.tar.gz release - rm -rf release obj-release + - name: Clone Gecko + id: clone-gecko + if: steps.sm-cache.outputs.cache-hit != 'true' + run: | + fetch_commits= + if [[ ! -a gecko-dev ]]; then + + # Clone Gecko repository at the required revision + mkdir gecko-dev + + git -C gecko-dev init + git -C gecko-dev remote add --no-tags \ + origin "$(cat "gecko-repository")" + + fetch_commits=1 + fi + + target_rev="$(cat "gecko-revision")" + if [[ -n "$fetch_commits" ]] || \ + [[ "$(git -C gecko-dev rev-parse HEAD)" != "$target_rev" ]]; then + git -C gecko-dev fetch --depth 1 origin "$target_rev" + # Shallow fetching doesn't fetch tags, so we need to check if the target revision + # is a tag name and if so, create a local tag for it. + if ! git rev-parse --verify --quiet "$target_rev" > /dev/null; then + git tag "$target_rev" FETCH_HEAD + fi + git -C gecko-dev checkout FETCH_HEAD + fi - bash ./build-engine.sh release weval - tar -a -cf dist/spidermonkey-wasm-static-lib_release_weval.tar.gz release-weval - rm -rf release-weval obj-release-weval + - name: "Build and bundle SpiderMonkey" + id: build + if: steps.sm-cache.outputs.cache-hit != 'true' + run: | + export WASI_SDK_PATH=$(pwd)/wasi-sdk-${WASI_SDK_VERSION}.0-$(uname -m)-linux - bash ./build-engine.sh debug - tar -a -cf dist/spidermonkey-wasm-static-lib_debug.tar.gz debug - rm -rf debug obj-debug + bash ./build-engine.sh $BUILD_TYPE + tar -a -cf dist/spidermonkey-wasm-static-lib_${BUILD_TYPE}.tar.gz $BUILD_TYPE - name: Calculate tag name run: | - name=rev_$GITHUB_SHA - echo ::set-output name=val::$name + name=rev_$(cat gecko-revision) + echo val=$name >> $GITHUB_OUTPUT echo TAG=$name >> $GITHUB_ENV id: tagname @@ -57,8 +105,8 @@ jobs: uses: actions/upload-artifact@v4 if: github.event_name != 'push' || (github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/tags/v')) with: - name: spidermonkey-wasm-static-lib.zip - path: dist/ + name: spidermonkey-wasm-static-lib-${{ matrix.build_type }}.tar.gz + path: dist/spidermonkey-wasm-static-lib_${{ matrix.build_type }}.tar.gz # ... and if this was an actual push (tag or `main`) then we publish a # new release. This'll automatically publish a tag release or update `dev` diff --git a/build-engine.sh b/build-engine.sh index 1ab0083..f0799dc 100755 --- a/build-engine.sh +++ b/build-engine.sh @@ -3,22 +3,55 @@ set -euo pipefail set -x +# If WASI_SDK_PATH is set, use it to set up the compiler environment. +if [[ -n "${WASI_SDK_PATH:-}" ]]; then + export CC="${WASI_SDK_PATH}/bin/clang" + export CXX="${WASI_SDK_PATH}/bin/clang++" + if [[ -z "${HOST_CC:-}" ]]; then + export HOST_CC=$(which clang) + fi + if [[ -z "${HOST_CXX:-}" ]]; then + export HOST_CXX=$(which clang++) + fi +else + # Otherwise, check that all required environment variables are set. + if [[ -z "${WASI_SYSROOT:-}" ]]; then + echo "Error: WASI_SYSROOT environment variable is not set." + exit 1 + fi + if [[ -z "${CC:-}" ]]; then + echo "Error: CC environment variable must be set to a clang that can target wasm32-wasip1." + exit 1 + fi + if [[ -z "${CXX:-}" ]]; then + echo "Error: CXX environment variable must be set to a clang++ that can target wasm32-wasip1." + exit 1 + fi + if [[ -z "${HOST_CC:-}" ]]; then + echo "Error: HOST_CC environment variable is not set." + exit 1 + fi + if [[ -z "${HOST_CXX:-}" ]]; then + echo "Error: HOST_CXX environment variable is not set." + exit 1 + fi +fi + working_dir="$(pwd)" script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" mode="${1:-release}" weval="" -if [[ $# > 1 ]] && [[ "$2" == "weval" ]]; then +if [[ $# -gt 1 ]] && [[ "$2" == "weval" ]]; then weval=-weval fi mozconfig="${working_dir}/mozconfig-${mode}${weval}" objdir="obj-$mode${weval}" outdir="$mode${weval}" -rebuild="${REBUILD_ENGINE:-0}" cat << EOF > "$mozconfig" ac_add_options --enable-project=js -ac_add_options --enable-application=js +ac_add_options --disable-js-shell # Prevents building Rust code, which we need to do ourselves anyway ac_add_options --target=wasm32-unknown-wasi ac_add_options --without-system-zlib ac_add_options --without-intl-api @@ -36,14 +69,20 @@ mk_add_options MOZ_OBJDIR=${working_dir}/${objdir} mk_add_options AUTOCLOBBER=1 EOF +if [[ -n "${WASI_SYSROOT:-}" ]]; then + echo "ac_add_options --with-sysroot=\"${WASI_SYSROOT}\"" >> "$mozconfig" +fi + target="$(uname)" case "$target" in Linux) echo "ac_add_options --disable-stdcxx-compat" >> "$mozconfig" + platform="linux64-x64" ;; Darwin) echo "ac_add_options --host=aarch64-apple-darwin" >> "$mozconfig" + platform="macosx64-aarch64" ;; *) @@ -76,59 +115,11 @@ case "$weval" in ;; esac -# For a full build (not a rebuild), we need to clone the repo and do some setup work. -# `rebuild.sh` invokes this script with REBUILD_ENGINE=1 which sets rebuild=1 -# and skips this setup. -if [[ $rebuild == 0 ]]; then - # Ensure the Rust version matches that used by Gecko, and can compile to WASI - rustup target add wasm32-wasi - - fetch_commits= - if [[ ! -a gecko-dev ]]; then - - # Clone Gecko repository at the required revision - mkdir gecko-dev - - git -C gecko-dev init - git -C gecko-dev remote add --no-tags -t wasi-embedding \ - origin "$(cat "$script_dir/gecko-repository")" - - fetch_commits=1 - fi - - target_rev="$(cat "$script_dir/gecko-revision")" - if [[ -n "$fetch_commits" ]] || \ - [[ "$(git -C gecko-dev rev-parse HEAD)" != "$target_rev" ]]; then - git -C gecko-dev fetch --depth 1 origin "$target_rev" - git -C gecko-dev checkout FETCH_HEAD - fi - - # Use Gecko's build system bootstrapping to ensure all dependencies are - # installed - cd gecko-dev - ./mach --no-interactive bootstrap --application-choice=js --no-system-changes - - # ... except, that doesn't install the wasi-sysroot, which we need, so we do - # that manually. - cd ~/.mozbuild - python3 \ - "${working_dir}/gecko-dev/mach" \ - --no-interactive \ - artifact \ - toolchain \ - --bootstrap \ - --from-build \ - sysroot-wasm32-wasi -fi - cd "$working_dir" # Build SpiderMonkey for WASI MOZCONFIG="${mozconfig}" \ MOZ_FETCHES_DIR=~/.mozbuild \ -CC=~/.mozbuild/clang/bin/clang \ -CXX=~/.mozbuild/clang/bin/clang++ \ -AR=~/.mozbuild/clang/bin/llvm-ar \ python3 "${working_dir}/gecko-dev/mach" \ --no-interactive \ build @@ -139,9 +130,10 @@ mkdir -p "$outdir/lib" cd "$objdir" cp -Lr dist/include "../$outdir" +cp js/src/js-confdefs.h "../$outdir/include/" while read -r file; do cp "$file" "../$outdir/lib" done < "$script_dir/object-files.list" -cp js/src/build/libjs_static.a "wasm32-wasi/${mode}/libjsrust.a" "../$outdir/lib" +cp js/src/build/libjs_static.a "../$outdir/lib" diff --git a/gecko-repository b/gecko-repository index 0994539..228c12d 100644 --- a/gecko-repository +++ b/gecko-repository @@ -1 +1 @@ -https://github.com/bytecodealliance/gecko-dev \ No newline at end of file +https://github.com/bytecodealliance/firefox diff --git a/gecko-revision b/gecko-revision index 559229f..5870cef 100644 --- a/gecko-revision +++ b/gecko-revision @@ -1 +1 @@ -7acfe5fcdb611518ecc36f5720cb784fdda1ad08 +tags/FIREFOX_140_0_4_RELEASE_STARLING diff --git a/object-files.list b/object-files.list index ca994c1..f5637ca 100644 --- a/object-files.list +++ b/object-files.list @@ -1,18 +1,22 @@ memory/build/Unified_cpp_memory_build0.o memory/mozalloc/Unified_cpp_memory_mozalloc0.o +mfbt/Unified_cpp_mfbt0.o +mfbt/Unified_cpp_mfbt1.o mozglue/misc/AutoProfilerLabel.o mozglue/misc/ConditionVariable_noop.o +mozglue/misc/Debug.o +mozglue/misc/Decimal.o mozglue/misc/MmapFaultHandler.o mozglue/misc/Mutex_noop.o +mozglue/misc/Now.o mozglue/misc/Printf.o +mozglue/misc/SIMD.o mozglue/misc/StackWalk.o mozglue/misc/TimeStamp.o mozglue/misc/TimeStamp_posix.o mozglue/misc/Uptime.o -mozglue/misc/Decimal.o -mfbt/lz4.o -mfbt/lz4frame.o -mfbt/lz4hc.o -mfbt/xxhash.o -mfbt/Unified_cpp_mfbt0.o -mfbt/Unified_cpp_mfbt1.o +mozglue/static/lz4.o +mozglue/static/lz4frame.o +mozglue/static/lz4hc.o +mozglue/static/xxhash.o +third_party/fmt/Unified_cpp_third_party_fmt0.o diff --git a/rust-toolchain.toml b/rust-toolchain.toml index b9901d2..e7a439c 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] -channel = "1.77.1" -targets = [ "wasm32-wasi" ] +channel = "1.88.0" +targets = [ "wasm32-wasip1" ] profile = "minimal"