Manage native build toolchain #1506
10
.github/actions/cache-emsdk/action.yml
vendored
Normal file
10
.github/actions/cache-emsdk/action.yml
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
name: Cache the installed copy of emsdk and its build artifacts
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Cache emsdk
|
||||||
|
uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: javascript/.emsdk
|
||||||
|
key: emsdk-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('yarn.lock', 'javascript/package.json', 'javascript/just.config.cjs'}}
|
23
.github/actions/install-emsdk/action.yml
vendored
23
.github/actions/install-emsdk/action.yml
vendored
@@ -1,23 +0,0 @@
|
|||||||
name: Install emsdk (including emcc)
|
|
||||||
inputs:
|
|
||||||
version:
|
|
||||||
description: EMCC Version to install
|
|
||||||
required: false
|
|
||||||
default: 3.1.28
|
|
||||||
|
|
||||||
runs:
|
|
||||||
using: "composite"
|
|
||||||
steps:
|
|
||||||
- name: Clone emsdk repo
|
|
||||||
working-directory: ${{ runner.temp }}
|
|
||||||
shell: bash
|
|
||||||
run: git clone https://github.com/emscripten-core/emsdk.git
|
|
||||||
|
|
||||||
- name: emdsk install
|
|
||||||
working-directory: ${{ runner.temp }}/emsdk
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
./emsdk install ${{ inputs.version }}
|
|
||||||
./emsdk activate ${{ inputs.version }}
|
|
||||||
echo $RUNNER_TEMP/emsdk >> $GITHUB_PATH
|
|
||||||
echo $RUNNER_TEMP/emsdk/upstream/emscripten >> $GITHUB_PATH
|
|
6
.github/actions/setup-js/action.yml
vendored
6
.github/actions/setup-js/action.yml
vendored
@@ -3,12 +3,6 @@ name: Setup JavaScript envirionment
|
|||||||
runs:
|
runs:
|
||||||
using: "composite"
|
using: "composite"
|
||||||
steps:
|
steps:
|
||||||
- name: Install emsdk
|
|
||||||
uses: ./.github/actions/install-emsdk
|
|
||||||
|
|
||||||
- name: Install Ninja
|
|
||||||
uses: ./.github/actions/install-ninja
|
|
||||||
|
|
||||||
- name: Setup Node environment
|
- name: Setup Node environment
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
|
14
.github/workflows/validate-js.yml
vendored
14
.github/workflows/validate-js.yml
vendored
@@ -24,6 +24,9 @@ jobs:
|
|||||||
- name: Setup
|
- name: Setup
|
||||||
uses: ./.github/actions/setup-js
|
uses: ./.github/actions/setup-js
|
||||||
|
|
||||||
|
- name: Restore emsdk
|
||||||
|
uses: ./.github/actions/cache-emsdk
|
||||||
|
|
||||||
- name: yarn benchmark
|
- name: yarn benchmark
|
||||||
run: yarn benchmark
|
run: yarn benchmark
|
||||||
working-directory: javascript
|
working-directory: javascript
|
||||||
@@ -40,8 +43,11 @@ jobs:
|
|||||||
- name: Setup
|
- name: Setup
|
||||||
uses: ./.github/actions/setup-js
|
uses: ./.github/actions/setup-js
|
||||||
|
|
||||||
|
- name: Restore emsdk
|
||||||
|
uses: ./.github/actions/cache-emsdk
|
||||||
|
|
||||||
- name: yarn build
|
- name: yarn build
|
||||||
run: yarn build
|
run: yarn build --verbose
|
||||||
working-directory: javascript
|
working-directory: javascript
|
||||||
|
|
||||||
test:
|
test:
|
||||||
@@ -56,6 +62,9 @@ jobs:
|
|||||||
- name: Setup
|
- name: Setup
|
||||||
uses: ./.github/actions/setup-js
|
uses: ./.github/actions/setup-js
|
||||||
|
|
||||||
|
- name: Restore emsdk
|
||||||
|
uses: ./.github/actions/cache-emsdk
|
||||||
|
|
||||||
- name: yarn test
|
- name: yarn test
|
||||||
run: yarn test
|
run: yarn test
|
||||||
working-directory: javascript
|
working-directory: javascript
|
||||||
@@ -94,6 +103,9 @@ jobs:
|
|||||||
- name: Setup
|
- name: Setup
|
||||||
uses: ./.github/actions/setup-js
|
uses: ./.github/actions/setup-js
|
||||||
|
|
||||||
|
- name: Restore emsdk
|
||||||
|
uses: ./.github/actions/cache-emsdk
|
||||||
|
|
||||||
- name: yarn pack
|
- name: yarn pack
|
||||||
run: yarn pack --filename yoga-layout.tar.gz
|
run: yarn pack --filename yoga-layout.tar.gz
|
||||||
working-directory: javascript
|
working-directory: javascript
|
||||||
|
3
.github/workflows/validate-website.yml
vendored
3
.github/workflows/validate-website.yml
vendored
@@ -34,6 +34,9 @@ jobs:
|
|||||||
- name: Setup
|
- name: Setup
|
||||||
uses: ./.github/actions/setup-js
|
uses: ./.github/actions/setup-js
|
||||||
|
|
||||||
|
- name: Restore emsdk
|
||||||
|
uses: ./.github/actions/cache-emsdk
|
||||||
|
|
||||||
- name: Build Website
|
- name: Build Website
|
||||||
run: yarn build
|
run: yarn build
|
||||||
working-directory: website-next
|
working-directory: website-next
|
||||||
|
1
javascript/.gitignore
vendored
1
javascript/.gitignore
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
/.emsdk
|
||||||
/binaries
|
/binaries
|
||||||
/build
|
/build
|
||||||
/dist
|
/dist
|
||||||
|
@@ -44,7 +44,11 @@ add_link_options(
|
|||||||
"SHELL:-s MODULARIZE=1"
|
"SHELL:-s MODULARIZE=1"
|
||||||
"SHELL:-s EXPORT_ES6=1"
|
"SHELL:-s EXPORT_ES6=1"
|
||||||
"SHELL:-s WASM=1"
|
"SHELL:-s WASM=1"
|
||||||
"SHELL:-s TEXTDECODER=0")
|
"SHELL:-s TEXTDECODER=0"
|
||||||
|
# SINGLE_FILE=1 combined with ENVIRONMENT='web' creates code that works on
|
||||||
|
# both bundlders and Node.
|
||||||
|
"SHELL:-s SINGLE_FILE=1"
|
||||||
|
"SHELL:-s ENVIRONMENT='web'")
|
||||||
|
|
||||||
link_libraries(embind)
|
link_libraries(embind)
|
||||||
|
|
||||||
@@ -52,9 +56,4 @@ add_library(yogaObjLib OBJECT ${SOURCES})
|
|||||||
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/binaries)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/binaries)
|
||||||
|
|
||||||
add_executable(web $<TARGET_OBJECTS:yogaObjLib>)
|
add_executable(yoga-wasm-base64-esm $<TARGET_OBJECTS:yogaObjLib>)
|
||||||
target_link_options(web PRIVATE
|
|
||||||
# SINGLE_FILE=1 combined with ENVIRONMENT='web' creates code that works on
|
|
||||||
# both bundlders and Node.
|
|
||||||
"SHELL:-s SINGLE_FILE=1"
|
|
||||||
"SHELL:-s ENVIRONMENT='web'")
|
|
||||||
|
@@ -20,9 +20,9 @@ const {
|
|||||||
tscTask,
|
tscTask,
|
||||||
} = require('just-scripts');
|
} = require('just-scripts');
|
||||||
|
|
||||||
const {readFile, writeFile} = require('fs/promises');
|
const {existsSync} = require('fs');
|
||||||
|
const {readFile, writeFile, rm} = require('fs/promises');
|
||||||
|
|
||||||
const chalk = require('chalk');
|
|
||||||
const glob = require('glob');
|
const glob = require('glob');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const which = require('which');
|
const which = require('which');
|
||||||
@@ -31,39 +31,26 @@ const node = process.execPath;
|
|||||||
|
|
||||||
option('fix');
|
option('fix');
|
||||||
|
|
||||||
task('clean', cleanTask({paths: ['build', 'dist']}));
|
task('clean', cleanTask({paths: ['.emsdk', 'binaries', 'build']}));
|
||||||
|
|
||||||
function defineFlavor(flavor, env) {
|
task(
|
||||||
task(`cmake-build:${flavor}`, cmakeBuildTask({targets: [flavor]}));
|
'build',
|
||||||
task(
|
series(installEmsdkTask(), emcmakeGenerateTask(), cmakeBuildTask()),
|
||||||
`jest:${flavor}`,
|
);
|
||||||
|
|
||||||
|
task(
|
||||||
|
'test',
|
||||||
|
series(
|
||||||
|
'build',
|
||||||
jestTask({
|
jestTask({
|
||||||
config: path.join(__dirname, 'jest.config.js'),
|
config: path.join(__dirname, 'jest.config.js'),
|
||||||
nodeArgs: ['--experimental-vm-modules'],
|
nodeArgs: ['--experimental-vm-modules'],
|
||||||
env,
|
|
||||||
}),
|
}),
|
||||||
);
|
|
||||||
task(
|
|
||||||
`test:${flavor}`,
|
|
||||||
series(emcmakeGenerateTask(), `cmake-build:${flavor}`, `jest:${flavor}`),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
defineFlavor('web');
|
|
||||||
|
|
||||||
task('build', series(emcmakeGenerateTask(), cmakeBuildTask()));
|
|
||||||
|
|
||||||
task('test', series(emcmakeGenerateTask(), 'cmake-build:web', 'jest:web'));
|
|
||||||
|
|
||||||
task(
|
|
||||||
'benchmark',
|
|
||||||
series(
|
|
||||||
emcmakeGenerateTask(),
|
|
||||||
cmakeBuildTask({targets: ['web']}),
|
|
||||||
runBenchTask(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
task('benchmark', series('build', runBenchTask()));
|
||||||
|
|
||||||
task('clang-format', clangFormatTask({fix: argv().fix}));
|
task('clang-format', clangFormatTask({fix: argv().fix}));
|
||||||
|
|
||||||
task('prepack-package-json', async () => {
|
task('prepack-package-json', async () => {
|
||||||
@@ -133,36 +120,74 @@ function runBenchTask() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function findExecutable(name, failureMessage) {
|
const emsdkVersion = '3.1.28';
|
||||||
const exec = which.sync(name, {nothrow: true});
|
const emsdkPath = path.join(__dirname, '.emsdk');
|
||||||
if (exec) {
|
const emsdkBin = path.join(
|
||||||
return exec;
|
emsdkPath,
|
||||||
}
|
process.platform === 'win32' ? 'emsdk.bat' : 'emsdk',
|
||||||
|
);
|
||||||
|
const emcmakeBin = path.join(
|
||||||
|
emsdkPath,
|
||||||
|
'upstream',
|
||||||
|
'emscripten',
|
||||||
|
process.platform === 'win32' ? 'emcmake.bat' : 'emcmake',
|
||||||
|
);
|
||||||
|
|
||||||
logger.error(chalk.bold.red(failureMessage));
|
function installEmsdkTask() {
|
||||||
process.exit(1);
|
return async () => {
|
||||||
|
if (await isEmsdkReadyAndActivated()) {
|
||||||
|
logger.verbose(
|
||||||
|
`emsdk ${emsdkVersion} is already installed and activated`,
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info(`installing emsdk ${emsdkVersion} to ${emsdkPath}`);
|
||||||
|
await rm(emsdkPath, {recursive: true, force: true});
|
||||||
|
|
||||||
|
await spawn(
|
||||||
|
'git',
|
||||||
|
['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkPath],
|
||||||
|
{stdio: 'inherit'},
|
||||||
|
);
|
||||||
|
|
||||||
|
await spawn(emsdkBin, ['install', emsdkVersion], {stdio: 'inherit'});
|
||||||
|
|
||||||
|
await spawn(emsdkBin, ['activate', emsdkVersion], {
|
||||||
|
stdio: logger.enableVerbose ? 'inherit' : 'ignore',
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function tryFindExecutable(name, failureMessage) {
|
async function isEmsdkReadyAndActivated() {
|
||||||
const exec = which.sync(name, {nothrow: true});
|
if (!existsSync(emcmakeBin)) {
|
||||||
if (exec) {
|
return false;
|
||||||
return exec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn(chalk.bold.yellow(failureMessage));
|
try {
|
||||||
return exec;
|
const emsdkReleases = JSON.parse(
|
||||||
|
await readFile(path.join(emsdkPath, 'emscripten-releases-tags.json')),
|
||||||
|
).releases;
|
||||||
|
|
||||||
|
const versionHash = emsdkReleases[emsdkVersion];
|
||||||
|
if (!versionHash) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const activatedVersion = await readFile(
|
||||||
|
path.join(emsdkPath, 'upstream', '.emsdk_version'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return activatedVersion.toString().includes(versionHash);
|
||||||
|
} catch {
|
||||||
|
// Something is wrong. Pave and redo.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function emcmakeGenerateTask() {
|
function emcmakeGenerateTask() {
|
||||||
return () => {
|
return () => {
|
||||||
const ninja = tryFindExecutable(
|
logger.verbose(`emcmake path: ${emcmakeBin}`);
|
||||||
'ninja',
|
|
||||||
'Warning: Install Ninja (e.g. "brew install ninja") for faster builds',
|
|
||||||
);
|
|
||||||
const emcmake = findExecutable(
|
|
||||||
'emcmake',
|
|
||||||
'Error: Please install the emscripten SDK: https://emscripten.org/docs/getting_started/',
|
|
||||||
);
|
|
||||||
|
|
||||||
const args = [
|
const args = [
|
||||||
'cmake',
|
'cmake',
|
||||||
@@ -170,20 +195,21 @@ function emcmakeGenerateTask() {
|
|||||||
'.',
|
'.',
|
||||||
'-B',
|
'-B',
|
||||||
'build',
|
'build',
|
||||||
...(ninja ? ['-G', 'Ninja'] : []),
|
...(process.platform === 'win32' ? [] : ['-G', 'Ninja']),
|
||||||
];
|
];
|
||||||
logger.info(['emcmake', ...args].join(' '));
|
logger.info(['emcmake', ...args].join(' '));
|
||||||
|
|
||||||
return spawn(emcmake, args, {stdio: 'inherit'});
|
return spawn(emcmakeBin, args, {
|
||||||
|
stdio: logger.enableVerbose ? 'inherit' : 'ignore',
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function cmakeBuildTask(opts) {
|
function cmakeBuildTask(opts) {
|
||||||
return () => {
|
return () => {
|
||||||
const cmake = findExecutable(
|
const cmake = which.sync('cmake');
|
||||||
'cmake',
|
logger.verbose(`cmake path: ${cmake}`);
|
||||||
'Error: Please install CMake (e.g. "brew install cmake")',
|
|
||||||
);
|
|
||||||
const args = [
|
const args = [
|
||||||
'--build',
|
'--build',
|
||||||
'build',
|
'build',
|
||||||
|
@@ -36,11 +36,13 @@
|
|||||||
"@types/jest": "^29.5.1",
|
"@types/jest": "^29.5.1",
|
||||||
"@types/node": "^16.18.25",
|
"@types/node": "^16.18.25",
|
||||||
"@types/which": "^3.0.0",
|
"@types/which": "^3.0.0",
|
||||||
|
"@yogalayout/cmake-bin": "3.28.0-1",
|
||||||
"babel-register-esm": "^1.2.5",
|
"babel-register-esm": "^1.2.5",
|
||||||
"clang-format": "^1.8.0",
|
"clang-format": "^1.8.0",
|
||||||
"glob": "^8.0.3",
|
"glob": "^8.0.3",
|
||||||
"jest": "^29.3.1",
|
"jest": "^29.3.1",
|
||||||
"just-scripts": "^2.1.0",
|
"just-scripts": "^2.1.0",
|
||||||
|
"ninja-binaries": "^1.11.1",
|
||||||
"which": "^3.0.0"
|
"which": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// @ts-ignore untyped from Emscripten
|
// @ts-ignore untyped from Emscripten
|
||||||
import loadYoga from '../binaries/web.js';
|
import loadYoga from '../binaries/yoga-wasm-base64-esm.js';
|
||||||
import wrapAssembly from './wrapAssembly.ts';
|
import wrapAssembly from './wrapAssembly.ts';
|
||||||
|
|
||||||
export type {
|
export type {
|
||||||
|
29
yarn.lock
29
yarn.lock
@@ -2901,6 +2901,30 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
|
||||||
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
|
||||||
|
|
||||||
|
"@yogalayout/cmake-bin-darwin-universal@3.28.0":
|
||||||
|
version "3.28.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@yogalayout/cmake-bin-darwin-universal/-/cmake-bin-darwin-universal-3.28.0.tgz#727e10d62ae4fca960e3502465b68f948841dd6c"
|
||||||
|
integrity sha512-grgtVOaJZT5fCvCaLVbYmVKqsBqtphQffG6WTjDCdyJ++giM4AvrhiRgFKnyr4rx3pj42DrWTvpIWJJl2nBc6w==
|
||||||
|
|
||||||
|
"@yogalayout/cmake-bin-linux-x64@3.28.0":
|
||||||
|
version "3.28.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@yogalayout/cmake-bin-linux-x64/-/cmake-bin-linux-x64-3.28.0.tgz#9bbd414a24a1264a6b8b824c6eb582d623d4ae8e"
|
||||||
|
integrity sha512-RQlsWl1si7+yi87NI2tV13Ca7RYxhjw1AmoULLwhPNkNSLu9Laja2IFvjgvz6iJ3zD9fWSMUl5TwA/ugiNj7OQ==
|
||||||
|
|
||||||
|
"@yogalayout/cmake-bin-windows-x64@3.28.0":
|
||||||
|
version "3.28.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@yogalayout/cmake-bin-windows-x64/-/cmake-bin-windows-x64-3.28.0.tgz#c60787a7148d54fe0d579dcb4fd80d1f7aef56ed"
|
||||||
|
integrity sha512-wMWwUbw/NkXynVRcrFElbFJD/p9HQHmScuv9amZAKMM/JhLjrxDQaivQ+7ZmEOlRQ1uWZjiue9QCkaJERt9Bog==
|
||||||
|
|
||||||
|
"@yogalayout/cmake-bin@3.28.0-1":
|
||||||
|
version "3.28.0-1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@yogalayout/cmake-bin/-/cmake-bin-3.28.0-1.tgz#af366eb6205ec07c1ede2bcec668a2be083869b9"
|
||||||
|
integrity sha512-2bnXhH4qt+bxjm+fgkjTHYhvB2quaS874XkYmUL1Obo6S0kWtDXEp7s0ZgtKvOfW3+y4Q5eomNMIobOeGLi9rw==
|
||||||
|
optionalDependencies:
|
||||||
|
"@yogalayout/cmake-bin-darwin-universal" "3.28.0"
|
||||||
|
"@yogalayout/cmake-bin-linux-x64" "3.28.0"
|
||||||
|
"@yogalayout/cmake-bin-windows-x64" "3.28.0"
|
||||||
|
|
||||||
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
|
accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
|
||||||
version "1.3.8"
|
version "1.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||||
@@ -7823,6 +7847,11 @@ next-tick@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
|
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb"
|
||||||
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
|
integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==
|
||||||
|
|
||||||
|
ninja-binaries@^1.11.1:
|
||||||
|
version "1.11.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ninja-binaries/-/ninja-binaries-1.11.1.tgz#9089191512ab44f990b1ee03792b47f79aedeaaa"
|
||||||
|
integrity sha512-/fjozfApkgrHe2IGbSMhwiDYdz0AUpvsm1szWWu9cy4NJmwPDuhd4mvfFMlCp35CPexHim3jSWn1BjHddxFkkA==
|
||||||
|
|
||||||
no-case@^3.0.4:
|
no-case@^3.0.4:
|
||||||
version "3.0.4"
|
version "3.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
||||||
|
Reference in New Issue
Block a user