Files
yoga/javascript/CMakeLists.txt
Nick Gerleman b8a0240aaf Build WebAssembly with SINGLE_FILE=1 (#1310)
Summary:
Pull Request resolved: https://github.com/facebook/yoga/pull/1310

Emscripten normally compiles a binary into a `.js` file and a `.wasm` file. The `.js` file contains a shim to load the WebAssembly file for the target platform, along with passing some environment information to the underlying assembly.

Under Node this would use APIs like `fs.readFile` and its WebAssembly APIs to load the binary. In a browser, APIs like `instantiateStreaming` are used to start downloading and compiling the binary at the same time.

This format creates many, many, headaches, and manual bundler configuration. E.g. we must tell Webpack to treat WASM files as auxilary files instead of WebAssembly, cannot use Emscripten's loader directly, and would need to add more variants of the binary, since (or Node polyfills in the browser) `-s ENVIRONMENT='web,node'` emits code that looks like `if (isNode) {require('fs')}`.

This change makes us instead pack the WebAssembly as base64 inline with the JS loader. This adds a size penalty, and means we cannot start async compilation until the entire file is present, but should work out of the box when using different bundlers and configurations, and the size is small enough where it likely makes sense to inline into the bundle anyway.

There is a [proposal for integration of WebAssembly and ES Modules](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration) that Node has experimental support for, and bundlers are veering towards supporting. It is the eventual solution we should target, but does not seem mature enough yet. E.g. WebPack [does not support](https://github.com/webpack/webpack/issues/11893) WebAssembly import objects, and will instead try to import each of the named imports as modules.

Reviewed By: rozele

Differential Revision: D46884398

fbshipit-source-id: a1c93c122c255b913f426bfb6bdb38fd9f9dfd41
2023-06-21 17:18:26 -07:00

75 lines
1.9 KiB
CMake

# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
cmake_minimum_required(VERSION 3.13...3.26)
set(CMAKE_VERBOSE_MAKEFILE on)
project(yoga)
file(GLOB SOURCES CONFIGURE_DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/../yoga/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/../yoga/**/*.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
include_directories(..)
set(CMAKE_CXX_STANDARD 14)
add_compile_definitions(
EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0)
set(COMPILE_OPTIONS
-flto
-fno-exceptions
-fno-rtti
-g0
-Os
"SHELL:-s STRICT=1")
add_compile_options(${COMPILE_OPTIONS})
add_link_options(
${COMPILE_OPTIONS}
--closure 1
--memory-init-file 0
--no-entry
"SHELL:-s ALLOW_MEMORY_GROWTH=1"
"SHELL:-s ASSERTIONS=0"
"SHELL:-s DYNAMIC_EXECUTION=0"
"SHELL:-s ENVIRONMENT='web,node'"
"SHELL:-s EXPORT_NAME='loadYoga'"
"SHELL:-s FETCH_SUPPORT_INDEXEDDB=0"
"SHELL:-s FILESYSTEM=0"
"SHELL:-s MALLOC='emmalloc'"
"SHELL:-s MODULARIZE=1"
"SHELL:-s TEXTDECODER=0")
link_libraries(embind)
add_library(yogaObjLib OBJECT ${SOURCES})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/binaries)
add_executable(asmjs-sync $<TARGET_OBJECTS:yogaObjLib>)
target_link_options(asmjs-sync PUBLIC
"SHELL:-s WASM=0"
"SHELL:-s WASM_ASYNC_COMPILATION=0")
add_executable(asmjs-async $<TARGET_OBJECTS:yogaObjLib>)
target_link_options(asmjs-async PUBLIC
"SHELL:-s WASM=0"
"SHELL:-s WASM_ASYNC_COMPILATION=1")
add_executable(wasm-sync $<TARGET_OBJECTS:yogaObjLib>)
target_link_options(wasm-sync PUBLIC
"SHELL:-s WASM=1"
"SHELL:-s SINGLE_FILE=1"
"SHELL:-s WASM_ASYNC_COMPILATION=0")
add_executable(wasm-async $<TARGET_OBJECTS:yogaObjLib>)
target_link_options(wasm-async PUBLIC
"SHELL:-s WASM=1"
"SHELL:-s SINGLE_FILE=1"
"SHELL:-s WASM_ASYNC_COMPILATION=1")