Skip to content
Merged
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
16 changes: 8 additions & 8 deletions build-on-linux.sh
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@ docker run --rm \
fi

echo ">>> Step 7: Build PyInstaller..."
pyinstaller --onefile --name weasyprint run_weasyprint.py
pyinstaller --onedir --name weasyprint run_weasyprint.py

echo ">>> Step 8: Check result..."
if [ -f "dist/weasyprint" ]; then
if [ -d "dist/weasyprint" ]; then
ls -lh dist/weasyprint
cp dist/weasyprint /build/'"$OUTPUT_NAME"'
cp -rv dist/weasyprint /build/'"$OUTPUT_NAME"'
echo ">>> SUCCESS: File was created!"
else
echo ">>> ERROR: dist/weasyprint does not exists!"
Expand All @@ -109,7 +109,7 @@ docker run --rm \

# 4. Check if file exists
echo "[4/7] Check if file exists..."
if [ ! -f "$OUTPUT_NAME" ]; then
if [ ! -d "$OUTPUT_NAME" ]; then
echo "❌ ERROR: The file $OUTPUT_NAME was not created!"
echo ""
echo "Possible reasons:"
Expand All @@ -128,7 +128,7 @@ if docker run --rm \
-v "$PWD":/build \
-w /build \
"$DOCKER_IMAGE" \
/bin/bash -lc 'apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf-2.0-0 >/dev/null 2>&1 && "./$OUTPUT_NAME" --version'; then
/bin/bash -lc 'apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends libpango-1.0-0 libpangocairo-1.0-0 libgdk-pixbuf-2.0-0 >/dev/null 2>&1 && "./$OUTPUT_NAME/weasyprint" --info'; then
echo "✅ Version test passed inside Docker!"
else
echo "⚠️ Version test failed (maybe because of missing system libraries in Docker image)"
Expand All @@ -144,16 +144,16 @@ echo "📝 Usage:"
echo " ./$OUTPUT_NAME input.html output.pdf"
echo "============================================"

cp $OUTPUT_NAME ../
cp -r $OUTPUT_NAME ../

echo "[6/7] Creating version file..."
cd ..
touch "version-$VERSION"

echo "[7/7] Creating archive $ASSETS_DIR/standalone-linux-64.zip..."
zip "./$ASSETS_DIR/standalone-linux-64.zip" "version-$VERSION" "$OUTPUT_NAME"
zip -r "./$ASSETS_DIR/standalone-linux-64.zip" "version-$VERSION" "$OUTPUT_NAME"

# Cleanup
echo "Cleanup..."
rm "$OUTPUT_NAME" "version-$VERSION"
rm -r "$OUTPUT_NAME" "version-$VERSION"

53 changes: 43 additions & 10 deletions build-on-windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,52 @@ if (!(Test-Path $assets)) {
$workingDir = Resolve-Path -Path "./standalone-windows-64";
$assets = Resolve-Path -Path "./assets";

Write-Host "*** Downloading weasyprint Windows executable"
Invoke-WebRequest -Uri "https://github.com/Kozea/WeasyPrint/releases/download/v68.1/weasyprint-windows.zip" -OutFile "$workingDir/weasyprint-windows.zip"
Expand-Archive -Path "$workingDir/weasyprint-windows.zip" -DestinationPath "$workingDir" -Force
Remove-Item "$workingDir/weasyprint-windows.zip" -Recurse -Force | Out-Null
Write-Host "*** Downloading msys2 environment"
Invoke-WebRequest -Uri "https://github.com/msys2/msys2-installer/releases/download/2025-12-13/msys2-base-x86_64-20251213.sfx.exe" -OutFile "$workingDir/msys2-base-x86_64-20251213.sfx.exe"
Write-Host "*** Extracting msys2 environment"
Invoke-Expression "$workingDir/msys2-base-x86_64-20251213.sfx.exe -y -o$workingDir"
Remove-Item "$workingDir/msys2-base-x86_64-20251213.sfx.exe" -Recurse -Force | Out-Null

Set-Location "$workingDir"
Move-Item -Path "$workingDir/dist/weasyprint.exe" -Destination "$workingDir/weasyprint.exe"
Remove-Item -Path "$workingDir/dist"
Write-Host "*** Downloading python (https://github.com/indygreg/python-build-standalone)"
Invoke-WebRequest -Uri "https://github.com/astral-sh/python-build-standalone/releases/download/20260408/cpython-3.13.13+20260408-x86_64-pc-windows-msvc-install_only.tar.gz" -OutFile "$workingDir/python.tar.gz"
Write-Host "*** Extracting python"
Invoke-Expression "tar -xvzf $workingDir/python.tar.gz -C $workingDir"
Remove-Item "$workingDir/python.tar.gz" -Recurse -Force | Out-Null

Write-Host "*** Installing weasyprint dependencies"
Invoke-Expression "$workingDir\msys64\usr\bin\bash -lc 'pacman -S mingw-w64-x86_64-pango mingw-w64-x86_64-sed --noconfirm'"

Write-Host "*** Remove python.exe to avoid conflicts with msys2 python"
Remove-Item "$workingDir\msys64\mingw64\bin\python.exe"

Write-Host "*** Installing weasyprint and pyinstaller"
Invoke-Expression "$workingDir\python\python.exe -m pip install weasyprint==68.1 pyinstaller"

Write-Host "*** Patching weasyprint __main__.py to fix imports"
Invoke-Expression "$workingDir\msys64\mingw64\bin\sed -i 's/^from \. /from weasyprint /' $workingDir/python/Lib/site-packages/weasyprint/__main__.py"
Invoke-Expression "$workingDir\msys64\mingw64\bin\sed -i 's/^from \./from weasyprint\./' $workingDir/python/Lib/site-packages/weasyprint/__main__.py"
$Env:PATH = "$workingDir\msys64\mingw64\bin;$Env:PATH"

Write-Host "*** Building weasyprint executable"
Invoke-Expression "$workingDir\python\python.exe -m PyInstaller $workingDir/python/Lib/site-packages/weasyprint/__main__.py -n weasyprint -D"

Write-Host "*** Cleaning up python and msys2 environments for testing weasyprint executable"
Remove-Item "$workingDir/python" -Recurse -Force | Out-Null
Remove-Item "$workingDir/msys64" -Recurse -Force | Out-Null

Set-Location "./dist/"
Move-Item -Path "./weasyprint" -Destination "./weasyprint-windows"
New-Item -Path "version-$version"

Set-Location "./weasyprint-windows"
Write-Host "*** Testing weasyprint"
Invoke-Expression ".\weasyprint.exe --info"
New-Item -Path "$workingDir/version-$version"
Set-Location "../"

Set-Location "../"
Write-Host "*** Create archive $assets/standalone-windows-64.zip"
Compress-Archive -Path "$workingDir/*" -DestinationPath "$assets/standalone-windows-64.zip" -CompressionLevel "Optimal" -Force
Compress-Archive -Path "./*" -DestinationPath "$assets/standalone-windows-64.zip" -CompressionLevel "Optimal" -Force

Set-Location "../"
Write-Host "*** Clean up dist and build directories"
Remove-Item -Path "./dist" -Recurse -Force | Out-Null
Remove-Item -Path "./build" -Recurse -Force | Out-Null
15 changes: 11 additions & 4 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,23 @@ Check here for the answer: <https://stackoverflow.com/questions/67607643/what-do

### Windows (build-on-windows.ps1 does approximately this)

* Download the Windows standalone binary https://github.com/Kozea/WeasyPrint/releases
* Pack it into the resources zip for Windows
Basically it does the same thing as the original exe generation of weasyprint does (https://github.com/Kozea/WeasyPrint/blob/main/.github/workflows/exe.yml), but wrapped into a ps1 script and generating a one directory solution instead a one file solution. Here are the steps:

* Installing a msys2 environment (https://www.msys2.org)
* Installing python3 (https://github.com/indygreg/python-build-standalone) and all the dependencies
* Installing weasyprint and pyinstaller using pip
* Use pyinstaller to create a standalone executable for Windows (https://pyinstaller.org/en/stable/usage.html#cmdoption-D)
* Get rid of the python and msys2 files for testing
* Chek the newly created executable to make sure it works and has all the needed dependencies
* Pack the executable into the resources zip for Windows

### Linux (build-on-linux.ps1 does approximately this)

* Starting a docker image with an Ubunut 22.04
* Update the image to the latest packages
* Installing python3 and all the dependencies for weasyprint inside the docker image
* Install weasyprint and pyinstaller using pip
* Use pyinstaller to create a standalone executable for Linux (https://pyinstaller.org/en/stable/usage.html#creating-a-one-file-bundle)
* Installing weasyprint and pyinstaller using pip
* Use pyinstaller to create a standalone executable for Linux (https://pyinstaller.org/en/stable/usage.html#cmdoption-D)
* Chek the newly created executable in a new clean docker image to make sure it works and has all the needed dependencies
* Pack the executable into the resources zip for Linux

Expand Down
8 changes: 4 additions & 4 deletions src/Weasyprint.Wrapped/Printer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,12 @@ private Command BuildOsSpecificCommand()
Command command;
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
command = Cli
.Wrap($"{workingFolder}/weasyprint.exe")
.WithWorkingDirectory($"{workingFolder}");
.Wrap($"{workingFolder}/weasyprint-windows/weasyprint.exe")
.WithWorkingDirectory($"{workingFolder}/weasyprint-windows");
else
command = Cli
.Wrap($"{workingFolder}/weasyprint-linux")
.WithWorkingDirectory($"{workingFolder}");
.Wrap($"{workingFolder}/weasyprint-linux/weasyprint")
.WithWorkingDirectory($"{workingFolder}/weasyprint-linux");

return command;
}
Expand Down
Loading