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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Preserve verbatim dependency patch context and recorded tool output.
patches/*.patch -whitespace
openspec/changes/archive/**/evidence/*.txt -whitespace
41 changes: 13 additions & 28 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Build and test runtime image
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.deploy
platforms: linux/amd64
load: true
tags: ptouch-deploy:check
- name: Smoke - IPP jobs and isolated socket capture
run: |
set -e
sudo apt-get update && sudo apt-get install -y --no-install-recommends cups-ipp-utils
python3 scripts/smoke-image.py ptouch-deploy:check
- name: Log in to GHCR
if: github.event_name != 'pull_request'
uses: docker/login-action@v4
Expand All @@ -28,34 +41,6 @@ jobs:
tags: |
type=raw,value=edge,enable=${{ github.ref == 'refs/heads/main' }}
type=sha
- name: Build (PR = load, no push)
if: github.event_name == 'pull_request'
uses: docker/build-push-action@v6
with:
context: .
file: Dockerfile.deploy
platforms: linux/amd64
load: true
tags: ptouch-deploy:pr
- name: Smoke (PR) - no hardware, no sink (Codex #2/#9)
if: github.event_name == 'pull_request'
run: |
set -e
sudo apt-get update && sudo apt-get install -y --no-install-recommends cups-ipp-utils
cleanup() { docker rm -f ptouch-smoke 2>/dev/null || true; }
trap cleanup EXIT
# socket:// registers the printer without a listener; attributes query needs no sink
docker run -d --name ptouch-smoke -p 18000:8000 \
-e PTOUCH_DEVICE_URI=socket://127.0.0.1:9100 ptouch-deploy:pr
for i in $(seq 1 15); do
if ipptool -t ipp://127.0.0.1:18000/ipp/print/ptouch \
./spikes/fixtures/get-printer-attributes.test >/tmp/ptouch-smoke-ipp.log 2>&1; then
echo "IPP OK"; break; fi
sleep 1
done
ipptool -tv ipp://127.0.0.1:18000/ipp/print/ptouch \
./spikes/fixtures/get-printer-attributes.test
docker logs ptouch-smoke
- name: Build + push (main)
if: github.event_name != 'pull_request'
uses: docker/build-push-action@v6
Expand Down
88 changes: 58 additions & 30 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ project(ptouch_print_server C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_compile_options(-Wall -Wextra)
option(PTOUCH_CORE_ONLY "Build only the hardware-free core and capture tests" OFF)

# Pure, hardware-free core (libc only). The PAPPL + raw-libusb adapter (M2) links this.
add_library(ptcore STATIC
Expand All @@ -18,34 +19,61 @@ target_include_directories(ptcore PUBLIC src)
enable_testing()
add_subdirectory(tests)

# The PAPPL app (M2+) builds only where PAPPL + libusb + libpng are present (the container).
# On the Mac (no PAPPL) the pure core + tests still build.
find_package(PkgConfig)
if(PkgConfig_FOUND)
pkg_check_modules(PAPPL pappl)
pkg_check_modules(USB libusb-1.0)
pkg_check_modules(PNG libpng) # our image/png filter (#40) calls libpng directly
if(PAPPL_FOUND AND USB_FOUND)
# Optional live transport for the test-only probe, using the existing scheme.
target_sources(ptouch-cut-probe PRIVATE src/device_usb.c)
target_compile_definitions(ptouch-cut-probe PRIVATE PT_PROBE_TRANSPORT=1)
target_link_libraries(ptouch-cut-probe PRIVATE ${PAPPL_LIBRARIES} ${USB_LIBRARIES})
target_include_directories(ptouch-cut-probe PRIVATE ${PAPPL_INCLUDE_DIRS} ${USB_INCLUDE_DIRS})
target_link_directories(ptouch-cut-probe PRIVATE ${PAPPL_LIBRARY_DIRS} ${USB_LIBRARY_DIRS})
target_compile_options(ptouch-cut-probe PRIVATE ${PAPPL_CFLAGS_OTHER})
endif()
if(PAPPL_FOUND AND USB_FOUND AND PNG_FOUND)
add_executable(test_driver tests/test_driver.c src/filter_png.c)
target_link_libraries(test_driver PRIVATE ptcore ${PAPPL_LIBRARIES} ${PNG_LIBRARIES})
target_include_directories(test_driver PRIVATE ${PAPPL_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
target_link_directories(test_driver PRIVATE ${PAPPL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
target_compile_options(test_driver PRIVATE ${PAPPL_CFLAGS_OTHER})
add_test(NAME driver_finishings COMMAND test_driver)
set_tests_properties(driver_finishings PROPERTIES TIMEOUT 90)
add_executable(ptouch-app src/main.c src/driver.c src/device_usb.c src/filter_png.c)
target_link_libraries(ptouch-app PRIVATE ptcore ${PAPPL_LIBRARIES} ${USB_LIBRARIES} ${PNG_LIBRARIES})
target_include_directories(ptouch-app PRIVATE ${PAPPL_INCLUDE_DIRS} ${USB_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
target_link_directories(ptouch-app PRIVATE ${PAPPL_LIBRARY_DIRS} ${USB_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
target_compile_options(ptouch-app PRIVATE ${PAPPL_CFLAGS_OTHER})
endif()
# The default build must include the app and adapter tests. Opt into the core
# explicitly when building on a machine without the printer dependencies.
if(NOT PTOUCH_CORE_ONLY)
find_package(PkgConfig REQUIRED)
pkg_check_modules(PAPPL REQUIRED pappl)
pkg_check_modules(USB REQUIRED libusb-1.0)
pkg_check_modules(PNG REQUIRED libpng)
# Optional live transport for the test-only probe, using the existing scheme.
target_sources(ptouch-cut-probe PRIVATE src/device_usb.c)
target_compile_definitions(ptouch-cut-probe PRIVATE PT_PROBE_TRANSPORT=1)
target_link_libraries(ptouch-cut-probe PRIVATE ${PAPPL_LIBRARIES} ${USB_LIBRARIES})
target_include_directories(ptouch-cut-probe PRIVATE ${PAPPL_INCLUDE_DIRS} ${USB_INCLUDE_DIRS})
target_link_directories(ptouch-cut-probe PRIVATE ${PAPPL_LIBRARY_DIRS} ${USB_LIBRARY_DIRS})
target_compile_options(ptouch-cut-probe PRIVATE ${PAPPL_CFLAGS_OTHER})
add_executable(test_driver tests/test_driver.c src/filter_png.c)
target_link_libraries(test_driver PRIVATE ptcore ${PAPPL_LIBRARIES} ${PNG_LIBRARIES})
target_include_directories(test_driver PRIVATE ${PAPPL_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
target_link_directories(test_driver PRIVATE ${PAPPL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
target_compile_options(test_driver PRIVATE ${PAPPL_CFLAGS_OTHER})
add_test(NAME driver_finishings COMMAND test_driver)
set_tests_properties(driver_finishings PROPERTIES TIMEOUT 90)
add_executable(test_pappl_raster tests/test_pappl_raster.c)
target_link_libraries(test_pappl_raster PRIVATE ${PAPPL_LIBRARIES} ${PNG_LIBRARIES})
target_include_directories(test_pappl_raster PRIVATE ${PAPPL_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
target_link_directories(test_pappl_raster PRIVATE ${PAPPL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
target_compile_options(test_pappl_raster PRIVATE ${PAPPL_CFLAGS_OTHER})
add_test(NAME pappl_raster COMMAND test_pappl_raster)
set_tests_properties(pappl_raster PROPERTIES TIMEOUT 90)
add_executable(test_pappl_finishings tests/test_pappl_finishings.c)
target_link_libraries(test_pappl_finishings PRIVATE ${PAPPL_LIBRARIES})
target_include_directories(test_pappl_finishings PRIVATE ${PAPPL_INCLUDE_DIRS})
target_link_directories(test_pappl_finishings PRIVATE ${PAPPL_LIBRARY_DIRS})
target_compile_options(test_pappl_finishings PRIVATE ${PAPPL_CFLAGS_OTHER})
add_test(NAME pappl_finishings COMMAND test_pappl_finishings)
set_tests_properties(pappl_finishings PROPERTIES TIMEOUT 90)
add_executable(test_png_geometry tests/test_png_geometry.c src/driver.c src/filter_png.c)
target_link_libraries(test_png_geometry PRIVATE ptcore ${PAPPL_LIBRARIES} ${PNG_LIBRARIES})
target_include_directories(test_png_geometry PRIVATE ${PAPPL_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
target_link_directories(test_png_geometry PRIVATE ${PAPPL_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
target_compile_options(test_png_geometry PRIVATE ${PAPPL_CFLAGS_OTHER})
add_test(NAME png_geometry COMMAND test_png_geometry)
set_tests_properties(png_geometry PROPERTIES TIMEOUT 90)
add_executable(test_device_usb tests/test_device_usb.c)
target_link_libraries(test_device_usb PRIVATE ptcore ${PAPPL_LIBRARIES} ${USB_LIBRARIES})
target_include_directories(test_device_usb PRIVATE ${PAPPL_INCLUDE_DIRS} ${USB_INCLUDE_DIRS})
target_link_directories(test_device_usb PRIVATE ${PAPPL_LIBRARY_DIRS} ${USB_LIBRARY_DIRS})
target_compile_options(test_device_usb PRIVATE ${PAPPL_CFLAGS_OTHER})
add_test(NAME device_usb COMMAND test_device_usb)
# Test assertions include fixture setup and must stay active in Release too.
foreach(test_target test_driver test_pappl_raster test_pappl_finishings test_png_geometry test_device_usb)
target_compile_options(${test_target} PRIVATE -UNDEBUG)
endforeach()
add_executable(ptouch-app src/main.c src/driver.c src/device_usb.c src/filter_png.c)
target_link_libraries(ptouch-app PRIVATE ptcore ${PAPPL_LIBRARIES} ${USB_LIBRARIES} ${PNG_LIBRARIES})
target_include_directories(ptouch-app PRIVATE ${PAPPL_INCLUDE_DIRS} ${USB_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
target_link_directories(ptouch-app PRIVATE ${PAPPL_LIBRARY_DIRS} ${USB_LIBRARY_DIRS} ${PNG_LIBRARY_DIRS})
target_compile_options(ptouch-app PRIVATE ${PAPPL_CFLAGS_OTHER})
endif()
12 changes: 10 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,22 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
autoconf automake libtool gettext autopoint \
libusb-1.0-0-dev libgd-dev libpng-dev libjpeg-dev zlib1g-dev \
libcups2-dev libcupsimage2-dev cups-ipp-utils usbutils \
libssl-dev libavahi-client-dev \
libssl-dev libavahi-client-dev libgnutls28-dev libkrb5-dev \
python3 python3-pil \
&& rm -rf /var/lib/apt/lists/*

# PAPPL from source (not packaged in bookworm). Pinned to the 1.4.x line, which
# targets CUPS 2.x (bookworm's libcups2-dev 2.4); master needs libcups >= 2.5.
# Retain Debian security fixes while correcting only raster EOF reporting.
COPY patches/cups-2.4.2-deb12u9-raster.patch /tmp/cups-raster.patch
COPY scripts/build-cups.sh /tmp/build-cups.sh
RUN /tmp/build-cups.sh /tmp/cups-raster.patch
COPY patches/pappl-1.4.11-raster.patch /tmp/pappl-raster.patch
COPY patches/pappl-1.4.11-finishings.patch /tmp/pappl-finishings.patch
RUN git clone --depth 1 --branch v1.4.11 https://github.com/michaelrsweet/pappl /tmp/pappl \
&& cd /tmp/pappl && ./configure && make && make install && ldconfig \
&& cd /tmp/pappl && patch --batch --forward --fuzz=0 -p1 < /tmp/pappl-raster.patch \
&& patch --batch --forward --fuzz=0 -p1 < /tmp/pappl-finishings.patch \
&& ./configure && make && make install && ldconfig \
&& rm -rf /tmp/pappl

WORKDIR /work
25 changes: 20 additions & 5 deletions Dockerfile.deploy
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,25 @@
# ---- build stage: PAPPL + ptouch-app ----
FROM debian:bookworm AS build
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential cmake pkg-config git ca-certificates \
build-essential cmake pkg-config git ca-certificates python3 \
libusb-1.0-0-dev libpng-dev libjpeg-dev zlib1g-dev \
libcups2-dev libcupsimage2-dev libssl-dev libavahi-client-dev \
libcups2-dev libcupsimage2-dev libssl-dev libavahi-client-dev libgnutls28-dev libkrb5-dev \
&& rm -rf /var/lib/apt/lists/*
# Retain Debian security fixes while correcting only raster EOF reporting.
COPY patches/cups-2.4.2-deb12u9-raster.patch /tmp/cups-raster.patch
COPY scripts/build-cups.sh /tmp/build-cups.sh
RUN /tmp/build-cups.sh /tmp/cups-raster.patch
COPY patches/pappl-1.4.11-raster.patch /tmp/pappl-raster.patch
COPY patches/pappl-1.4.11-finishings.patch /tmp/pappl-finishings.patch
RUN git clone --depth 1 --branch v1.4.11 https://github.com/michaelrsweet/pappl /tmp/pappl \
&& cd /tmp/pappl && ./configure && make && make install && ldconfig \
&& cd /tmp/pappl && patch --batch --forward --fuzz=0 -p1 < /tmp/pappl-raster.patch \
&& patch --batch --forward --fuzz=0 -p1 < /tmp/pappl-finishings.patch \
&& ./configure && make && make install && ldconfig \
&& rm -rf /tmp/pappl
WORKDIR /src
COPY . .
RUN cmake -S . -B build-app && cmake --build build-app --target ptouch-app \
RUN cmake -S . -B build-app -DPTOUCH_CORE_ONLY=OFF && cmake --build build-app \
&& ctest --test-dir build-app --output-on-failure \
&& install -Dm755 build-app/ptouch-app /out/usr/local/bin/ptouch-app

# ---- runtime stage: slim ----
Expand All @@ -21,7 +30,13 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
libpng16-16 libjpeg62-turbo zlib1g libssl3 \
avahi-daemon dbus ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# PAPPL shared libs (SONAME chain) + the app
# Patched ABI-compatible CUPS and PAPPL libraries (including SONAME links).
COPY --from=build /usr/local/lib/libcups.so* /usr/local/lib/
COPY --from=build /usr/local/lib/libcupsimage.so* /usr/local/lib/
COPY --from=build /usr/local/share/ptouch/cups-source-version /usr/local/share/ptouch/cups-source-version
# Fail rather than replace a newer runtime security revision with cached libraries.
RUN test "$(dpkg-query -W -f='${source:Version}' libcups2)" = "$(cat /usr/local/share/ptouch/cups-source-version)"
# PAPPL shared libs + the app
COPY --from=build /usr/local/lib/libpappl.so* /usr/local/lib/
COPY --from=build /out/usr/local/bin/ptouch-app /usr/local/bin/ptouch-app
RUN ldconfig
Expand Down
Loading
Loading