Skip to content

Commit adb2d94

Browse files
Brandon Paytonbrandonpayton
andcommitted
Build php-wasm with Emscripten 3.1.74 (#2)
Note: This work is continued from a PR started under the WordPress GH org. There are a couple of reasons for this upgrade: 1. I am having trouble rebuilding php-wasm on my current system. References to older ubuntu images and emscripten versions [has given me trouble](#2038 (comment)). 2. We want [this Emscripten fix](emscripten-core/emscripten#22932) from @jeroenpf and @bgrgicak which was first included in Emscripten 3.1.73. This PR: - Bumps the ubuntu docker image version due to build errors related to missing image. Referencing a newer ubuntu image seemed to fix the "missing image" errors. - Bumps Emscripten version - Adjusts Playground-specific patches to Emscripten output since the latest breaks that patching. - CI (once we can run GH actions on A8C's GHE instance) --------- Co-authored-by: Brandon Payton <[email protected]>
1 parent 3a89213 commit adb2d94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

86 files changed

+160094
-127782
lines changed

package-lock.json

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
"prepare": "husky install",
2424
"reset": "nx reset",
2525
"recompile:php": "npm run recompile:php:web && npm run recompile:php:node",
26+
"recompile:php:web": "nx recompile-php:all php-wasm-web ",
2627
"recompile:php:web:jspi:all": "nx recompile-php:jspi:all php-wasm-web",
2728
"recompile:php:web:jspi:8.4": "nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.4 ",
2829
"recompile:php:web:jspi:8.3": "nx recompile-php:jspi php-wasm-web -- --PHP_VERSION=8.3 ",

packages/php-wasm/compile/base-image/Dockerfile

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Originally forked from https://github.com/seanmorris/php-wasm
2-
# ubuntu:lunar supports amd64 and arm64 (Apple Silicon) while
3-
# emscripten/emsdk:3.1.24 supports amd64 only.
4-
FROM ubuntu:lunar as emscripten
2+
# ubuntu:noble supports amd64 and arm64 (Apple Silicon)
3+
FROM ubuntu:noble as emscripten
54

65
SHELL ["/bin/bash", "-c"]
76

@@ -50,8 +49,8 @@ RUN set -euxo pipefail;\
5049
# https://github.com/WordPress/wordpress-playground/tree/67d916b5eccfe78e26e9c953598cc1a81f316931/packages/php-wasm/compile
5150
RUN ln -s /usr/bin/python3 /usr/bin/python
5251
RUN git clone https://github.com/emscripten-core/emsdk.git && \
53-
./emsdk/emsdk install 3.1.61 && \
54-
/root/emsdk/emsdk activate 3.1.61
52+
./emsdk/emsdk install 3.1.74 && \
53+
/root/emsdk/emsdk activate 3.1.74
5554

5655
RUN mkdir -p /root/lib/lib /root/lib/include /root/lib/share /root/lib/bin
5756

@@ -62,9 +61,11 @@ for dir in $(ls $1); do \n\
6261
cp -r /root/$1/$dir/* /root/lib/$dir/ 2>/dev/null || :; \n\
6362
done ' > /root/copy-lib.sh
6463
RUN chmod a+x /root/copy-lib.sh
65-
# Script to replace strings in files and exit with a non-zero status if the string is not found.
64+
# Scripts to replace strings in files and exit with a non-zero status if the string is not found.
6665
COPY ./replace.sh /root/replace.sh
6766
RUN chmod a+x /root/replace.sh
67+
COPY ./replace-across-lines.sh /root/replace-across-lines.sh
68+
RUN chmod a+x /root/replace-across-lines.sh
6869

6970
# Patch emcc to allow skipping flags and passing additional flags using environment variables.
7071
#
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/bin/bash
2+
3+
# This script is used to replace strings in files and exit with a non-zero status if the string is not found.
4+
# This version of the script can do replacements across multiple lines.
5+
6+
perl -0 -pi.bak -e "$1" "$2"
7+
if [ $? -ne 0 ]; then
8+
echo "Failed to replace $1 in file $2 - exiting with non-zero status"
9+
exit 1
10+
fi
11+
if cmp --silent -- "$2" "$2.bak"; then
12+
echo "No matches found for $1 in file $2 - exiting with non-zero status"
13+
exit 1
14+
fi

packages/php-wasm/compile/php/Dockerfile

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ RUN set -euxo pipefail; \
10721072
# This assumes the traffic is always forwarded to the same target.
10731073
# However, we want to support arbitrary targets, so we need to
10741074
# replace the hardcoded websocket target URL with a dynamic callback.
1075-
/root/replace.sh $'s/if\s*\(\s*["\']string["\']\s*===\s*typeof Module\[["\']websocket["\']\]\[["\']url["\']\]\s*\)/if("function"===typeof Module["websocket"]["url"]) {\nurl = Module["websocket"]["url"](...arguments);\n}else if ("string" === typeof Module["websocket"]["url"])/g' \
1075+
/root/replace.sh $'s/if\s*\(\s*SOCKFS\.websocketArgs\["url"\]\s*\)/if("function"===typeof SOCKFS.websocketArgs["url"]) {\nurl = SOCKFS.websocketArgs["url"](...arguments);\n}else if ("string" === typeof SOCKFS.websocketArgs["url"])/g' \
10761076
/root/output/php.js; \
10771077
# Enable custom WebSocket constructors to support socket options.
10781078
/root/replace.sh "s/ws\s*=\s*new WebSocketConstructor/if (Module['websocket']['decorator']) {WebSocketConstructor = Module['websocket']['decorator'](WebSocketConstructor);}ws = new WebSocketConstructor/g" /root/output/php.js && \
@@ -1110,6 +1110,26 @@ RUN set -euxo pipefail; \
11101110
# wrapper function.
11111111
/root/replace.sh $'s/ENVIRONMENT_IS_([A-Z]+)\s*=\s*(true|false)/ENVIRONMENT_IS_$1=RuntimeName==="$1"/g' /root/output/php.js; \
11121112
/root/replace.sh 's/var ENV\s*=\s*\{/var ENV = PHPLoader.ENV || {/g' /root/output/php.js; \
1113+
# Patch Emscripten exit status to include a stack trace
1114+
# Override Emscripten's default ExitStatus class which gets
1115+
# thrown on failure. Unfortunately, the default object is not
1116+
# a subclass of Error and does not provide any stack trace.
1117+
#
1118+
# This is a deliberate behavior on Emscripten's end to prevent
1119+
# memory leaks after the program exits. See:
1120+
#
1121+
# https://github.com/emscripten-core/emscripten/pull/9108
1122+
#
1123+
# In case of WordPress Playground, the worker in which the PHP
1124+
# runs will typically exit after the PHP program finishes, so
1125+
# we don't have to worry about memory leaks.
1126+
/root/replace-across-lines.sh 's/(class\s+ExitStatus\s*\{\s*name\s*=\s*"ExitStatus";\s*constructor\(\s*status\s*\)\s*\{\s*this\.message\s*=\s*`Program terminated with exit\(\$\{status\}\)`;\s*this.status\s*=\s*status;?\s*\}\s*\})/$1\nExitStatus = class PHPExitStatus extends Error {\nconstructor(status) {\n super(status);\n this.name = "ExitStatus";\n this.message = "Program terminated with exit(" + status + ")";\n this.status = status;\n }\n};/' /root/output/php.js; \
1127+
# Restore quit handling to Emscripten
1128+
# Quit callback customization was removed from Emscripten by:
1129+
# https://github.com/emscripten-core/emscripten/pull/22371
1130+
# But the alternative `onExit()` handling is conditional and has different semantics.
1131+
# To avoid bugs due to this change, let's just restore support for quit callback customization.
1132+
/root/replace.sh 's/(if\s*\(Module\["thisProgram"\]\)\s*thisProgram\s*=\s*Module\["thisProgram"\];)/$1\nif (Module["quit"]) quit_=Module["quit"];/' /root/output/php.js; \
11131133
# Turn the php.js file into an ES module
11141134
# Manually turn the output into a esm module instead of relying on -s MODULARIZE=1.
11151135
# which pollutes the global namespace and does not play well with import() mechanics.
Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,2 @@
11
export function init(RuntimeName, PHPLoader) {
2-
/**
3-
* Overrides Emscripten's default ExitStatus object which gets
4-
* thrown on failure. Unfortunately, the default object is not
5-
* a subclass of Error and does not provide any stack trace.
6-
*
7-
* This is a deliberate behavior on Emscripten's end to prevent
8-
* memory leaks after the program exits. See:
9-
*
10-
* https://github.com/emscripten-core/emscripten/pull/9108
11-
*
12-
* In case of WordPress Playground, the worker in which the PHP
13-
* runs will typically exit after the PHP program finishes, so
14-
* we don't have to worry about memory leaks.
15-
*
16-
* As for assigning to a previously undeclared ExitStatus variable here,
17-
* the Emscripten module declares `ExitStatus` as `function ExitStatus`
18-
* which means it gets hoisted to the top of the scope and can be
19-
* reassigned here – before the actual declaration is reached.
20-
*
21-
* If that sounds weird, try this example:
22-
*
23-
* ExitStatus = () => { console.log("reassigned"); }
24-
* function ExitStatus() {}
25-
* ExitStatus();
26-
* // logs "reassigned"
27-
*/
28-
ExitStatus = class PHPExitStatus extends Error {
29-
constructor(status) {
30-
super(status);
31-
this.name = "ExitStatus";
32-
this.message = "Program terminated with exit(" + status + ")";
33-
this.status = status;
34-
}
35-
}
36-
372
// The rest of the code comes from the built php.js file and esm-suffix.js

0 commit comments

Comments
 (0)