Skip to content

dev(nix): enable macOS cross-compilation#518

Merged
OGKevin merged 4 commits into
masterfrom
ogkevin/push/unpukymmnooo
May 26, 2026
Merged

dev(nix): enable macOS cross-compilation#518
OGKevin merged 4 commits into
masterfrom
ogkevin/push/unpukymmnooo

Conversation

@OGKevin

@OGKevin OGKevin commented May 26, 2026

Copy link
Copy Markdown
Owner

Add support for downloading, installing, and running the Linaro compiler and patchelf toolchains on macOS (Darwin) hosts.

Ref: baskerville/plato#417

Change-Id: c92ac710cc19af4426704c1619dd2918
Change-Id-Short: nqxpnsyznnyq

Add support for downloading, installing, and running the Linaro compiler
and patchelf toolchains on macOS (Darwin) hosts.

Change-Id: c92ac710cc19af4426704c1619dd2918
Change-Id-Short: nqxpnsyznnyq
@OGKevin OGKevin self-assigned this May 26, 2026
@coderabbitai coderabbitai Bot added the dependencies Pull requests that update a dependency file label May 26, 2026
@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: fb7cad31-bec6-4b09-b012-d164f474668e

📥 Commits

Reviewing files that changed from the base of the PR and between f66d6ec and 53856d2.

📒 Files selected for processing (2)
  • xtask/src/tasks/build_kobo.rs
  • xtask/src/tasks/util/thirdparty.rs
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Prefer ? over unwrap() / expect() in library and app code
Use thiserror for custom error types and anyhow for ad-hoc errors in Rust
Use iterators over index-based loops in Rust
Use &str over String in function parameters when ownership is not needed
Prefer borrowing over cloning in Rust
Inline expressions directly into struct fields—avoid intermediate bindings solely to pass them into a struct literal
Avoid unsafe unless required and documented in Rust
Avoid premature collect() in Rust—keep iterators lazy
Ensure Rust code compiles without warnings
Prefer newtype wrappers over raw primitives for domain concepts (e.g., Fingerprint(String) instead of bare String)
Wrap String, i64, and similar primitives when the value represents a specific domain concept (fingerprints, file kinds, identifiers, …)
Implement Display, FromStr, and other standard traits on newtypes so they stay ergonomic
Match on enum variants instead of string comparisons—the compiler catches missing arms
Use structured fields with the tracing crate in Rust—never use string formatting for log data
Use direct field formatting for primitives (int, float, bool) with tracing crate
Use Display % formatter with tracing crate for types implementing Display
Use Debug ? formatter with tracing crate for types implementing Debug
Use debug log level for development and troubleshooting detail
Use info log level for important runtime events
Use warn log level for recoverable issues (retries, fallbacks)
Use error log level for failures requiring attention
Return domain types directly from sqlx queries instead of parsing primitives after the fact
Implement sqlx::Type<sqlx::Sqlite>, sqlx::Encode<sqlx::Sqlite>, and sqlx::Decode<sqlx::Sqlite> traits for custom types used in sqlx queries
Use sqlx type-override syntax with column aliases (e.g., AS "fingerprint: Fp") so the macro deserializes into domain types directly
When the orphan rule prevents implem...

Files:

  • xtask/src/tasks/util/thirdparty.rs
  • xtask/src/tasks/build_kobo.rs
🔇 Additional comments (2)
xtask/src/tasks/util/thirdparty.rs (1)

28-29: LGTM!

Also applies to: 46-49, 53-54

xtask/src/tasks/build_kobo.rs (1)

11-13: LGTM!

Also applies to: 100-100


Walkthrough

Adds macOS support for Kobo cross-compilation: the Linaro toolchain derivation is platform-conditional for Darwin, devenv packaging and help text are updated, build tasks/scripts run unconditionally on Linux and macOS, and third-party build invocations receive explicit cross-compilation environment variables.

Changes

Kobo macOS Cross-Compilation Support

Layer / File(s) Summary
Linaro cross-compiler macOS support
devenv.nix
The Linaro toolchain derivation becomes platform-conditional: Linux uses the existing Linaro tarball with autoPatchelfHook; macOS downloads a Darwin-compatible archive and disables ELF patching/stripping/fixups.
Development environment updates
devenv.nix
Rust toolchain wrapper resolves and replaces symlinked $out/lib with a real directory and repopulates via lndir. linaroToolchain moved into main package set; patchelf remains Linux-only.
Build workflow and platform checks
devenv.nix, xtask/src/tasks/build_kobo.rs, xtask/src/tasks/setup_native.rs
tasks."build:kobo" and scripts.cadmus-build-kobo run unconditionally; xtask platform gate is relaxed to allow Linux & macOS and user-facing setup instructions updated.
Third-party build scripts and cross env
thirdparty/mupdf/build-kobo.sh, xtask/src/tasks/util/thirdparty.rs
MuPDF build script deletes stale build/ dir before make. SONAME extraction uses arm-linux-gnueabihf-readelf. build_libraries() passes explicit cross-compilation env (AR, AS, STRIP, RANLIB, LD, CC_FOR_BUILD, CXX_FOR_BUILD, CC_BUILD) to ./build-kobo.sh.
Command documentation and xtask updates
xtask/src/lib.rs, xtask/src/tasks/build_kobo.rs, xtask/src/tasks/setup_native.rs
xtask command list, variant doc comment, and platform documentation updated to state build-kobo targets Linux & macOS instead of Linux-only.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested labels

documentation, dependencies

Poem

🌲 Toolchains stretch from Linux shore to Mac,
A symlink fixed, a lndir unpack,
Scripts now run on both shores hand in hand,
Cross-env sealed so builds understand,
One command, two homes — the Kobo's back on track.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'dev(nix): enable macOS cross-compilation' follows Conventional Commits format with a type, scope, and clear description of the main change.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

Review ran into problems

🔥 Problems

Stopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a @coderabbit review after the pipeline has finished.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
xtask/src/tasks/build_kobo.rs (1)

9-12: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Docstring is now outdated.

The module docstring still says the Linaro toolchain "is only available on Linux" and that "The task exits with a clear error on macOS." This no longer matches the implementation.

📝 Suggested fix
 //! ## Platform requirement
 //!
-//! Cross-compilation requires the Linaro ARM toolchain
-//! (`arm-linux-gnueabihf-gcc` and friends) which is only available on Linux.
-//! The task exits with a clear error on macOS.
+//! Cross-compilation requires the Linaro ARM toolchain
+//! (`arm-linux-gnueabihf-gcc` and friends) which is available on Linux and macOS.
+//! On other platforms, the task exits with a clear error.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@xtask/src/tasks/build_kobo.rs` around lines 9 - 12, The module docstring at
the top of build_kobo.rs is outdated: remove or rewrite the lines claiming the
Linaro ARM toolchain "is only available on Linux" and that "The task exits with
a clear error on macOS" so it matches the current behavior; update the docstring
to state the actual requirement (cross-compilation needs the Linaro ARM
toolchain) and that the task performs a runtime check and emits a helpful error
if the toolchain is missing (refer to the top-of-file module docstring in
build_kobo.rs to locate and edit the text).
🧹 Nitpick comments (1)
devenv.nix (1)

149-153: 💤 Low value

Google Drive URL may be unreliable for CI builds.

Google Drive download links can be rate-limited, require CAPTCHA, or change without notice. If CI starts failing intermittently, consider mirroring this artifact to a more stable host (GitHub Releases, S3, etc.).

That said, if this is the only available Darwin-compatible Linaro build, it's understandable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@devenv.nix` around lines 149 - 153, The fetchurl entry using pkgs.fetchurl
for the artifact named "gcc-linaro-darwin.tar.bz2" points at an unstable Google
Drive download URL; replace this with a stable mirror (e.g., GitHub Releases,
S3, or a canonical distro mirror) and update the url and sha256 values
accordingly, or add a documented fallback/conditional that only uses the Google
Drive URL if no stable mirror exists; ensure you update the pkgs.fetchurl block
for the "gcc-linaro-darwin.tar.bz2" name and its sha256 to the values for the
chosen mirror.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@xtask/src/tasks/util/thirdparty.rs`:
- Line 59: The CI requires rustfmt formatting for the command invocation:
reformat the call to cmd::output so it follows multiline formatting rules (split
the arguments across lines) and run cargo fmt; specifically update the
cmd::output("arm-linux-gnueabihf-readelf", &["-d", so_path_str], libs_dir, &[])?
invocation in xtask::tasks::util::thirdparty.rs to a properly formatted
multiline form and then run cargo fmt to persist changes.

---

Outside diff comments:
In `@xtask/src/tasks/build_kobo.rs`:
- Around line 9-12: The module docstring at the top of build_kobo.rs is
outdated: remove or rewrite the lines claiming the Linaro ARM toolchain "is only
available on Linux" and that "The task exits with a clear error on macOS" so it
matches the current behavior; update the docstring to state the actual
requirement (cross-compilation needs the Linaro ARM toolchain) and that the task
performs a runtime check and emits a helpful error if the toolchain is missing
(refer to the top-of-file module docstring in build_kobo.rs to locate and edit
the text).

---

Nitpick comments:
In `@devenv.nix`:
- Around line 149-153: The fetchurl entry using pkgs.fetchurl for the artifact
named "gcc-linaro-darwin.tar.bz2" points at an unstable Google Drive download
URL; replace this with a stable mirror (e.g., GitHub Releases, S3, or a
canonical distro mirror) and update the url and sha256 values accordingly, or
add a documented fallback/conditional that only uses the Google Drive URL if no
stable mirror exists; ensure you update the pkgs.fetchurl block for the
"gcc-linaro-darwin.tar.bz2" name and its sha256 to the values for the chosen
mirror.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 0b4d40f0-9517-49e0-9797-a728489c30dc

📥 Commits

Reviewing files that changed from the base of the PR and between 45b03c6 and 1ec41de.

📒 Files selected for processing (6)
  • devenv.nix
  • thirdparty/mupdf/build-kobo.sh
  • xtask/src/lib.rs
  • xtask/src/tasks/build_kobo.rs
  • xtask/src/tasks/setup_native.rs
  • xtask/src/tasks/util/thirdparty.rs
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Prefer ? over unwrap() / expect() in library and app code
Use thiserror for custom error types and anyhow for ad-hoc errors in Rust
Use iterators over index-based loops in Rust
Use &str over String in function parameters when ownership is not needed
Prefer borrowing over cloning in Rust
Inline expressions directly into struct fields—avoid intermediate bindings solely to pass them into a struct literal
Avoid unsafe unless required and documented in Rust
Avoid premature collect() in Rust—keep iterators lazy
Ensure Rust code compiles without warnings
Prefer newtype wrappers over raw primitives for domain concepts (e.g., Fingerprint(String) instead of bare String)
Wrap String, i64, and similar primitives when the value represents a specific domain concept (fingerprints, file kinds, identifiers, …)
Implement Display, FromStr, and other standard traits on newtypes so they stay ergonomic
Match on enum variants instead of string comparisons—the compiler catches missing arms
Use structured fields with the tracing crate in Rust—never use string formatting for log data
Use direct field formatting for primitives (int, float, bool) with tracing crate
Use Display % formatter with tracing crate for types implementing Display
Use Debug ? formatter with tracing crate for types implementing Debug
Use debug log level for development and troubleshooting detail
Use info log level for important runtime events
Use warn log level for recoverable issues (retries, fallbacks)
Use error log level for failures requiring attention
Return domain types directly from sqlx queries instead of parsing primitives after the fact
Implement sqlx::Type<sqlx::Sqlite>, sqlx::Encode<sqlx::Sqlite>, and sqlx::Decode<sqlx::Sqlite> traits for custom types used in sqlx queries
Use sqlx type-override syntax with column aliases (e.g., AS "fingerprint: Fp") so the macro deserializes into domain types directly
When the orphan rule prevents implem...

Files:

  • xtask/src/tasks/build_kobo.rs
  • xtask/src/tasks/setup_native.rs
  • xtask/src/lib.rs
  • xtask/src/tasks/util/thirdparty.rs
🪛 GitHub Actions: Cargo / 69_format.txt
xtask/src/tasks/util/thirdparty.rs

[error] 56-59: cargo fmt --all --check failed (rustfmt formatting difference). Diff indicates missing multiline formatting for cmd::output(...) call around arm-linux-gnueabihf-readelf invocation.

🔇 Additional comments (10)
xtask/src/lib.rs (1)

24-24: LGTM!

Also applies to: 74-74

devenv.nix (5)

23-37: LGTM!


155-176: LGTM!


317-322: LGTM!


684-688: LGTM!


712-716: LGTM!

Also applies to: 792-801

xtask/src/tasks/build_kobo.rs (1)

103-108: LGTM!

xtask/src/tasks/setup_native.rs (1)

60-60: LGTM!

thirdparty/mupdf/build-kobo.sh (1)

6-6: LGTM!

xtask/src/tasks/util/thirdparty.rs (1)

409-419: LGTM!

Comment thread xtask/src/tasks/util/thirdparty.rs Outdated
@coderabbitai

coderabbitai Bot commented May 26, 2026

Copy link
Copy Markdown
Contributor

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • xtask/src/tasks/util/thirdparty.rs

Commit: f66d6ec9b6226d79118b06e1b3b3f6aaa769da24

The changes have been pushed to the ogkevin/push/unpukymmnooo branch.

Time taken: 5m 26s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@coderabbitai coderabbitai Bot removed the dependencies Pull requests that update a dependency file label May 26, 2026
@OGKevin

OGKevin commented May 26, 2026

Copy link
Copy Markdown
Owner Author

@copilot can you address the following:

Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @xtask/src/tasks/build_kobo.rs around lines 9 - 12, The module docstring at
the top of build_kobo.rs is outdated: remove or rewrite the lines claiming the
Linaro ARM toolchain "is only available on Linux" and that "The task exits with
a clear error on macOS" so it matches the current behavior; update the docstring
to state the actual requirement (cross-compilation needs the Linaro ARM
toolchain) and that the task performs a runtime check and emits a helpful error
if the toolchain is missing (refer to the top-of-file module docstring in
build_kobo.rs to locate and edit the text).

Copilot AI commented May 26, 2026

Copy link
Copy Markdown
Contributor

@copilot can you address the following:

Verify each finding against current code. Fix only still-valid issues, skip the
...

Addressed in d66ea45. I verified this finding is still valid and updated the top module docstring in /xtask/src/tasks/build_kobo.rs to reflect current behavior: Kobo cross-compilation requires the Linaro toolchain, and the task performs a runtime check that returns a clear error if it’s missing.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file labels May 26, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
xtask/src/tasks/build_kobo.rs (1)

99-101: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update stale # Errors rustdoc to match Linux+macOS support.

Line 100 still says “platform is not Linux,” but run() now rejects only non-Linux/non-macOS platforms. Please align the doc text with current behavior.

Suggested doc fix
 /// Returns an error if:
-/// - The platform is not Linux.
+/// - The platform is neither Linux nor macOS.
 /// - The Linaro toolchain is not on `PATH`.
 /// - Any build step fails.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@xtask/src/tasks/build_kobo.rs` around lines 99 - 101, The rustdoc for
build_kobo.rs is stale: update the `# Errors` section so it reflects that
`run()` rejects non-Linux and non-macOS platforms (instead of only non-Linux);
change the first bullet under "Returns an error if:" to mention "the platform is
not Linux or macOS" (or equivalent wording) and keep the existing second bullet
about the Linaro toolchain on `PATH`, ensuring the reference to the `run()`
behavior and the error cases in that doc comment are consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@xtask/src/tasks/build_kobo.rs`:
- Around line 99-101: The rustdoc for build_kobo.rs is stale: update the `#
Errors` section so it reflects that `run()` rejects non-Linux and non-macOS
platforms (instead of only non-Linux); change the first bullet under "Returns an
error if:" to mention "the platform is not Linux or macOS" (or equivalent
wording) and keep the existing second bullet about the Linaro toolchain on
`PATH`, ensuring the reference to the `run()` behavior and the error cases in
that doc comment are consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 8997a658-0239-405e-bd5d-06cb210314a9

📥 Commits

Reviewing files that changed from the base of the PR and between f66d6ec and d66ea45.

📒 Files selected for processing (1)
  • xtask/src/tasks/build_kobo.rs
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: devenv (macos-latest)
  • GitHub Check: build-docs-epub
  • GitHub Check: devenv (ubuntu-latest)
  • GitHub Check: Analyze (rust)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Prefer ? over unwrap() / expect() in library and app code
Use thiserror for custom error types and anyhow for ad-hoc errors in Rust
Use iterators over index-based loops in Rust
Use &str over String in function parameters when ownership is not needed
Prefer borrowing over cloning in Rust
Inline expressions directly into struct fields—avoid intermediate bindings solely to pass them into a struct literal
Avoid unsafe unless required and documented in Rust
Avoid premature collect() in Rust—keep iterators lazy
Ensure Rust code compiles without warnings
Prefer newtype wrappers over raw primitives for domain concepts (e.g., Fingerprint(String) instead of bare String)
Wrap String, i64, and similar primitives when the value represents a specific domain concept (fingerprints, file kinds, identifiers, …)
Implement Display, FromStr, and other standard traits on newtypes so they stay ergonomic
Match on enum variants instead of string comparisons—the compiler catches missing arms
Use structured fields with the tracing crate in Rust—never use string formatting for log data
Use direct field formatting for primitives (int, float, bool) with tracing crate
Use Display % formatter with tracing crate for types implementing Display
Use Debug ? formatter with tracing crate for types implementing Debug
Use debug log level for development and troubleshooting detail
Use info log level for important runtime events
Use warn log level for recoverable issues (retries, fallbacks)
Use error log level for failures requiring attention
Return domain types directly from sqlx queries instead of parsing primitives after the fact
Implement sqlx::Type<sqlx::Sqlite>, sqlx::Encode<sqlx::Sqlite>, and sqlx::Decode<sqlx::Sqlite> traits for custom types used in sqlx queries
Use sqlx type-override syntax with column aliases (e.g., AS "fingerprint: Fp") so the macro deserializes into domain types directly
When the orphan rule prevents implem...

Files:

  • xtask/src/tasks/build_kobo.rs
🔇 Additional comments (1)
xtask/src/tasks/build_kobo.rs (1)

11-13: LGTM!

Also applies to: 104-108

Update soname() docs to name the actual binary used
(arm-linux-gnueabihf-readelf, not generic readelf), and fix the
run() # Errors section in build_kobo.rs to say Linux or macOS
instead of Linux only.

- build_kobo.rs: "The platform is not Linux or macOS."
- thirdparty.rs: readelf -> arm-linux-gnueabihf-readelf in SONAMES
  constant doc and soname() function doc
@coderabbitai coderabbitai Bot removed documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file labels May 26, 2026
@OGKevin OGKevin added documentation Improvements or additions to documentation dependencies Pull requests that update a dependency file labels May 26, 2026
@OGKevin
OGKevin merged commit d61537a into master May 26, 2026
81 checks passed
@OGKevin
OGKevin deleted the ogkevin/push/unpukymmnooo branch May 26, 2026 18:00
@OGKevin

OGKevin commented May 26, 2026

Copy link
Copy Markdown
Owner Author

aaah forgot about the damn docs 🫠

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review dependencies Pull requests that update a dependency file documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants