Skip to content

Commit

Permalink
fix: rpath missing from app, closes #7710 (#7773)
Browse files Browse the repository at this point in the history
Co-authored-by: Lucas Nogueira <[email protected]>
Co-authored-by: Lucas Fernandes Nogueira <[email protected]>
fix: codesign doesn't sign frameworks or sidecar, closes #7690 (#7774)
  • Loading branch information
3 people authored Sep 24, 2023
1 parent dcdbe3e commit 5ecb46b
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changes/rpath.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"tauri-build": patch:bug
---

Automatically set rpath on macOS if frameworks are bundled and copy frameworks to `src-tauri/target/Frameworks` for usage in development.
2 changes: 2 additions & 0 deletions core/tauri-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ heck = "0.4"
json-patch = "1.0"
tauri-winres = "0.1"
semver = "1"
walkdir = "2"
dirs-next = "2"

[features]
codegen = [ "tauri-codegen", "quote" ]
Expand Down
123 changes: 122 additions & 1 deletion core/tauri-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#![cfg_attr(doc_cfg, feature(doc_cfg))]

use anyhow::Context;
pub use anyhow::Result;
use cargo_toml::Manifest;
use heck::AsShoutySnakeCase;
Expand Down Expand Up @@ -80,6 +81,113 @@ fn copy_resources(resources: ResourcePaths<'_>, path: &Path) -> Result<()> {
Ok(())
}

#[cfg(unix)]
fn symlink_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
std::os::unix::fs::symlink(src, dst)
}

/// Makes a symbolic link to a directory.
#[cfg(windows)]
fn symlink_dir(src: &Path, dst: &Path) -> std::io::Result<()> {
std::os::windows::fs::symlink_dir(src, dst)
}

/// Makes a symbolic link to a file.
#[cfg(unix)]
fn symlink_file(src: &Path, dst: &Path) -> std::io::Result<()> {
std::os::unix::fs::symlink(src, dst)
}

/// Makes a symbolic link to a file.
#[cfg(windows)]
fn symlink_file(src: &Path, dst: &Path) -> std::io::Result<()> {
std::os::windows::fs::symlink_file(src, dst)
}

fn copy_dir(from: &Path, to: &Path) -> Result<()> {
for entry in walkdir::WalkDir::new(from) {
let entry = entry?;
debug_assert!(entry.path().starts_with(from));
let rel_path = entry.path().strip_prefix(from)?;
let dest_path = to.join(rel_path);
if entry.file_type().is_symlink() {
let target = std::fs::read_link(entry.path())?;
if entry.path().is_dir() {
symlink_dir(&target, &dest_path)?;
} else {
symlink_file(&target, &dest_path)?;
}
} else if entry.file_type().is_dir() {
std::fs::create_dir(dest_path)?;
} else {
std::fs::copy(entry.path(), dest_path)?;
}
}
Ok(())
}

// Copies the framework under `{src_dir}/{framework}.framework` to `{dest_dir}/{framework}.framework`.
fn copy_framework_from(src_dir: &Path, framework: &str, dest_dir: &Path) -> Result<bool> {
let src_name = format!("{}.framework", framework);
let src_path = src_dir.join(&src_name);
if src_path.exists() {
copy_dir(&src_path, &dest_dir.join(&src_name))?;
Ok(true)
} else {
Ok(false)
}
}

// Copies the macOS application bundle frameworks to the target folder
fn copy_frameworks(dest_dir: &Path, frameworks: &[String]) -> Result<()> {
std::fs::create_dir_all(dest_dir).with_context(|| {
format!(
"Failed to create frameworks output directory at {:?}",
dest_dir
)
})?;
for framework in frameworks.iter() {
if framework.ends_with(".framework") {
let src_path = PathBuf::from(framework);
let src_name = src_path
.file_name()
.expect("Couldn't get framework filename");
let dest_path = dest_dir.join(src_name);
copy_dir(&src_path, &dest_path)?;
continue;
} else if framework.ends_with(".dylib") {
let src_path = PathBuf::from(framework);
if !src_path.exists() {
return Err(anyhow::anyhow!("Library not found: {}", framework));
}
let src_name = src_path.file_name().expect("Couldn't get library filename");
let dest_path = dest_dir.join(src_name);
copy_file(&src_path, &dest_path)?;
continue;
} else if framework.contains('/') {
return Err(anyhow::anyhow!(
"Framework path should have .framework extension: {}",
framework
));
}
if let Some(home_dir) = dirs_next::home_dir() {
if copy_framework_from(&home_dir.join("Library/Frameworks/"), framework, dest_dir)? {
continue;
}
}
if copy_framework_from(&PathBuf::from("/Library/Frameworks/"), framework, dest_dir)?
|| copy_framework_from(
&PathBuf::from("/Network/Library/Frameworks/"),
framework,
dest_dir,
)?
{
continue;
}
}
Ok(())
}

// checks if the given Cargo feature is enabled.
fn has_feature(feature: &str) -> bool {
// when a feature is enabled, Cargo sets the `CARGO_FEATURE_<name` env var to 1
Expand Down Expand Up @@ -370,13 +478,26 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
}

if target_triple.contains("darwin") {
if let Some(frameworks) = &config.tauri.bundle.macos.frameworks {
if !frameworks.is_empty() {
let frameworks_dir = target_dir.parent().unwrap().join("Frameworks");
let _ = std::fs::remove_dir_all(&frameworks_dir);
// copy frameworks to the root `target` folder (instead of `target/debug` for instance)
// because the rpath is set to `@executable_path/../Frameworks`.
copy_frameworks(&frameworks_dir, frameworks)?;

// If we have frameworks, we need to set the @rpath
// https://github.com/tauri-apps/tauri/issues/7710
println!("cargo:rustc-link-arg=-Wl,-rpath,@executable_path/../Frameworks");
}
}

if let Some(version) = &config.tauri.bundle.macos.minimum_system_version {
println!("cargo:rustc-env=MACOSX_DEPLOYMENT_TARGET={version}");
}
}

if target_triple.contains("windows") {
use anyhow::Context;
use semver::Version;
use tauri_winres::{VersionInfo, WindowsResource};

Expand Down
2 changes: 1 addition & 1 deletion core/tauri-codegen/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsE
}

info_plist
.to_file_xml(&out_dir.join("Info.plist"))
.to_file_xml(out_dir.join("Info.plist"))
.expect("failed to write Info.plist");
quote!({
tauri::embed_plist::embed_info_plist!(concat!(std::env!("OUT_DIR"), "/Info.plist"));
Expand Down

0 comments on commit 5ecb46b

Please sign in to comment.