--- - name: Packages needed to build the front-end ansible.builtin.apt: name: - build-essential - pkg-config # The only C libraries the binary links: everything else - X11, Wayland, EGL, # GL - is dlopen'd at runtime by winit and glutin, so it is not needed to build. - libfontconfig1-dev - libfreetype-dev - curl # Runtime, not build: winit and glutin dlopen all of these, so they never show # up in `ldd` and the binary links happily without them - it then aborts on # first run with "Library libxkbcommon-x11.so could not be loaded". - libxkbcommon0 - libxkbcommon-x11-0 - libx11-xcb1 - libxcb-xkb1 - libxcursor1 - libxi6 - libxrandr2 - libgl1 - libegl1 - libgles2 # The design uses emoji as iconography - the shelf badges, the figurine marker, # the scene sparkle. Raspbian ships no font that has them, so without these they # render as empty boxes. Symbola is the monochrome fallback for the glyphs Noto # does not cover. - fonts-noto-color-emoji - fonts-symbola cache_valid_time: 7200 - name: Check for a rust toolchain ansible.builtin.stat: path: /root/.cargo/bin/cargo register: pi_slint_frontend_cargo - name: Fetch the rustup installer ansible.builtin.get_url: url: https://sh.rustup.rs dest: /tmp/rustup-init.sh mode: "0755" when: not pi_slint_frontend_cargo.stat.exists - name: Install the rust toolchain # Debian 12 ships rustc 1.63, which is far too old for Slint, so this comes from # rustup rather than apt. ansible.builtin.command: cmd: "/tmp/rustup-init.sh -y --profile minimal --default-toolchain {{ pi_slint_frontend_toolchain }}" creates: /root/.cargo/bin/cargo when: not pi_slint_frontend_cargo.stat.exists - name: Check the checkout has a slint-frontend ansible.builtin.stat: path: "{{ pi_slint_frontend_root }}/Cargo.toml" register: pi_slint_frontend_manifest when: not ansible_check_mode - name: Fail on a checkout without the front-end ansible.builtin.fail: msg: >- {{ musicmouse_version }} has no slint-frontend/, so it predates the native front-end. Point musicmouse_version at a branch that has it, or set mediapi_install_slint_frontend to false for this host. when: not ansible_check_mode and not pi_slint_frontend_manifest.stat.exists - name: Fail when the checkout's commit is unknown # This role builds what pi_musicmouse checked out, and reuses its record of which # commit that was. With mediapi_install_kidsmusic false that role never ran, so # there is no checkout to build and no commit to stamp - and the stamp comparison # below would compare against an empty string and rebuild on every run. ansible.builtin.fail: msg: >- pi_slint_frontend needs pi_musicmouse to have run first - it builds the slint-frontend/ inside the checkout that role owns. Set mediapi_install_kidsmusic to true for this host, or mediapi_install_slint_frontend to false. when: not ansible_check_mode and pi_musicmouse_commit | length == 0 - name: Read which commit the binary was built from # The same guard pi_musicmouse uses for the venv and the web dist, for the same # reason: hanging a 40-minute build off "the checkout changed" strands the device # when a run fails after the checkout, because the next run finds it current and # rebuilds nothing. ansible.builtin.command: cmd: "cat {{ pi_slint_frontend_root }}/.built-commit" register: pi_slint_frontend_stamp changed_when: false failed_when: false - name: Build the front-end # First build takes roughly 40 minutes on a Pi 4 - 570 crates, two jobs. Later ones # are incremental. `async` keeps the SSH connection from idling out underneath it. ansible.builtin.command: cmd: >- nice -n 10 /root/.cargo/bin/cargo build --release --no-default-features --features {{ pi_slint_frontend_features }} -j {{ pi_slint_frontend_jobs }} chdir: "{{ pi_slint_frontend_root }}" environment: # The committed release profile is tuned for a workstation. Thin LTO with # codegen-units=1 is a memory risk on 1.8 GB and buys nothing that matters here. CARGO_PROFILE_RELEASE_LTO: "false" CARGO_PROFILE_RELEASE_CODEGEN_UNITS: "16" PATH: "/root/.cargo/bin:{{ ansible_facts['env']['PATH'] }}" async: 7200 poll: 30 changed_when: true when: >- not ansible_check_mode and pi_slint_frontend_stamp.stdout | trim != pi_musicmouse_commit - name: Record which commit the binary was built from ansible.builtin.copy: content: "{{ pi_musicmouse_commit }}\n" dest: "{{ pi_slint_frontend_root }}/.built-commit" mode: "0644" when: not ansible_check_mode - name: Find the X session user's home directory ansible.builtin.getent: database: passwd key: "{{ pi_slint_frontend_x_user }}" - name: Note where the X cookie lives ansible.builtin.set_fact: pi_slint_frontend_x_home: "{{ ansible_facts.getent_passwd[pi_slint_frontend_x_user][4] }}" - name: Install the launcher ansible.builtin.template: src: musikdelfin.sh.j2 dest: /usr/local/bin/musikdelfin mode: "0755" - name: Install the systemd unit # Installed but deliberately not enabled: this is the thing under test, and the # kiosk browser is still what the device shows on boot. Start it by hand - # `systemctl start musikdelfin` - or run /usr/local/bin/musikdelfin over SSH. ansible.builtin.template: src: musikdelfin.service.j2 dest: /etc/systemd/system/musikdelfin.service mode: "0644" notify: Reload systemd