Skip to content

Commit 8add11b

Browse files
committed
Integrate SpiderMonkey build
Instead of relying on the external [spidermonkey-wasi-embedding](https://github.com/bytecodealliance/spidermonkey-wasi-embedding) repo doing debug/release builds of SpiderMonkey as a static library, and StarlingMonkey just pulling those in, with this commit the build is integrated into StarlingMonkey's CMake setup. The build system is still prepared to make use of pre-generated binaries, but right now nothing produces and publishes those. I'll follow this up with more commits adding both caching for CI and publishing of the binaries. Once that's done, hopefully the setup introduced here will just work with them. If not, I'll tweak things accordingly.
1 parent 8c19d16 commit 8add11b

File tree

7 files changed

+215
-18
lines changed

7 files changed

+215
-18
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ include("binaryen")
3232
include("wizer")
3333
include("weval")
3434
include("wasmtime")
35+
include("cbindgen")
3536

3637
include("spidermonkey")
3738
include("openssl")

cmake/cbindgen.cmake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
set(CBINDGEN_VERSION 0.29.0)
2+
3+
# cbindgen doesn't have pre-built binaries for all platforms, so we install it via cargo-binstall. Which we install first, too.
4+
find_program(CARGO_BINSTALL_EXECUTABLE cargo-binstall)
5+
if(NOT CARGO_BINSTALL_EXECUTABLE)
6+
execute_process(
7+
COMMAND curl -L --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh
8+
COMMAND bash
9+
)
10+
endif()
11+
execute_process(
12+
COMMAND cargo binstall -y cbindgen
13+
)

cmake/init-corrosion.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ set(Rust_CARGO_TARGET_LINK_NATIVE_LIBS "")
99
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/rust-toolchain.toml" Rust_TOOLCHAIN REGEX "^channel ?=")
1010
string(REGEX MATCH "[0-9.]+" Rust_TOOLCHAIN "${Rust_TOOLCHAIN}")
1111
execute_process(COMMAND rustup toolchain install ${Rust_TOOLCHAIN})
12-
execute_process(COMMAND rustup target add --toolchain ${Rust_TOOLCHAIN} wasm32-wasi)
12+
execute_process(COMMAND rustup target add --toolchain ${Rust_TOOLCHAIN} wasm32-wasip1)
1313

1414
CPMAddPackage("gh:corrosion-rs/corrosion@0.5.1")
1515
string(TOLOWER ${Rust_CARGO_HOST_ARCH} HOST_ARCH)

cmake/spidermonkey.cmake

Lines changed: 80 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
set(SM_REV b02d76023a15a3fa8c8f54bff5dac91099669003)
1+
set(SM_TAG FIREFOX_140_0_4_RELEASE_STARLING)
22

33
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
44
set(SM_BUILD_TYPE debug)
55
else()
66
set(SM_BUILD_TYPE release)
77
endif()
8-
set(SM_BUILD_TYPE_DASH ${SM_BUILD_TYPE})
98

109
option(WEVAL "Build with a SpiderMonkey variant that supports weval-based AOT compilation" OFF)
1110

1211
if (WEVAL)
13-
set(SM_BUILD_TYPE_DASH "${SM_BUILD_TYPE}-weval")
1412
set(SM_BUILD_TYPE "${SM_BUILD_TYPE}_weval")
1513
endif()
1614

@@ -21,25 +19,92 @@ endif()
2119
# This can be set, for example, to the output directly (`release/` or `debug/`)
2220
# under a local clone of the `spidermonkey-wasi-embedding` repo.
2321
if (DEFINED ENV{SPIDERMONKEY_BINARIES})
24-
set(SM_SOURCE_DIR $ENV{SPIDERMONKEY_BINARIES})
22+
set(SM_LIB_DIR $ENV{SPIDERMONKEY_BINARIES})
23+
message(STATUS "Using pre-built SpiderMonkey artifacts from local directory ${SM_LIB_DIR}")
2524
else()
26-
CPMAddPackage(NAME spidermonkey-${SM_BUILD_TYPE}
27-
URL https://github.com/bytecodealliance/spidermonkey-wasi-embedding/releases/download/rev_${SM_REV}/spidermonkey-wasm-static-lib_${SM_BUILD_TYPE}.tar.gz
28-
DOWNLOAD_ONLY YES
25+
set(SM_URL https://github.com/bytecodealliance/starlingmonkey/releases/download/libspidermonkey_${SM_TAG}/spidermonkey-static-${SM_BUILD_TYPE}.tar.gz)
26+
execute_process(
27+
COMMAND curl -s -o /dev/null -w "%{http_code}" ${SM_URL}
28+
RESULT_VARIABLE CURL_RESULT
29+
OUTPUT_VARIABLE HTTP_STATUS
2930
)
3031

31-
set(SM_SOURCE_DIR ${CPM_PACKAGE_spidermonkey-${SM_BUILD_TYPE}_SOURCE_DIR} CACHE STRING "Path to spidermonkey ${SM_BUILD_TYPE} build" FORCE)
32+
if (CURL_RESULT EQUAL 0 AND HTTP_STATUS STREQUAL "200")
33+
message(STATUS "Using pre-built SpiderMonkey artifacts from ${SM_URL}")
34+
CPMAddPackage(NAME spidermonkey-${SM_BUILD_TYPE}
35+
URL ${SM_URL}
36+
DOWNLOAD_ONLY YES
37+
)
38+
set(SM_LIB_DIR ${CPM_PACKAGE_spidermonkey-${SM_BUILD_TYPE}_SOURCE_DIR} CACHE STRING "Path to spidermonkey ${SM_BUILD_TYPE} build" FORCE)
39+
else()
40+
message(STATUS "No pre-built ${SM_BUILD_TYPE} SpiderMonkey artifacts available for tag ${SM_TAG}. Building from source.")
41+
endif()
3242
endif()
3343

34-
set(SM_INCLUDE_DIR ${SM_SOURCE_DIR}/include)
44+
if (DEFINED SM_LIB_DIR)
45+
set(SM_INCLUDE_DIR ${SM_LIB_DIR}/include)
46+
47+
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/null.cpp "")
48+
file(GLOB SM_OBJS ${SM_LIB_DIR}/lib/*.o)
3549

36-
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/null.cpp "")
37-
file(GLOB SM_OBJS ${SM_SOURCE_DIR}/lib/*.o)
50+
add_library(spidermonkey STATIC)
51+
target_sources(spidermonkey PRIVATE ${SM_OBJS} ${CMAKE_CURRENT_BINARY_DIR}/null.cpp)
52+
target_include_directories(spidermonkey PUBLIC ${SM_INCLUDE_DIR})
53+
target_link_libraries(spidermonkey PUBLIC ${SM_LIB_DIR}/lib/libjs_static.a)
54+
else()
55+
CPMAddPackage(NAME gecko-source
56+
GIT_REPOSITORY "https://github.com/bytecodealliance/firefox.git"
57+
GIT_TAG "${SM_TAG}"
58+
DOWNLOAD_ONLY YES
59+
)
60+
set(SM_SOURCE_DIR ${CPM_PACKAGE_gecko-source_SOURCE_DIR})
61+
set(SM_OBJ_DIR ${CMAKE_CURRENT_BINARY_DIR}/sm-obj-${SM_BUILD_TYPE})
62+
set(SM_INCLUDE_DIR "${SM_OBJ_DIR}/dist/include")
3863

39-
add_library(spidermonkey STATIC)
40-
target_sources(spidermonkey PRIVATE ${SM_OBJS} ${CMAKE_CURRENT_BINARY_DIR}/null.cpp)
41-
target_include_directories(spidermonkey PUBLIC ${SM_INCLUDE_DIR})
42-
target_link_libraries(spidermonkey PUBLIC ${SM_SOURCE_DIR}/lib/libjs_static.a)
64+
# Additional obj files needed, but not part of libjs_static.a
65+
set(SM_OBJ_FILES
66+
memory/build/Unified_cpp_memory_build0.o
67+
memory/mozalloc/Unified_cpp_memory_mozalloc0.o
68+
mfbt/Unified_cpp_mfbt0.o
69+
mfbt/Unified_cpp_mfbt1.o
70+
mozglue/misc/AutoProfilerLabel.o
71+
mozglue/misc/ConditionVariable_noop.o
72+
mozglue/misc/Debug.o
73+
mozglue/misc/Decimal.o
74+
mozglue/misc/MmapFaultHandler.o
75+
mozglue/misc/Mutex_noop.o
76+
mozglue/misc/Now.o
77+
mozglue/misc/Printf.o
78+
mozglue/misc/SIMD.o
79+
mozglue/misc/StackWalk.o
80+
mozglue/misc/TimeStamp.o
81+
mozglue/misc/TimeStamp_posix.o
82+
mozglue/misc/Uptime.o
83+
mozglue/static/lz4.o
84+
mozglue/static/lz4frame.o
85+
mozglue/static/lz4hc.o
86+
mozglue/static/xxhash.o
87+
third_party/fmt/Unified_cpp_third_party_fmt0.o
88+
)
89+
set(SM_OBJS)
90+
foreach(obj_file ${SM_OBJ_FILES})
91+
list(APPEND SM_OBJS ${SM_OBJ_DIR}/${obj_file})
92+
endforeach()
93+
94+
add_custom_command(
95+
OUTPUT ${SM_OBJS} ${SM_OBJ_DIR}/js/src/build/libjs_static.a
96+
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
97+
COMMAND ${CMAKE_COMMAND} -E env WASI_SDK_PATH=${WASI_SDK_PREFIX} SM_SOURCE_DIR=${SM_SOURCE_DIR}
98+
SM_OBJ_DIR=${SM_OBJ_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/scripts/build-spidermonkey.sh ${SM_BUILD_TYPE}
99+
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scripts/build-spidermonkey.sh
100+
VERBATIM
101+
)
102+
add_library(js_static_additional STATIC)
103+
target_sources(js_static_additional PRIVATE ${SM_OBJS} ${CMAKE_CURRENT_BINARY_DIR}/null.cpp)
104+
add_library(spidermonkey INTERFACE)
105+
target_include_directories(spidermonkey INTERFACE ${SM_INCLUDE_DIR})
106+
target_link_libraries(spidermonkey INTERFACE js_static_additional ${SM_OBJ_DIR}/js/src/build/libjs_static.a)
107+
endif()
43108

44109
# SpiderMonkey's builds include a header that defines some configuration options that need to be set
45110
# to ensure e.g. object layout is identical to the one used in the build.

cmake/wasi-sdk.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
set(WASI_SDK_VERSION 25 CACHE STRING "Version of wasi-sdk to use")
1+
set(WASI_SDK_VERSION 25 CACHE STRING "Version of wasi-sdk to use" FORCE)
22

33
set(WASI_SDK_URL "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-${HOST_CPU}-${HOST_OS}.tar.gz")
44
CPMAddPackage(NAME wasi-sdk URL ${WASI_SDK_URL})

rust-toolchain.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[toolchain]
2-
channel = "1.80.0"
2+
channel = "1.88.0"
33
targets = [ "wasm32-wasip1" ]
44
profile = "minimal"

scripts/build-spidermonkey.sh

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
set -x
5+
6+
# If WASI_SDK_PATH is set, use it to set up the compiler environment.
7+
if [[ -n "${WASI_SDK_PATH:-}" ]]; then
8+
export CC="${WASI_SDK_PATH}/bin/clang"
9+
export CXX="${WASI_SDK_PATH}/bin/clang++"
10+
if [[ -z "${HOST_CC:-}" ]]; then
11+
export HOST_CC=$(which clang)
12+
fi
13+
if [[ -z "${HOST_CXX:-}" ]]; then
14+
export HOST_CXX=$(which clang++)
15+
fi
16+
else
17+
# Otherwise, check that all required environment variables are set.
18+
if [[ -z "${WASI_SYSROOT:-}" ]]; then
19+
echo "Error: WASI_SYSROOT environment variable is not set."
20+
exit 1
21+
fi
22+
if [[ -z "${CC:-}" ]]; then
23+
echo "Error: CC environment variable must be set to a clang that can target wasm32-wasip1."
24+
exit 1
25+
fi
26+
if [[ -z "${CXX:-}" ]]; then
27+
echo "Error: CXX environment variable must be set to a clang++ that can target wasm32-wasip1."
28+
exit 1
29+
fi
30+
if [[ -z "${HOST_CC:-}" ]]; then
31+
echo "Error: HOST_CC environment variable is not set."
32+
exit 1
33+
fi
34+
if [[ -z "${HOST_CXX:-}" ]]; then
35+
echo "Error: HOST_CXX environment variable is not set."
36+
exit 1
37+
fi
38+
fi
39+
40+
mode="${1:-release}"
41+
weval=""
42+
if [[ $# -gt 1 ]] && [[ "$2" == "weval" ]]; then
43+
weval=-weval
44+
fi
45+
mozconfig="$(pwd)/mozconfig-${mode}${weval}"
46+
objdir="obj-$mode${weval}"
47+
outdir="$mode${weval}"
48+
49+
cat << EOF > "$mozconfig"
50+
ac_add_options --enable-project=js
51+
ac_add_options --disable-js-shell # Prevents building Rust code, which we need to do ourselves anyway
52+
ac_add_options --target=wasm32-unknown-wasi
53+
ac_add_options --without-system-zlib
54+
ac_add_options --without-intl-api
55+
ac_add_options --disable-jit
56+
ac_add_options --disable-shared-js
57+
ac_add_options --disable-shared-memory
58+
ac_add_options --disable-tests
59+
ac_add_options --disable-clang-plugin
60+
ac_add_options --enable-jitspew
61+
ac_add_options --enable-optimize=-O3
62+
ac_add_options --enable-js-streams
63+
ac_add_options --enable-portable-baseline-interp
64+
ac_add_options --prefix=${SM_OBJ_DIR}/dist
65+
mk_add_options MOZ_OBJDIR=${SM_OBJ_DIR}
66+
mk_add_options AUTOCLOBBER=1
67+
EOF
68+
69+
if [[ -n "${WASI_SYSROOT:-}" ]]; then
70+
echo "ac_add_options --with-sysroot=\"${WASI_SYSROOT}\"" >> "$mozconfig"
71+
fi
72+
73+
target="$(uname)"
74+
case "$target" in
75+
Linux)
76+
echo "ac_add_options --disable-stdcxx-compat" >> "$mozconfig"
77+
platform="linux64-x64"
78+
;;
79+
80+
Darwin)
81+
echo "ac_add_options --host=aarch64-apple-darwin" >> "$mozconfig"
82+
platform="macosx64-aarch64"
83+
;;
84+
85+
*)
86+
echo "Unsupported build target: $target"
87+
exit 1
88+
;;
89+
esac
90+
91+
case "$mode" in
92+
release)
93+
echo "ac_add_options --disable-debug" >> "$mozconfig"
94+
;;
95+
96+
debug)
97+
echo "ac_add_options --enable-debug" >> "$mozconfig"
98+
;;
99+
100+
*)
101+
echo "Unknown build type: $mode"
102+
exit 1
103+
;;
104+
esac
105+
106+
case "$weval" in
107+
-weval)
108+
echo "ac_add_options --enable-portable-baseline-interp-force" >> "$mozconfig"
109+
echo "ac_add_options --enable-aot-ics" >> "$mozconfig"
110+
echo "ac_add_options --enable-aot-ics-force" >> "$mozconfig"
111+
echo "ac_add_options --enable-pbl-weval" >> "$mozconfig"
112+
;;
113+
esac
114+
115+
# Build SpiderMonkey for WASI
116+
MOZCONFIG="${mozconfig}" python3 "${SM_SOURCE_DIR}/mach" --no-interactive build
117+
118+
cp -p "${SM_OBJ_DIR}/js/src/js-confdefs.h" "${SM_OBJ_DIR}/dist/include/"

0 commit comments

Comments
 (0)