Skip to content
Open
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
39 changes: 39 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Dependencies
node_modules/
tools/node_modules/

# Version control
.git/
.gitignore
.gitattributes

# Documentation
*.md
README*
LICENSE

# Test artifacts and scripts
test-*.sh
test-output/

# Build artifacts
*.o
*.a
*.wasm
*.wasm.map

# Logs
*.log

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Pi agent config
.pi/
20 changes: 10 additions & 10 deletions .github/actions/setup-binaryen/action.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
name: 'Setup Binaryen'
description: 'Install Binaryen WebAssembly toolchain'
name: "Setup Binaryen"
description: "Install Binaryen WebAssembly toolchain"
inputs:
version:
description: 'Binaryen version to install'
description: "Binaryen version to install"
required: false
default: '124'
default: "124"
install-path:
description: 'Directory to install Binaryen to'
description: "Directory to install Binaryen to"
required: false
default: '/opt/binaryen'
default: "/opt/binaryen"

outputs:
binaryen-path:
description: 'Path to the installed Binaryen'
description: "Path to the installed Binaryen"
value: ${{ steps.install-unix.outputs.binaryen-path || steps.install-windows.outputs.binaryen-path }}
binaryen-version:
description: 'Version of Binaryen that was installed'
description: "Version of Binaryen that was installed"
value: ${{ inputs.version }}

runs:
using: 'composite'
using: "composite"
steps:
- name: Detect platform
id: platform
Expand Down Expand Up @@ -128,4 +128,4 @@ runs:
shell: pwsh
run: |
& wasm-opt --version
Write-Host "Binaryen installation verified"
Write-Host "Binaryen installation verified"
20 changes: 10 additions & 10 deletions .github/actions/setup-wabt/action.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
name: 'Setup WABT'
description: 'Install WebAssembly Binary Toolkit (WABT)'
name: "Setup WABT"
description: "Install WebAssembly Binary Toolkit (WABT)"
inputs:
version:
description: 'WABT version to install'
description: "WABT version to install"
required: false
default: '1.0.39'
default: "1.0.39"
install-path:
description: 'Directory to install WABT to'
description: "Directory to install WABT to"
required: false
default: '/opt/wabt'
default: "/opt/wabt"

outputs:
wabt-path:
description: 'Path to the installed WABT'
description: "Path to the installed WABT"
value: ${{ steps.install-unix.outputs.wabt-path || steps.install-windows.outputs.wabt-path }}
wabt-version:
description: 'Version of WABT that was installed'
description: "Version of WABT that was installed"
value: ${{ inputs.version }}

runs:
using: 'composite'
using: "composite"
steps:
- name: Detect platform
id: platform
Expand Down Expand Up @@ -120,4 +120,4 @@ runs:
shell: pwsh
run: |
& wasm-objdump --version
Write-Host "WABT installation verified"
Write-Host "WABT installation verified"
19 changes: 9 additions & 10 deletions .github/workflows/nodefs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ env:
EMSCRIPTEN_VERSION: 3.1.73

jobs:

perlemscripten:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4

- name: Setup Emscripten
uses: mymindstorm/setup-emsdk@v13
with:
Expand Down Expand Up @@ -41,7 +40,7 @@ jobs:
# Archive::Zip Compress::Raw::Lzma Compress::Zlib Digest::MD5 Digest::SHA \
# IO::Compress::Brotli IO::Compress::RawDeflate IO::Uncompress::Brotli \
# IO::Uncompress::RawInflate POSIX::strptime Time::HiRes

- name: Heredoc
run: |
cat <<'EOF' > hintfile_wasm.sh
Expand Down Expand Up @@ -116,26 +115,26 @@ jobs:
# Configure apparently changes "-s ASSERTIONS=2 -s STACK_OVERFLOW_CHECK=2" to "-s -s" when converting ccflags to cppflags
# this is the current hack/workaround: copy cppflags from config.sh and fix it (TODO Later: better way would be to patch Configure)
cppflags='-lm -s ERROR_ON_UNDEFINED_SYMBOLS=0 -D_GNU_SOURCE -D_POSIX_C_SOURCE -DSTANDARD_C -DPERL_USE_SAFE_PUTENV -DNO_MATHOMS -Wno-null-pointer-arithmetic -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'

EOF
- name: Install Perl static wasm
shell: bash
run: |

mkdir wasm && curl -L $URLPERL | tar -xzf - --strip-components=1 --directory=wasm

cp hintfile_wasm.sh wasm/hints/emscripten.sh

cd wasm
# Ensure the correct directories are created
mkdir -p ./prefix/lib/perl5/site_perl/5.40.0/wasm

# Copy the required files
cp -rv ../native/prefix/lib/perl5/site_perl/5.40.0/Image ./prefix/lib/perl5/site_perl/5.40.0/wasm/
cp -rv ../native/prefix/lib/perl5/site_perl/5.40.0/File ./prefix/lib/perl5/site_perl/5.40.0/wasm/

emconfigure sh ./Configure -sde -Dinc_version_list=none -Ddlsrc=none -Dloclibpth='' -Dglibpth='' -Dlns='/bin/ln' -Dman1dir=none -Dman3dir=none -Dosname="emscripten" -Darchname="wasm" -Dosvers="2.0.5" -Dmyhostname='localhost' -Dmydomain='.local' -Dperladmin=root -Dcc=emcc -Dld=emcc -Dar=$(which emar) -Dranlib=$(which emranlib) -Doptimize="-O2" -Dlibs='-lm' -Dhintfile=emscripten -Dsysroot=$(dirname $(which emcc))/system -Dhostperl=$PWD/../native/miniperl -Dhostgenerate=$PWD/../native/generate_uudmap -Dprefix=$PWD/prefix -Dstatic_ext="mro Devel/Peek File/DosGlob File/Glob Sys/Syslog Sys/Hostname PerlIO/via PerlIO/mmap PerlIO/encoding B attributes Unicode/Normalize Unicode/Collate threads threads/shared IPC/SysV re Digest/MD5 Digest/SHA SDBM_File Math/BigInt/FastCalc Data/Dumper I18N/Langinfo Time/HiRes Time/Piece IO Socket Hash/Util/FieldHash Hash/Util Filter/Util/Call POSIX Encode/Unicode Encode Encode/JP Encode/KR Encode/EBCDIC Encode/CN Encode/Symbol Encode/Byte Encode/TW Compress/Raw/Zlib Compress/Raw/Bzip2 MIME/Base64 Cwd Storable List/Util Fcntl Opcode"

ln -s $PWD/pod/perldelta.pod .; ln $PWD/README.* ..
emmake make utilities PERL="$PWD/../native/miniperl"
emmake make RUN_PERL="$PWD/../native/miniperl -Ilib -I."
Expand Down
208 changes: 208 additions & 0 deletions .github/workflows/zeroperl-release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
name: zeroperl Release

on:
workflow_dispatch:
inputs:
tag:
description: "Release tag (e.g. v0.1.0). Leave empty to skip release creation."
required: false
type: string
default: ""
perl-version-legacy:
description: "Legacy Perl version"
required: false
default: "5.16.3"
perl-version-latest:
description: "Latest Perl version"
required: false
default: "5.42.2"
exiftool-version:
description: "ExifTool version"
required: false
default: "13.55"

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- name: exiftool-5.16.3
perl-version: ${{ inputs.perl-version-legacy }}
shrink-mode: full
embed-prefix: true
build-exiftool: true
- name: exiftool-5.42.2
perl-version: ${{ inputs.perl-version-latest }}
shrink-mode: full
embed-prefix: true
build-exiftool: true
- name: perl-only-5.16.3
perl-version: ${{ inputs.perl-version-legacy }}
shrink-mode: off
embed-prefix: true
build-exiftool: false
- name: perl-only-5.42.2
perl-version: ${{ inputs.perl-version-latest }}
shrink-mode: off
embed-prefix: true
build-exiftool: false

steps:
- name: Check out code
uses: actions/checkout@v7
with:
submodules: recursive

- name: Install verifier dependencies
run: npm --prefix tools ci

- name: Build zeroperl (${{ matrix.name }})
run: |
SFS_COMPRESS="false"
if [ "${{ matrix.shrink-mode }}" = "full" ]; then
SFS_COMPRESS="true"
fi

docker build \
--build-arg PERL_VERSION=${{ matrix.perl-version }} \
--build-arg EXIFTOOL_VERSION=${{ inputs.exiftool-version }} \
--build-arg BUILD_EXIFTOOL=${{ matrix.build-exiftool }} \
--build-arg TRIM=true \
--build-arg ZEROPERL_SHRINK=${{ matrix.shrink-mode }} \
--build-arg ZEROPERL_SFS_COMPRESS=${SFS_COMPRESS} \
--build-arg ZEROPERL_EMBED_PREFIX=${{ matrix.embed-prefix }} \
-t zeroperl:${{ matrix.name }} .

- name: Build wasi-perl stage (${{ matrix.name }})
run: |
SFS_COMPRESS="false"
if [ "${{ matrix.shrink-mode }}" = "full" ]; then
SFS_COMPRESS="true"
fi

docker build \
--target wasi-perl \
--build-arg PERL_VERSION=${{ matrix.perl-version }} \
--build-arg EXIFTOOL_VERSION=${{ inputs.exiftool-version }} \
--build-arg BUILD_EXIFTOOL=${{ matrix.build-exiftool }} \
--build-arg TRIM=true \
--build-arg ZEROPERL_SHRINK=${{ matrix.shrink-mode }} \
--build-arg ZEROPERL_SFS_COMPRESS=${SFS_COMPRESS} \
--build-arg ZEROPERL_EMBED_PREFIX=${{ matrix.embed-prefix }} \
-t zeroperl:${{ matrix.name }}-wasi .

- name: ExifTool smoke (${{ matrix.name }})
if: ${{ matrix.build-exiftool == true }}
run: |
docker run --rm zeroperl:${{ matrix.name }}-wasi \
sh -lc '/build/native/prefix/bin/perl /build/repo/exiftool.min.pl -ver'

- name: Extract wasi gen artifacts (${{ matrix.name }})
if: ${{ matrix.shrink-mode != 'off' }}
run: |
mkdir -p /tmp/wasi-gen/${{ matrix.name }}
for file in traced-files.txt xs-static-ext.txt warmup-inc.txt wasm-missing-paths.txt; do
docker run --rm zeroperl:${{ matrix.name }}-wasi \
sh -lc "cat /build/repo/gen/$file" > "/tmp/wasi-gen/${{ matrix.name }}/$file"
done

- name: Shrink manifest determinism (${{ matrix.name }})
if: ${{ matrix.shrink-mode != 'off' }}
run: |
SFS_COMPRESS="true"
docker build \
--target wasi-perl \
--build-arg PERL_VERSION=${{ matrix.perl-version }} \
--build-arg EXIFTOOL_VERSION=${{ inputs.exiftool-version }} \
--build-arg BUILD_EXIFTOOL=${{ matrix.build-exiftool }} \
--build-arg TRIM=true \
--build-arg ZEROPERL_SHRINK=${{ matrix.shrink-mode }} \
--build-arg ZEROPERL_SFS_COMPRESS=${SFS_COMPRESS} \
--build-arg ZEROPERL_EMBED_PREFIX=${{ matrix.embed-prefix }} \
-t zeroperl:${{ matrix.name }}-wasi-determinism .

manifest_cmd='for f in /build/repo/gen/traced-files.txt /build/repo/gen/xs-static-ext.txt /build/repo/gen/hints-static-ext.fragment /build/repo/gen/wasm-auto-libs.txt /build/repo/gen/xs_init.inc; do if [ -f "$f" ]; then sha256sum "$f"; else echo "MISSING $f"; fi; done'
docker run --rm zeroperl:${{ matrix.name }}-wasi sh -lc "$manifest_cmd" | sort > /tmp/manifest-${{ matrix.name }}-a.txt
docker run --rm zeroperl:${{ matrix.name }}-wasi-determinism sh -lc "$manifest_cmd" | sort > /tmp/manifest-${{ matrix.name }}-b.txt
diff -u /tmp/manifest-${{ matrix.name }}-a.txt /tmp/manifest-${{ matrix.name }}-b.txt

- name: Extract artifacts (${{ matrix.name }})
run: |
mkdir -p output/${{ matrix.name }}
docker run --rm -v $PWD/output:/output zeroperl:${{ matrix.name }} \
cp -r /artifacts/. /output/${{ matrix.name }}/
ls -la output/${{ matrix.name }}/

- name: Embedded @INC verifier (${{ matrix.name }})
if: ${{ matrix.embed-prefix == true && matrix.build-exiftool == true }}
run: node tools/verify-embedded-inc.mjs output/${{ matrix.name }}/zeroperl.wasm

- name: WASM runtime smoke (${{ matrix.name }})
if: ${{ matrix.build-exiftool == true && matrix.embed-prefix == true }}
run: node tools/wasm-smoke.mjs output/${{ matrix.name }}/zeroperl.wasm output/${{ matrix.name }}/exiftool.min.pl

- name: Upload WASM artifacts (${{ matrix.name }})
uses: actions/upload-artifact@v7
with:
name: wasm-${{ matrix.name }}
path: |
output/${{ matrix.name }}/zeroperl.wasm
output/${{ matrix.name }}/zeroperl_reactor.wasm
output/${{ matrix.name }}/config.h
if-no-files-found: error

- name: Upload Perl prefix (${{ matrix.name }})
uses: actions/upload-artifact@v7
with:
name: prefix-${{ matrix.name }}
path: output/${{ matrix.name }}/perl-wasi-prefix

- name: Upload ExifTool (${{ matrix.name }})
if: ${{ matrix.build-exiftool == true }}
uses: actions/upload-artifact@v7
with:
name: exiftool-${{ matrix.name }}
path: output/${{ matrix.name }}/exiftool.min.pl

publish:
needs: build
runs-on: ubuntu-latest
if: ${{ inputs.tag != '' }}
permissions:
contents: write

steps:
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: release-assets
merge-multiple: false

- name: Prepare release assets
run: |
mkdir -p assets
for dir in release-assets/wasm-*/; do
name=$(basename "$dir" | sed 's/^wasm-//')
if [ -f "$dir/zeroperl.wasm" ]; then
cp "$dir/zeroperl.wasm" "assets/${name}.wasm"
fi
for f in zeroperl_reactor.wasm config.h; do
if [ -f "$dir/$f" ]; then
cp "$dir/$f" "assets/${name}_${f}"
fi
done
done
echo "=== Release assets ==="
ls -lh assets/

- name: Create GitHub release
uses: softprops/action-gh-release@v3
with:
tag_name: ${{ inputs.tag }}
name: Release ${{ inputs.tag }}
draft: false
files: assets/*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Loading