From 3352385fb02a8171cc8b8b835a36fa6709a56588 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Fri, 23 Dec 2022 00:43:57 -0800 Subject: [PATCH] Move to 4 flavor build and tests --- javascript/.babelrc | 8 --- javascript/.babelrc.js | 17 +++++ javascript/.gitignore | 11 +-- javascript/.hgignore | 15 ---- javascript/CMakeLists.txt | 72 +++++++++++++++++++ javascript/Makefile | 67 ----------------- javascript/jest.config.js | 2 +- javascript/jest.setup.js | 67 +++-------------- javascript/package.json | 30 +++++--- javascript/sources/entry.js | 7 +- javascript/sources/index.asmjs.js | 21 ++++++ javascript/sources/index.wasm.js | 10 ++- javascript/sources/sync.asmjs.js | 17 +++++ .../sources/{index.asm.js => sync.wasm.js} | 6 +- javascript/tests/run-bench.js | 5 +- 15 files changed, 174 insertions(+), 181 deletions(-) delete mode 100644 javascript/.babelrc create mode 100644 javascript/.babelrc.js delete mode 100644 javascript/.hgignore create mode 100644 javascript/CMakeLists.txt delete mode 100644 javascript/Makefile create mode 100644 javascript/sources/index.asmjs.js create mode 100644 javascript/sources/sync.asmjs.js rename javascript/sources/{index.asm.js => sync.wasm.js} (71%) diff --git a/javascript/.babelrc b/javascript/.babelrc deleted file mode 100644 index 2f28ae87..00000000 --- a/javascript/.babelrc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "presets": [ - ["@babel/preset-env", {"targets": "defaults"}] - ], - "plugins": [ - "@babel/plugin-transform-flow-strip-types" - ] -} diff --git a/javascript/.babelrc.js b/javascript/.babelrc.js new file mode 100644 index 00000000..88e0db11 --- /dev/null +++ b/javascript/.babelrc.js @@ -0,0 +1,17 @@ +/** + * 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. + * + * @format + */ + +module.exports = { + "presets": [ + ["@babel/preset-env", {"targets": "defaults"}] + ], + "plugins": [ + "@babel/plugin-transform-flow-strip-types" + ] +}; diff --git a/javascript/.gitignore b/javascript/.gitignore index 2be86e61..29751e5c 100644 --- a/javascript/.gitignore +++ b/javascript/.gitignore @@ -1,10 +1,3 @@ -node_modules - -*.gypi -!/final-flags.gypi - +/build /dist -/build/* -/sources/yoga - -npm-debug.log* +/node_modules diff --git a/javascript/.hgignore b/javascript/.hgignore deleted file mode 100644 index 81e96ec0..00000000 --- a/javascript/.hgignore +++ /dev/null @@ -1,15 +0,0 @@ -syntax:glob - -node_modules - -*.gypi -!/final-flags.gypi - -/dist -/build/* -!/build/Release -/build/Release/* -!/build/Release/nbind.js -/sources/yoga - -npm-debug.log* diff --git a/javascript/CMakeLists.txt b/javascript/CMakeLists.txt new file mode 100644 index 00000000..4cc3f69e --- /dev/null +++ b/javascript/CMakeLists.txt @@ -0,0 +1,72 @@ +# 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) +set(CMAKE_VERBOSE_MAKEFILE on) +project(yoga) + +file(GLOB SOURCES + ../yoga/*.cpp + ../yoga/**/*.cpp + sources/*.cc) + +include_directories(..) + +set(CXX_STANDARD, 11) + +set(EMCC_FLAGS + -flto + -fno-exceptions + -fno-rtti + -g0 + -Os + "SHELL:-s STRICT=1") + +add_compile_options( + ${EMCC_FLAGS} + -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 + -std=c++11) + +add_link_options( + ${EMCC_FLAGS} + --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}/dist) + +add_executable(asmjs-sync $) +target_link_options(asmjs-sync PUBLIC + "SHELL:-s WASM=0" + "SHELL:-s WASM_ASYNC_COMPILATION=0") + +add_executable(asmjs-async $) +target_link_options(asmjs-async PUBLIC + "SHELL:-s WASM=0" + "SHELL:-s WASM_ASYNC_COMPILATION=1") + +add_executable(wasm-sync $) +target_link_options(wasm-sync PUBLIC + "SHELL:-s WASM=1" + "SHELL:-s WASM_ASYNC_COMPILATION=0") + +add_executable(wasm-async $) +target_link_options(wasm-async PUBLIC + "SHELL:-s WASM=1" + "SHELL:-s WASM_ASYNC_COMPILATION=1") diff --git a/javascript/Makefile b/javascript/Makefile deleted file mode 100644 index c74291fa..00000000 --- a/javascript/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -CXX=em++ - -SOURCES=\ - sources/yoga/*.cpp \ - sources/yoga/**/*.cpp \ - sources/*.cc - -CXXFLAGS=\ - -Isources \ - -DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 \ - -std=c++11 \ - -g0 \ - -Os \ - -flto \ - -fno-exceptions \ - -fno-rtti \ - -EMCCFLAGS=\ - --closure 1 \ - --memory-init-file 0 \ - --no-entry - -EMCCOPTS=\ - -s ALLOW_MEMORY_GROWTH=1 \ - -s ASSERTIONS=0 \ - -s DEFAULT_TO_CXX=1 \ - -s DYNAMIC_EXECUTION=0 \ - -s ENVIRONMENT="web,node" \ - -s EXPORT_NAME="yoga" \ - -s FETCH_SUPPORT_INDEXEDDB=0 \ - -s FILESYSTEM=0 \ - -s MALLOC="emmalloc" \ - -s MODULARIZE=1 \ - -s STRICT=1 \ - -s TEXTDECODER=0 \ - -s USE_ES6_IMPORT_META=0 - -LDLIBS=\ - -lembind - -all: clean dir asm wasm - -asm: - $(CXX) $(SOURCES) \ - $(INCLUDE) \ - $(CXXFLAGS) \ - $(EMCCFLAGS) \ - $(LDLIBS) \ - $(EMCCOPTS) \ - -s WASM=0 \ - -o dist/asm.js - -wasm: - $(CXX) $(SOURCES) \ - $(INCLUDE) \ - $(CXXFLAGS) \ - $(EMCCFLAGS) \ - $(LDLIBS) \ - $(EMCCOPTS) \ - -s WASM=1 \ - -o dist/wasm.js - -clean: - rm -rf dist - -dir: - mkdir -p dist diff --git a/javascript/jest.config.js b/javascript/jest.config.js index 8129bc93..2e962810 100644 --- a/javascript/jest.config.js +++ b/javascript/jest.config.js @@ -8,7 +8,7 @@ */ module.exports = { - setupFiles: ["./jest.setup.js"], + setupFiles: ["./jest.setup.js", "./tests/tools.js"], testRegex: '/tests/Facebook.Yoga/.*\\.js$', watchman: false, } diff --git a/javascript/jest.setup.js b/javascript/jest.setup.js index 5ee9275e..85c6582d 100644 --- a/javascript/jest.setup.js +++ b/javascript/jest.setup.js @@ -8,62 +8,13 @@ */ module.exports = async () => { - global.Yoga = process.env['WASM'] - ? await require("./dist/index.wasm").initialize() - : await require("./dist/index.asm").initialize(); - - global.getMeasureCounter = function(Yoga, cb, staticWidth, staticHeight) { - var counter = 0; - - return { - inc: function(width, widthMode, height, heightMode) { - counter += 1; - - return cb - ? cb(width, widthMode, height, heightMode) - : {width: staticWidth, height: staticHeight}; - }, - - get: function() { - return counter; - }, - }; - }; - - global.getMeasureCounterMax = function(Yoga) { - return getMeasureCounter(Yoga, function( - width, - widthMode, - height, - heightMode, - ) { - var measuredWidth = widthMode === Yoga.MEASURE_MODE_UNDEFINED ? 10 : width; - var measuredHeight = - heightMode === Yoga.MEASURE_MODE_UNDEFINED ? 10 : height; - - return {width: measuredWidth, height: measuredHeight}; - }); - }; - - global.getMeasureCounterMin = function(Yoga) { - return getMeasureCounter(Yoga, function( - width, - widthMode, - height, - heightMode, - ) { - var measuredWidth = - widthMode === Yoga.MEASURE_MODE_UNDEFINED || - (widthMode == Yoga.MEASURE_MODE_AT_MOST && width > 10) - ? 10 - : width; - var measuredHeight = - heightMode === Yoga.MEASURE_MODE_UNDEFINED || - (heightMode == Yoga.MEASURE_MODE_AT_MOST && height > 10) - ? 10 - : height; - - return {width: measuredWidth, height: measuredHeight}; - }); - }; + if (process.env['SYNC'] && process.env['WASM']) { + global.Yoga = require("./dist/sync.wasm"); + } else if (process.env['SYNC']) { + global.Yoga = require("./dist/sync.asmjs"); + } else if (process.env['WASM']) { + global.Yoga = await require("./dist/index.wasm").load(); + } else { + global.Yoga = await require("./dist/index.asmjs").load(); + } } diff --git a/javascript/package.json b/javascript/package.json index 539534b7..a291941a 100644 --- a/javascript/package.json +++ b/javascript/package.json @@ -11,19 +11,31 @@ ".": { "browser": "./dist/index.wasm.js", "node": "./dist/index.wasm.js", - "react-native": "./dist/index.asm.js", - "default": "./dist/index.asm.js" + "react-native": "./dist/index.asmjs.js", + "default": "./dist/index.asmjs.js" + }, + "./sync": { + "browser": "./dist/sync.asmks.js", + "node": "./dist/sync.wasm.js", + "react-native": "./dist/sync.asmjs.js", + "default": "./dist/sync.asmjs.js" } }, + "files": [ + "dist/**", + "sources/**" + ], "scripts": { - "is-monolithic": "test \"$(basename \"$(pwd)\")\" = javascript", - "copy-sources": "! npm -s run is-monolithic || (rsync -r --checksum --delete ../yoga/ sources/yoga/)", - "build": "npm run copy-sources && make && npm run build:js", - "test": "yarn test:asm && yarn test:wasm", - "test:asm": "jest", + "build": "yarn build:native && yarn build:js", + "build:native": "yarn build:project && cmake --build build", + "build:project": "which ninja && emcmake cmake -S . -B build -G Ninja || emcmake cmake -S . -B build", + "build:js": "babel sources --source-maps --out-dir dist && flow-copy-source sources dist", + "test": "yarn test:asmjs && yarn test:asmjs-sync && yarn test:wasm && yarn test:wasm-sync", + "test:asmjs": "jest", + "test:asmjs-sync": "SYNC=1 jest", "test:wasm": "WASM=1 jest", - "benchmark": "npm run build && node tests/run-bench $(find tests/Benchmarks -name '*.js')", - "build:js": "babel sources --source-maps --out-dir dist && flow-copy-source sources dist" + "test:wasm-sync": "WASM=1 SYNC=1 jest", + "benchmark": "node tests/run-bench $(find tests/Benchmarks -name '*.js')" }, "devDependencies": { "@babel/cli": "^7.20.7", diff --git a/javascript/sources/entry.js b/javascript/sources/entry.js index add4e59a..0b9a3545 100644 --- a/javascript/sources/entry.js +++ b/javascript/sources/entry.js @@ -8,7 +8,6 @@ * @format */ - const CONSTANTS = require('./YGEnums'); import type { Yoga$Edge, @@ -238,7 +237,7 @@ type Yoga = { ...typeof CONSTANTS, }; -function wrapLib(lib: any): Yoga { +module.exports = function wrapLib(lib: any): Yoga { function patch(prototype, name, fn) { let original = prototype[name]; @@ -378,7 +377,3 @@ function wrapLib(lib: any): Yoga { ...CONSTANTS, }; }; - -module.exports = (libPromise: any) => ({ - initialize: () => libPromise.then(wrapLib) -}: YogaConstructor); diff --git a/javascript/sources/index.asmjs.js b/javascript/sources/index.asmjs.js new file mode 100644 index 00000000..ce3710cd --- /dev/null +++ b/javascript/sources/index.asmjs.js @@ -0,0 +1,21 @@ +/** + * 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. + * + * @flow + * @format + */ + +const wrapLib = require('./entry'); +const loadYoga = require('./asmjs-async'); + +module.exports = { + load: () => { + return loadYoga().then(wrapLib); + } +} + +export type * from './YGEnums.js'; +export type * from './entry'; diff --git a/javascript/sources/index.wasm.js b/javascript/sources/index.wasm.js index 19f00053..d218d310 100644 --- a/javascript/sources/index.wasm.js +++ b/javascript/sources/index.wasm.js @@ -8,10 +8,14 @@ * @format */ -const entry = require('./entry'); -const yoga = require('./wasm'); +const wrapLib = require('./entry'); +const loadYoga = require('./wasm-async'); -module.exports = entry(yoga()); +module.exports = { +load: () => { + return loadYoga().then(wrapLib); +} +} export type * from './YGEnums.js'; export type * from './entry'; diff --git a/javascript/sources/sync.asmjs.js b/javascript/sources/sync.asmjs.js new file mode 100644 index 00000000..b967e046 --- /dev/null +++ b/javascript/sources/sync.asmjs.js @@ -0,0 +1,17 @@ +/** + * 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. + * + * @flow + * @format + */ + +const wrapLib = require('./entry'); +const loadYoga = require('./asmjs-sync'); + +module.exports = wrapLib(loadYoga()); + +export type * from './YGEnums.js'; +export type * from './entry'; diff --git a/javascript/sources/index.asm.js b/javascript/sources/sync.wasm.js similarity index 71% rename from javascript/sources/index.asm.js rename to javascript/sources/sync.wasm.js index 6b6eff65..196d7a08 100644 --- a/javascript/sources/index.asm.js +++ b/javascript/sources/sync.wasm.js @@ -8,10 +8,10 @@ * @format */ -const entry = require('./entry'); -const yoga = require('./asm'); +const wrapLib = require('./entry'); +const loadYoga = require('./wasm-sync'); -module.exports = entry(yoga()); +module.exports = wrapLib(loadYoga()); export type * from './YGEnums.js'; export type * from './entry'; diff --git a/javascript/tests/run-bench.js b/javascript/tests/run-bench.js index cc2946f9..0475b5e0 100644 --- a/javascript/tests/run-bench.js +++ b/javascript/tests/run-bench.js @@ -1,3 +1,4 @@ +#!/usr/bin/env node /** * Copyright (c) Meta Platforms, Inc. and affiliates. * @@ -21,12 +22,12 @@ let testFiles = process.argv.slice(2).map(file => { let testResults = new Map(); -for (let type of ['asm', 'wasm']) { +for (let type of ['asmjs', 'wasm']) { for (let file of testFiles) { vm.runInNewContext( file, Object.assign(Object.create(global), { - Yoga: require(type === 'asm' ? '../dist/index.asm' : '../dist/index.wasm'), + Yoga: require(type === 'asmjs' ? '../dist/sync.asmjs' : '../dist/sync.wasm'), YGBENCHMARK: function(name, fn) { let testEntry = testResults.get(name);