Skip to content
Draft
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
19 changes: 11 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ objc2-user-notifications = "0.3"

tokenizers = "0.21.4"

swift-rs = { git = "https://github.com/yujonglee/swift-rs", rev = "41a1605" }
swift-rs = { git = "https://github.com/yujonglee/swift-rs", rev = "0b36e41" }
sysinfo = "0.37.0"

[patch.crates-io]
Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ crate-type = ["staticlib", "rlib"]
[build-dependencies]
tauri-build = { workspace = true, features = [] }

[target.'cfg(all(target_os = "macos", target_arch = "aarch64"))'.build-dependencies]
swift-rs = { workspace = true, features = ["build"] }

[dependencies]
tauri = { workspace = true, features = ["specta", "macos-private-api", "protocol-asset"] }

Expand Down
3 changes: 3 additions & 0 deletions apps/desktop/src-tauri/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ fn main() {
#[cfg(target_os = "macos")]
println!("cargo:rustc-link-arg=-fapple-link-rtlib");

#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
swift_rs::link_swift_framework("tauri-plugin-local-stt");

Comment on lines +5 to +7
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Check the links field in local-stt plugin Cargo.toml
echo "=== Checking links field in plugins/local-stt/Cargo.toml ==="
cat plugins/local-stt/Cargo.toml | grep -A 1 'links ='

# Check if there are any Swift source files in the plugin
echo -e "\n=== Checking for Swift source files ==="
fd -e swift . plugins/local-stt/ 2>/dev/null || echo "No Swift files found"

# Check the build.rs file content
echo -e "\n=== Checking build.rs file ==="
cat -n apps/desktop/src-tauri/build.rs | head -20

# Look for any other references to this framework name
echo -e "\n=== Checking for other references to tauri-plugin-local-stt ==="
rg "tauri-plugin-local-stt" --type rust --type toml

Repository: fastrepl/hyprnote

Length of output: 1584


🏁 Script executed:

#!/bin/bash

# Check if there's a pre-built framework or binary somewhere
echo "=== Looking for framework files or Swift build artifacts ==="
fd "\.framework" plugins/local-stt/ 2>/dev/null || echo "No .framework directories found"
fd "\.a$|\.dylib$|\.so$" plugins/local-stt/ 2>/dev/null || echo "No library files found"

# Check the plugin's build.rs if it exists
echo -e "\n=== Checking if plugin has build.rs ==="
ls -la plugins/local-stt/build.rs 2>/dev/null || echo "No build.rs in plugin"

# Check the plugin structure
echo -e "\n=== Plugin directory structure ==="
find plugins/local-stt -type f -name "*.rs" -o -name "*.swift" -o -name "*.toml" | head -20

# Check src directory
echo -e "\n=== Plugin src directory ==="
ls -la plugins/local-stt/src/ 2>/dev/null || echo "No src directory"

# Look at the plugin's Cargo.toml more thoroughly
echo -e "\n=== Full Cargo.toml of plugin ==="
head -30 plugins/local-stt/Cargo.toml

Repository: fastrepl/hyprnote

Length of output: 2356


🏁 Script executed:

#!/bin/bash

# Read the plugin's build.rs
echo "=== Plugin's build.rs ==="
cat -n plugins/local-stt/build.rs

# Read more of the desktop app's build.rs to understand the full context
echo -e "\n=== Desktop app's full build.rs ==="
cat -n apps/desktop/src-tauri/build.rs

# Check workspace Cargo.toml to understand dependency order
echo -e "\n=== Checking workspace members and build order ==="
cat Cargo.toml | grep -A 20 "\[workspace\]"

Repository: fastrepl/hyprnote

Length of output: 2378


Fix framework name mismatch: plugin's build.rs links "vad-ext" but should link "tauri-plugin-local-stt".

The plugin's Cargo.toml declares links = "tauri-plugin-local-stt" (line 7), and the desktop app's build.rs attempts to link a framework with that same name (line 6 of apps/desktop/src-tauri/build.rs). However, the plugin's own build.rs (line 16 of plugins/local-stt/build.rs) links swift_rs::link_swift_framework("vad-ext") instead. This mismatch will cause a build failure because:

  1. The links field in Cargo.toml must match what the build.rs actually produces
  2. The desktop app expects to link "tauri-plugin-local-stt" but the plugin creates "vad-ext"

Update plugins/local-stt/build.rs line 16 to link the correct framework name that matches the Cargo.toml links field:

swift_rs::link_swift_framework("tauri-plugin-local-stt");
🤖 Prompt for AI Agents
In plugins/local-stt/build.rs around line 16, the build script links the Swift
framework as "vad-ext" which mismatches the Cargo.toml links field
("tauri-plugin-local-stt"); change the call to swift_rs::link_swift_framework to
link "tauri-plugin-local-stt" so the produced framework name matches Cargo.toml
and the desktop app's build.rs.

#[cfg(debug_assertions)]
{
use std::path::PathBuf;
Expand Down
1 change: 1 addition & 0 deletions crates/vad-ext/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
name = "vad-ext"
version = "0.1.0"
edition = "2021"
links = "vad-ext"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Cargo links key metadata native library linking best practices

💡 Result:

Concise best-practices for using Cargo's package.links metadata and linking native libraries

  1. Use links only for low-level "sys" crates; keep high-level safe wrappers free of links. This follows the common sys / non-sys pattern. [1][4]

  2. Always include a build script when you set package.links. The build script must emit rustc-link-lib / rustc-link-search (cargo:rustc-link-lib / cargo:rustc-link-search) and may emit metadata via cargo:metadata for dependents. [1][3]

  3. Ensure each links name is unique across your dependency graph (one package per links name). Cargo enforces this to avoid duplicate native symbols; avoid semver-incompatible releases that change behavior for widely-used links names. [2]

  4. Export metadata carefully and predictably. Build-script metadata is passed to immediate dependents as DEP__=value environment variables — not to transitive dependents — so design your sys crate API and metadata keys accordingly. [3]

  5. Allow users / packagers to override build-script behavior via .cargo/config (rustc-link-lib, rustc-link-search, root, metadata keys). Document how to configure overrides for distro/system-provided libraries. [1][4]

  6. Prefer static vs dynamic explicitly: emit rustc-link-lib with the appropriate kind (static/dylib/framework) in the build script; document expected linkage and required linker flags. [1][7]

  7. Minimize global side effects: avoid emitting linker args or env cfgs that change global build behavior for unrelated crates; confine changes to what consumers need. [1][7]

  8. Test dependency resolution scenarios: CI should build with realistic graphs (multiple versions of wrappers) to catch "multiple packages link to native library" errors early; if necessary, recommend consumers pin or unify versions. [2][8]

Primary references

  • Cargo build scripts / links key (how to emit rustc-link-*, metadata, overrides). [1][4]
  • Dependency resolver rules for links (one crate per links name, resolver errors). [2]
  • Build-script metadata / DEP_* variable behavior and usage. [3]

If you want, I can produce a minimal example sys crate (Cargo.toml + build.rs) showing rustc-link-lib/search + metadata and a small non-sys wrapper that consumes DEP_* values.


🏁 Script executed:

# First, let's examine the build.rs file to understand what's actually being linked
cat -n crates/vad-ext/build.rs

Repository: fastrepl/hyprnote

Length of output: 208


🏁 Script executed:

# Check the Cargo.toml structure and metadata
cat -n crates/vad-ext/Cargo.toml

Repository: fastrepl/hyprnote

Length of output: 999


🏁 Script executed:

# Search for any usage of DEP_VAD_EXT in the codebase
rg "DEP_VAD_EXT" --type rust --type toml

Repository: fastrepl/hyprnote

Length of output: 43


🏁 Script executed:

# Check if other crates depend on vad-ext and what they expect
rg "vad-ext" --type toml -A 2 -B 2

Repository: fastrepl/hyprnote

Length of output: 2839


Remove the links field from Cargo.toml.

The links metadata is intended only for low-level "sys" crates that provide direct native bindings. vad-ext is a high-level wrapper with regular Rust dependencies (serde, tokio, thiserror, etc.), not a sys crate. Sys crates use links to declare and communicate linking metadata to dependents via build scripts; since vad-ext doesn't follow this pattern and no downstream crates consume DEP_VAD_EXT_* variables, this field should not be present.

🤖 Prompt for AI Agents
crates/vad-ext/Cargo.toml around line 5: the file currently contains a `links =
"vad-ext"` metadata entry which is only appropriate for low-level sys crates
exposing native bindings; remove the `links` field from Cargo.toml to reflect
that vad-ext is a high-level wrapper with normal Rust dependencies and does not
provide or export build-script linking variables.


[target.'cfg(all(target_os = "macos", target_arch = "aarch64"))'.build-dependencies]
swift-rs = { workspace = true, features = ["build"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/vad-ext/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn main() {
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
swift_rs::propagate_framework_rpath("vvad", false);
swift_rs::link_swift_framework("vvad");
}
2 changes: 1 addition & 1 deletion crates/vvad/build.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn main() {
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
swift_rs::propagate_framework_rpath("am2", true);
swift_rs::link_swift_framework("am2");
}
4 changes: 4 additions & 0 deletions plugins/local-stt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ load-dynamic = ["hypr-transcribe-whisper-local/load-dynamic"]
[build-dependencies]
tauri-plugin = { workspace = true, features = ["build"] }

[target.'cfg(all(target_os = "macos", target_arch = "aarch64"))'.build-dependencies]
swift-rs = { workspace = true, features = ["build"] }

[dev-dependencies]
hypr-audio-utils = { workspace = true }
hypr-data = { workspace = true }
Expand All @@ -44,6 +47,7 @@ hypr-host = { workspace = true }
hypr-language = { workspace = true, features = ["whisper"] }
hypr-transcribe-moonshine = { workspace = true }
hypr-transcribe-whisper-local = { workspace = true }
hypr-vad-ext = { workspace = true }
hypr-whisper-local = { workspace = true }
hypr-whisper-local-model = { workspace = true }

Expand Down
3 changes: 3 additions & 0 deletions plugins/local-stt/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@ const COMMANDS: &[&str] = &[
];

fn main() {
#[cfg(all(target_os = "macos", target_arch = "aarch64"))]
swift_rs::link_swift_framework("vad-ext");

Comment on lines +15 to +17
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find . -name "build.rs" | head -20

Repository: fastrepl/hyprnote

Length of output: 599


🏁 Script executed:

cat -n crates/vad-ext/build.rs 2>/dev/null || echo "File not found, searching..."

Repository: fastrepl/hyprnote

Length of output: 208


🏁 Script executed:

find . -path "*/vad-ext/*" -name "build.rs" -exec cat -n {} \;

Repository: fastrepl/hyprnote

Length of output: 208


🏁 Script executed:

find . -path "*/vad-ext/*" -type f \( -name "Cargo.toml" -o -name "build.rs" \) | head -10

Repository: fastrepl/hyprnote

Length of output: 114


🏁 Script executed:

cat -n crates/vad-ext/Cargo.toml

Repository: fastrepl/hyprnote

Length of output: 999


🏁 Script executed:

cat -n plugins/local-stt/Cargo.toml

Repository: fastrepl/hyprnote

Length of output: 3557


🏁 Script executed:

cat -n crates/vvad/Cargo.toml 2>/dev/null || echo "File not found"

Repository: fastrepl/hyprnote

Length of output: 600


🏁 Script executed:

find . -name "*.swift" -o -name "*.xcframework" | grep -i "vad" | head -20

Repository: fastrepl/hyprnote

Length of output: 43


🏁 Script executed:

find . -type d -name "*.framework" -o -name "*.xcframework" | head -20

Repository: fastrepl/hyprnote

Length of output: 43


🏁 Script executed:

find crates/vad-ext -type f | head -30

Repository: fastrepl/hyprnote

Length of output: 257


🏁 Script executed:

cat -n plugins/local-stt/build.rs

Repository: fastrepl/hyprnote

Length of output: 637


🏁 Script executed:

find plugins/local-stt -type f -name "*.rs" | head -10

Repository: fastrepl/hyprnote

Length of output: 406


Change framework name from "vad-ext" to "vvad".

The build script attempts to link a Swift framework named "vad-ext", but no such framework exists in the codebase. The vad-ext crate is a Rust wrapper that itself links the actual Swift framework "vvad" (see crates/vad-ext/build.rs line 3). Update line 16 to link the correct framework:

    #[cfg(all(target_os = "macos", target_arch = "aarch64"))]
    swift_rs::link_swift_framework("vvad");
🤖 Prompt for AI Agents
In plugins/local-stt/build.rs around lines 15 to 17, the script links a
non-existent Swift framework "vad-ext"; change the linked framework name to
"vvad" by updating the swift_rs::link_swift_framework call to use "vvad" so it
matches the actual framework the vad-ext crate wraps.

tauri_plugin::Builder::new(COMMANDS).build();
}
Loading