Skip to content

Commit

Permalink
attempt wasm fallback on android x64 (#2068)
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Mar 3, 2022
1 parent 8e28f5a commit b690fe8
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 17 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
.DS_Store
.idea/
.vscode/
/bench/
/demo/
/deno/
/esbuild
/github/
/npm/esbuild-android-64/esbuild.wasm
/npm/esbuild-android-64/exit0.js
/npm/esbuild-android-64/wasm_exec.js
/npm/esbuild-wasm/browser.js
/npm/esbuild-wasm/esbuild.wasm
/npm/esbuild-wasm/esm/
Expand All @@ -18,5 +23,3 @@
bin
esbuild.exe
node_modules/
.vscode/
.idea/
21 changes: 17 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ wasm-napi-exit0-windows:

platform-all:
@$(MAKE) --no-print-directory -j4 \
platform-android \
platform-android-arm64 \
platform-darwin \
platform-darwin-arm64 \
Expand Down Expand Up @@ -273,6 +274,9 @@ platform-unixlike: cmd/esbuild/version.go
node scripts/esbuild.js "$(NPMDIR)/package.json" --version
CGO_ENABLED=0 GOOS="$(GOOS)" GOARCH="$(GOARCH)" go build $(GO_FLAGS) -o "$(NPMDIR)/bin/esbuild" ./cmd/esbuild

platform-android: platform-wasm
node scripts/esbuild.js npm/esbuild-android-64/package.json --version

platform-android-arm64:
@$(MAKE) --no-print-directory GOOS=android GOARCH=arm64 NPMDIR=npm/esbuild-android-arm64 platform-unixlike

Expand Down Expand Up @@ -358,7 +362,8 @@ publish-all: check-go-version
@read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \
publish-windows \
publish-windows-32 \
publish-windows-arm64
publish-windows-arm64 \
publish-sunos

@echo Enter one-time password:
@read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \
Expand All @@ -369,10 +374,10 @@ publish-all: check-go-version

@echo Enter one-time password:
@read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \
publish-android \
publish-android-arm64 \
publish-darwin \
publish-darwin-arm64 \
publish-sunos
publish-darwin-arm64

@echo Enter one-time password:
@read OTP && OTP="$$OTP" $(MAKE) --no-print-directory -j4 \
Expand Down Expand Up @@ -406,6 +411,9 @@ publish-windows-32: platform-windows-32
publish-windows-arm64: platform-windows-arm64
test -n "$(OTP)" && cd npm/esbuild-windows-arm64 && npm publish --otp="$(OTP)"

publish-android: platform-android
test -n "$(OTP)" && cd npm/esbuild-android-64 && npm publish --otp="$(OTP)"

publish-android-arm64: platform-android-arm64
test -n "$(OTP)" && cd npm/esbuild-android-arm64 && npm publish --otp="$(OTP)"

Expand Down Expand Up @@ -473,6 +481,8 @@ clean:
rm -f npm/esbuild-windows-32/esbuild.exe
rm -f npm/esbuild-windows-64/esbuild.exe
rm -f npm/esbuild-windows-arm64/esbuild.exe
rm -rf npm/esbuild-android-64/bin
rm -rf npm/esbuild-android-64/esbuild.wasm npm/esbuild-android-64/wasm_exec.js npm/esbuild-android-64/exit0.js
rm -rf npm/esbuild-android-arm64/bin
rm -rf npm/esbuild-darwin-64/bin
rm -rf npm/esbuild-darwin-arm64/bin
Expand All @@ -489,8 +499,11 @@ clean:
rm -rf npm/esbuild-netbsd-64/bin
rm -rf npm/esbuild-openbsd-64/bin
rm -rf npm/esbuild-sunos-64/bin
rm -f npm/esbuild-wasm/esbuild.wasm npm/esbuild-wasm/wasm_exec.js
rm -rf npm/esbuild/bin
rm -f npm/esbuild-wasm/esbuild.wasm npm/esbuild-wasm/wasm_exec.js npm/esbuild-wasm/exit0.js
rm -r npm/esbuild/install.js
rm -rf npm/esbuild/lib
rm -rf npm/esbuild-wasm/esm
rm -rf npm/esbuild-wasm/lib
rm -rf require/*/bench/
rm -rf require/*/demo/
Expand Down
25 changes: 18 additions & 7 deletions lib/npm/node-platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,14 @@ export const knownUnixlikePackages: Record<string, string> = {
'sunos x64 LE': 'esbuild-sunos-64',
};

export function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: string } {
export const knownWebAssemblyFallbackPackages: Record<string, string> = {
'android x64 LE': 'esbuild-android-64',
};

export function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: string, isWASM: boolean } {
let pkg: string;
let subpath: string;
let isWASM = false;
let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`;

if (platformKey in knownWindowsPackages) {
Expand All @@ -47,11 +52,17 @@ export function pkgAndSubpathForCurrentPlatform(): { pkg: string, subpath: strin
subpath = 'bin/esbuild';
}

else if (platformKey in knownWebAssemblyFallbackPackages) {
pkg = knownWebAssemblyFallbackPackages[platformKey];
subpath = 'bin/esbuild';
isWASM = true;
}

else {
throw new Error(`Unsupported platform: ${platformKey}`);
}

return { pkg, subpath };
return { pkg, subpath, isWASM };
}

function pkgForSomeOtherPlatform(): string | null {
Expand Down Expand Up @@ -84,15 +95,15 @@ export function downloadedBinPath(pkg: string, subpath: string): string {
return path.join(esbuildLibDir, `downloaded-${pkg}-${path.basename(subpath)}`);
}

export function generateBinPath(): string {
export function generateBinPath(): { binPath: string, isWASM: boolean } {
// This feature was added to give external code a way to modify the binary
// path without modifying the code itself. Do not remove this because
// external code relies on this (in addition to esbuild's own test suite).
if (ESBUILD_BINARY_PATH) {
return ESBUILD_BINARY_PATH;
return { binPath: ESBUILD_BINARY_PATH, isWASM: false };
}

const { pkg, subpath } = pkgAndSubpathForCurrentPlatform();
const { pkg, subpath, isWASM } = pkgAndSubpathForCurrentPlatform();
let binPath: string;

try {
Expand Down Expand Up @@ -180,8 +191,8 @@ by esbuild to install the correct binary executable for your current platform.`)
fs.copyFileSync(binPath, binTargetPath);
fs.chmodSync(binTargetPath, 0o755);
}
return binTargetPath;
return { binPath: binTargetPath, isWASM };
}

return binPath;
return { binPath, isWASM };
}
7 changes: 6 additions & 1 deletion lib/npm/node-shim.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
#!/usr/bin/env node

import { generateBinPath } from "./node-platform";
require('child_process').execFileSync(generateBinPath(), process.argv.slice(2), { stdio: 'inherit' });
const { binPath, isWASM } = generateBinPath()
if (isWASM) {
require('child_process').execFileSync('node', [binPath].concat(process.argv.slice(2)), { stdio: 'inherit' });
} else {
require('child_process').execFileSync(binPath, process.argv.slice(2), { stdio: 'inherit' });
}
7 changes: 6 additions & 1 deletion lib/npm/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,12 @@ let esbuildCommandAndArgs = (): [string, string[]] => {
return ['node', [path.join(__dirname, '..', 'bin', 'esbuild')]];
}

return [generateBinPath(), []];
const { binPath, isWASM } = generateBinPath()
if (isWASM) {
return ['node', [binPath]]
} else {
return [binPath, []];
}
};

// Return true if stderr is a TTY
Expand Down
3 changes: 3 additions & 0 deletions npm/esbuild-android-64/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# esbuild

This is a WebAssembly shim for esbuild on Android x64. See https://github.com/evanw/esbuild for details.
17 changes: 17 additions & 0 deletions npm/esbuild-android-64/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "esbuild-android-64",
"version": "0.14.23",
"description": "A WebAssembly shim for esbuild on Android x64.",
"repository": "https://github.com/evanw/esbuild",
"license": "MIT",
"preferUnplugged": false,
"engines": {
"node": ">=12"
},
"os": [
"android"
],
"cpu": [
"x64"
]
}
1 change: 1 addition & 0 deletions npm/esbuild/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"esbuild": "bin/esbuild"
},
"optionalDependencies": {
"esbuild-android-64": "0.14.23",
"esbuild-android-arm64": "0.14.23",
"esbuild-darwin-64": "0.14.23",
"esbuild-darwin-arm64": "0.14.23",
Expand Down
19 changes: 17 additions & 2 deletions scripts/esbuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const buildNeutralLib = (esbuildPath) => {
const optionalDependencies = Object.fromEntries(Object.values({
...platforms.exports.knownWindowsPackages,
...platforms.exports.knownUnixlikePackages,
...platforms.exports.knownWebAssemblyFallbackPackages,
}).sort().map(x => [x, version]))

// Update "npm/esbuild/package.json"
Expand All @@ -81,6 +82,10 @@ const buildNeutralLib = (esbuildPath) => {
}

exports.buildWasmLib = async (esbuildPath) => {
const npmWasmShimDirs = [
path.join(repoDir, 'npm', 'esbuild-android-64'),
]

// Asynchronously start building the WebAssembly module
const npmWasmDir = path.join(repoDir, 'npm', 'esbuild-wasm')
const goBuildPromise = new Promise((resolve, reject) => childProcess.execFile('go',
Expand Down Expand Up @@ -223,17 +228,27 @@ exports.buildWasmLib = async (esbuildPath) => {
exit0Map[entry] = compressed.toString('base64');
}
}
fs.writeFileSync(path.join(npmWasmDir, 'exit0.js'), `
const exit0Code = `
// Each of these is a native module that calls "exit(0)". This is a workaround
// for https://github.com/nodejs/node/issues/36616. These native modules are
// stored in a string both to make them smaller and to hide them from Yarn 2,
// since they make Yarn 2 unzip this package.
module.exports = ${JSON.stringify(exit0Map, null, 2)};
`);
`;
fs.writeFileSync(path.join(npmWasmDir, 'exit0.js'), exit0Code);

// Join with the asynchronous WebAssembly build
await goBuildPromise;

// Also copy this into the WebAssembly shim directories
for (const dir of npmWasmShimDirs) {
fs.mkdirSync(path.join(dir, 'bin'), { recursive: true })
fs.writeFileSync(path.join(dir, 'wasm_exec.js'), wasm_exec_js);
fs.writeFileSync(path.join(dir, 'exit0.js'), exit0Code);
fs.copyFileSync(path.join(npmWasmDir, 'bin', 'esbuild'), path.join(dir, 'bin', 'esbuild'));
fs.copyFileSync(path.join(npmWasmDir, 'esbuild.wasm'), path.join(dir, 'esbuild.wasm'));
}
}

const buildDenoLib = (esbuildPath) => {
Expand Down

0 comments on commit b690fe8

Please sign in to comment.