From f6a169afaa1f19ecc3a442554293f4d15ad08e27 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Fri, 2 Oct 2026 23:14:18 +0200 Subject: [PATCH] Build irserver on the device on a 64-bit or trixie userland The shipped irserver is a 32-bit ARM binary linked against libzip.so.4, which only exists on armhf with Debian 12 or older. On a 64-bit userland or trixie it cannot run, so the role now compiles the bundled 2019 sources on the device there, with GCC 14's new hard errors (implicit declarations, implicit int, pointer/int mix-ups) downgraded rather than the old code patched. Picked from `dpkg --print-architecture` and the distribution version; `pi_irserver_build_from_source: true|false` forces it. Co-Authored-By: Claude Opus 5.5 --- roles/pi_irserver/README.md | 6 ++++ roles/pi_irserver/defaults/main.yml | 6 ++++ roles/pi_irserver/tasks/build.yml | 44 +++++++++++++++++++++++++++++ roles/pi_irserver/tasks/main.yml | 19 ++++++++++++- 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 roles/pi_irserver/defaults/main.yml create mode 100644 roles/pi_irserver/tasks/build.yml diff --git a/roles/pi_irserver/README.md b/roles/pi_irserver/README.md index fea98a7..60e4352 100644 --- a/roles/pi_irserver/README.md +++ b/roles/pi_irserver/README.md @@ -3,3 +3,9 @@ Installs and configures `irserver` (with a Hauppauge remote config) as an autostarted systemd service for IR remote control, and registers it with `pi_sysdweb`. + +The shipped `files/irserver` is a 32-bit ARM binary needing `libzip.so.4`, so it is used +only on an armhf userland with Debian 12 or older. On a 64-bit userland or trixie it is +compiled on the device from `files/irserver-src.tar.gz` instead (the 2019 sources need +GCC's newer hard errors downgraded; see `tasks/build.yml`). Automatic; override with +`pi_irserver_build_from_source: true|false`. diff --git a/roles/pi_irserver/defaults/main.yml b/roles/pi_irserver/defaults/main.yml new file mode 100644 index 0000000..a120b81 --- /dev/null +++ b/roles/pi_irserver/defaults/main.yml @@ -0,0 +1,6 @@ +--- +# The shipped files/irserver is a 32-bit ARM binary linked against libzip.so.4 (Debian +# bookworm's libzip4 on armhf). It cannot run on a 64-bit userland, and trixie no longer +# ships libzip.so.4 at all. "auto" uses it only on armhf + Debian <= 12 and compiles +# files/irserver-src.tar.gz on the device everywhere else; set true/false to force. +pi_irserver_build_from_source: auto diff --git a/roles/pi_irserver/tasks/build.yml b/roles/pi_irserver/tasks/build.yml new file mode 100644 index 0000000..b6d839e --- /dev/null +++ b/roles/pi_irserver/tasks/build.yml @@ -0,0 +1,44 @@ +--- +- name: Install irserver build dependencies + ansible.builtin.apt: + name: + - build-essential + - libzip-dev + cache_valid_time: 7200 + +- name: Create irserver source directory + ansible.builtin.file: + path: /opt/irserver-src + state: directory + mode: "0755" + +- name: Unpack irserver source + ansible.builtin.unarchive: + src: irserver-src.tar.gz + dest: /opt/irserver-src + creates: /opt/irserver-src/makefile + +- name: Build irserver + # The 2019 sources predate modern C: GCC 14 rejects implicit function declarations, + # implicit int and a few pointer/int mix-ups as hard errors. They are old but working + # code, so the errors are downgraded rather than the source patched. libzip comes from + # libzip-dev (`irserver_arm_noccf` links -lzip); the bundled 32-bit static libzip*.a + # are not used. `arm/` is where the makefile puts its objects. + ansible.builtin.shell: + cmd: | + set -e + mkdir -p arm + make irserver_arm_noccf LDFLAGS="-lzip" \ + CFLAGS="-w -Wno-error=implicit-function-declaration -Wno-error=int-conversion \ + -Wno-error=incompatible-pointer-types -Wno-error=return-mismatch \ + -Wno-error=implicit-int" + chdir: /opt/irserver-src + creates: /opt/irserver-src/irserver + +- name: Install built irserver + ansible.builtin.copy: + src: /opt/irserver-src/irserver + dest: /usr/bin/irserver + mode: u+rx + remote_src: true + notify: Restart irserver diff --git a/roles/pi_irserver/tasks/main.yml b/roles/pi_irserver/tasks/main.yml index 81c34e4..dcec9a5 100644 --- a/roles/pi_irserver/tasks/main.yml +++ b/roles/pi_irserver/tasks/main.yml @@ -1,10 +1,27 @@ --- -- name: Copy irserver +- name: Get the userland architecture + # See pi_squeezelite_custom: the kernel's architecture is not the userland's. + ansible.builtin.command: dpkg --print-architecture + register: pi_irserver_dpkg_arch + changed_when: false + check_mode: false # read-only +- name: Decide between the prebuilt binary and a build on the device + ansible.builtin.set_fact: + pi_irserver_build: >- + {{ (pi_irserver_build_from_source | string | lower == 'true') + or (pi_irserver_build_from_source | string | lower == 'auto' + and (pi_irserver_dpkg_arch.stdout | trim != 'armhf' + or ansible_facts.distribution_major_version | int >= 13)) }} +- name: Copy prebuilt irserver (32-bit ARM binary) ansible.builtin.copy: src: irserver dest: /usr/bin/irserver mode: u+rx notify: Restart irserver + when: not pi_irserver_build +- name: Build irserver from source (needed on a 64-bit userland, see README) + ansible.builtin.include_tasks: build.yml + when: pi_irserver_build - name: Make config dir for remotes ansible.builtin.file: path: /usr/bin/remotes