Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP: Explore building with pthreads #346

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 43 additions & 25 deletions packages/php-wasm/compile/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# emscripten/emsdk:3.1.24 supports amd64 only.
FROM ubuntu:lunar as emscripten

SHELL ["/bin/bash", "-c"]
SHELL ["/bin/bash", "-l", "-c"]

ENV PKG_CONFIG_PATH /root/lib/lib/pkgconfig
ENV TIMER "(which pv > /dev/null && pv --name '${@}' || cat)"
Expand Down Expand Up @@ -37,9 +37,18 @@ RUN set -euxo pipefail;\
# Docker image, but there is no arm64 image available which makes
# the build take forever on Apple Silicon.
RUN ln -s /usr/bin/python3 /usr/bin/python
RUN git clone https://github.com/emscripten-core/emsdk.git && \
./emsdk/emsdk install latest && \
/root/emsdk/emsdk activate latest
RUN git clone https://github.com/emscripten-core/emsdk.git

RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash
RUN echo 'source /root/.nvm/nvm.sh' >> /root/.bashrc
RUN . /root/.nvm/nvm.sh && nvm install 20

RUN /root/emsdk/emsdk install latest
RUN /root/emsdk/emsdk list
RUN /root/emsdk/emsdk activate latest

RUN . /root/.nvm/nvm.sh && echo 'NODE_JS = "'$(which node)'"' >> /root/emsdk/.emscripten


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

Expand Down Expand Up @@ -120,8 +129,8 @@ RUN cd libzip/build && \
-DZLIB_LIBRARY=/root/lib/lib/libz.a \
-DZLIB_INCLUDE_DIR=/root/lib/include \
..
RUN cd libzip/build && source /root/emsdk/emsdk_env.sh && EMCC_SKIP="-lz" EMCC_FLAGS=" -sSIDE_MODULE " emmake make
RUN cd libzip/build && source /root/emsdk/emsdk_env.sh && EMCC_SKIP="-lz" EMCC_FLAGS=" -sSIDE_MODULE " emmake make install
RUN cd libzip/build && source /root/emsdk/emsdk_env.sh && EMCC_SKIP="-lz" EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 " emmake make
RUN cd libzip/build && source /root/emsdk/emsdk_env.sh && EMCC_SKIP="-lz" EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 " emmake make install

# Compile ncurses
FROM emscripten AS emscripten-ncurses
Expand Down Expand Up @@ -180,7 +189,7 @@ RUN wget https://www.thrysoee.dk/editline/libedit-20221030-3.1.tar.gz && \
# Musl is ISO 10646 compliant but doesn't define __STDC_ISO_10646__, so
# let's define it manually. Learn more at:
# http://lists.busybox.net/pipermail/buildroot/2016-January/149100.html
EMCC_SKIP="-lc -lncurses " EMCC_FLAGS=" -sSIDE_MODULE -D__STDC_ISO_10646__=201103L " \
EMCC_SKIP="-lc -lncurses " EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 -D__STDC_ISO_10646__=201103L " \
emmake make && \
emmake make install

Expand All @@ -193,8 +202,8 @@ RUN source /root/emsdk/emsdk_env.sh && \
--depth 1 && \
cd libxml2 && \
./autogen.sh && \
emconfigure ./configure --with-http=no --with-ftp=no --with-python=no --with-threads=no --enable-shared=no --prefix=/root/lib/ &&\
EMCC_FLAGS=" -sSIDE_MODULE " emmake make && \
emconfigure ./configure --with-http=no --with-ftp=no --with-python=no --with-threads=yes --enable-shared=no --prefix=/root/lib/ &&\
EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 " emmake make && \
emmake make install

# Compile Bison 2.7 (for PHP <=7.3)
Expand Down Expand Up @@ -222,7 +231,7 @@ RUN set -euxo pipefail &&\
--build i386-pc-linux-gnu \
--target wasm32-unknown-emscripten \
--prefix=/root/lib/ && \
EMCC_SKIP="-lc" EMCC_FLAGS=" -sSIDE_MODULE " emmake make && \
EMCC_SKIP="-lc" EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 " emmake make && \
emmake make install

# Compile OpenSSL
Expand All @@ -237,12 +246,12 @@ RUN set -euxo pipefail && \
wget https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz && \
tar xf openssl-$OPENSSL_VERSION.tar.gz && \
cd openssl-$OPENSSL_VERSION && \
emconfigure ./Configure dist -DHAVE_FORK=0 -DOPENSSL_NO_AFALGENG=1 no-threads --prefix=/root/lib && \
emconfigure ./Configure dist -DHAVE_FORK=0 -DOPENSSL_NO_AFALGENG=1 --prefix=/root/lib && \
sed -i 's|^CROSS_COMPILE.*$|CROSS_COMPILE=|g' Makefile && \
EMCC_FLAGS=" -sSIDE_MODULE " EMCC_SKIP="-lz" emmake make -j 12 build_generated libssl.a libcrypto.a; \
EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 " EMCC_SKIP="-lz" emmake make -j 12 build_generated libssl.a libcrypto.a; \
cp -RL include/openssl /root/lib/include && \
cp libcrypto.a libssl.a /root/lib/lib && \
EMCC_FLAGS=" -sSIDE_MODULE " EMCC_SKIP="-lz" emmake make install;
EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 " EMCC_SKIP="-lz" emmake make install;

# Compile libpng
FROM emscripten AS emscripten-libpng
Expand All @@ -259,7 +268,7 @@ RUN source /root/emsdk/emsdk_env.sh && \
--build i386-pc-linux-gnu \
--target wasm32-unknown-emscripten \
--prefix=/root/lib/
RUN source /root/emsdk/emsdk_env.sh && EMCC_SKIP="-lc -lz" EMCC_FLAGS="-sSIDE_MODULE" emmake make
RUN source /root/emsdk/emsdk_env.sh && EMCC_SKIP="-lc -lz" EMCC_FLAGS="-sSIDE_MODULE -sUSE_PTHREADS=1" emmake make
RUN source /root/emsdk/emsdk_env.sh && emmake make install

# Clone PHP
Expand Down Expand Up @@ -330,15 +339,16 @@ RUN if [ "$WITH_LIBZIP" = "yes" ]; then \
echo -n ' --with-zlib --with-zlib-dir=/root/lib --with-zip' >> /root/.php-configure-flags; \
echo -n ' -I /root/zlib -I /root/libzip' >> /root/.emcc-php-wasm-flags; \
echo -n ' /root/lib/lib/libzip.a /root/lib/lib/libz.a' >> /root/.emcc-php-wasm-sources; \
fi && \
/root/replace.sh 's/pharcmd=pharcmd/pharcmd=/g' /root/php-src/configure && \
/root/replace.sh 's/pharcmd_install=install-pharcmd/pharcmd_install=/g' /root/php-src/configure; \
fi; \
fi;

RUN /root/replace.sh 's/pharcmd=pharcmd/pharcmd=/g' /root/php-src/configure
RUN /root/replace.sh 's/pharcmd_install=install-pharcmd/pharcmd_install=/g' /root/php-src/configure;

# Add ncurses if needed and libedit if needed
COPY --from=emscripten-libedit /root/lib /root/lib-libedit
COPY --from=emscripten-ncurses /root/lib /root/lib-ncurses
RUN if [ "$WITH_CLI_SAPI" = "yes" ]; \
RUN if [ "$WITH_CLI_SAPI" = "disabled" ]; \
then \
/root/copy-lib.sh lib-ncurses && \
/root/copy-lib.sh lib-libedit && \
Expand Down Expand Up @@ -463,6 +473,10 @@ RUN source /root/emsdk/emsdk_env.sh && \
# --enable-json for PHP < 8.0:
--enable-json \
--enable-embed=static \
--enable-zts \
--enable-maintainer-zts \
--enable-pthreads \
--enable-pcntl \
--with-layout=GNU \
--disable-cgi \
--disable-all \
Expand All @@ -485,7 +499,8 @@ RUN source /root/emsdk/emsdk_env.sh && \

# Silence the errors "munmap() failed: [28] Invalid argument"
# @TODO: Identify the root cause behind these errors and fix them properly
RUN echo '#define ZEND_MM_ERROR 0' >> /root/php-src/main/php_config.h;
RUN echo '#define ZEND_MM_ERROR 1' >> /root/php-src/main/php_config.h;
RUN echo '#define ZEND_DEBUG 1' >> /root/php-src/main/php_config.h;

# With HAVE_UNISTD_H=1 PHP complains about the missing getdtablesize() function
RUN /root/replace.sh 's/define HAVE_UNISTD_H 1/define HAVE_UNISTD_H 0/g' /root/php-src/main/php_config.h
Expand All @@ -511,7 +526,7 @@ RUN echo 'extern int wasm_close(int fd);' >> /root/php-src/main/php_config.h;

RUN source /root/emsdk/emsdk_env.sh && \
# We're compiling PHP as emscripten's side module...
EMCC_FLAGS=" -sSIDE_MODULE -Dsetsockopt=wasm_setsockopt -Dpopen=wasm_popen -Dpclose=wasm_pclose " \
EMCC_FLAGS=" -sSIDE_MODULE -sUSE_PTHREADS=1 -Dsetsockopt=wasm_setsockopt -Dpopen=wasm_popen -Dpclose=wasm_pclose " \
# ...which means we must skip all the libraries - they will be provided in the final linking step.
EMCC_SKIP="-lz -ledit -ldl -lncurses -lzip -lpng16 -lssl -lcrypto -lxml2 -lc -lm -lsqlite3 /root/lib/lib/libxml2.a /root/lib/lib/libsqlite3.so /root/lib/lib/libsqlite3.a /root/lib/lib/libpng16.so" \
emmake make -j8
Expand Down Expand Up @@ -910,6 +925,7 @@ RUN mkdir /root/output
COPY ./build-assets/phpwasm-emscripten-library.js /root/phpwasm-emscripten-library.js
RUN source /root/emsdk/emsdk_env.sh && \
export EXPORTED_FUNCTIONS=$'["_php_wasm_init", \n\
"_run_php", \n\
"_phpwasm_destroy_uploaded_files_hash", \n\
"_phpwasm_init_uploaded_files_hash", \n\
"_phpwasm_register_uploaded_file", \n\
Expand All @@ -930,8 +946,9 @@ RUN source /root/emsdk/emsdk_env.sh && \
"_wasm_set_request_port", \n\
"_wasm_set_request_uri", \n\
"_wasm_set_skip_shebang" '"$(cat /root/.EXPORTED_FUNCTIONS)"']'; \
emcc -O3 \
emcc -O0 -g2 \
--js-library /root/phpwasm-emscripten-library.js \
-pthread \
-I . \
-I ext \
-I ext/json \
Expand All @@ -946,7 +963,8 @@ RUN source /root/emsdk/emsdk_env.sh && \
-s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "UTF8ToString", "lengthBytesUTF8", "FS", "PROXYFS"]' \
-s INITIAL_MEMORY=1024MB \
-s ALLOW_MEMORY_GROWTH=1 \
-s ASSERTIONS=0 \
-s USE_PTHREADS=1 \
-s ASSERTIONS=3 \
-s ERROR_ON_UNDEFINED_SYMBOLS=0 \
-s NODEJS_CATCH_EXIT=0 \
-s INVOKE_RUN=0 \
Expand Down Expand Up @@ -1038,13 +1056,13 @@ RUN \
# Turn the php.js file into an ES module
# Manually turn the output into a esm module instead of relying on -s MODULARIZE=1.
# which pollutes the global namespace and does not play well with import() mechanics.
echo "export const dependenciesTotalSize = $FILE_SIZE; " >> /root/output/php-module.js && \
echo "const dependenciesTotalSize = $FILE_SIZE; " >> /root/output/php-module.js && \
if [ "$EMSCRIPTEN_ENVIRONMENT" = "node" ]; then \
echo "const dependencyFilename = __dirname + '/$WASM_FILENAME'; " >> /root/output/php-module.js; \
echo "const dependencyFilename = './$WASM_FILENAME'; " >> /root/output/php-module.js; \
else \
echo "import dependencyFilename from './$WASM_FILENAME'; " >> /root/output/php-module.js; \
fi; \
echo " export { dependencyFilename }; export function init(RuntimeName, PHPLoader) {" >> /root/output/php-module.js && \
echo " module.exports = function init(RuntimeName, PHPLoader) {" >> /root/output/php-module.js && \
cat /root/output/php.js >> /root/output/php-module.js && \
cat /root/append-before-return.js >> /root/output/php-module.js && \
echo " return PHPLoader; }" >> /root/output/php-module.js && \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,3 @@ DNS.address_map.addrs.localhost = '127.0.0.1';
* so that it can be inspected later.
*/
PHPLoader.debug = 'debug' in PHPLoader ? PHPLoader.debug : true;
if (PHPLoader.debug) {
const originalHandleSleep = Asyncify.handleSleep;
Asyncify.handleSleep = function (startAsync) {
if (!ABORT) {
Module["lastAsyncifyStackSource"] = new Error();
}
return originalHandleSleep(startAsync);
}
}
Loading