mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-11-28 03:47:37 +03:00
feat(cli): synchronize Tauri config and lib name with iOS Xcode project (#10802)
- the Xcode project now uses a fixed output library name, which means changes to the Cargo.toml lib name won't affect it (backwards compatible change, we're checking if this new format is being used or not by reading the project.pbxproj) - sync config identifier with the pbxproj - sync development team config with the pbxproj the sync runs both on dev and on build Co-authored-by: Amr Bashir <amr.bashir2015@gmail.com>
This commit is contained in:
parent
431208207b
commit
f67a9eb6de
6
.changes/synchronize-config-and-xcode-project.md
Normal file
6
.changes/synchronize-config-and-xcode-project.md
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
"tauri-cli": patch:enhance
|
||||
"@tauri-apps/cli": patch:enhance
|
||||
---
|
||||
|
||||
Synchronize identifier, development team and lib name with the iOS Xcode project.
|
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -747,9 +747,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-mobile2"
|
||||
version = "0.15.0"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b1baf430f92ddf6e492c9186e4e97dc3051366345b8aa7ffdc0e0f952c9a35b"
|
||||
checksum = "d0b8132519bea2d46174e777bd36d480d93afbe1df31c27cacfb411ff152bba1"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"core-foundation 0.10.0",
|
||||
|
@ -36,7 +36,7 @@ name = "cargo-tauri"
|
||||
path = "src/main.rs"
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
|
||||
cargo-mobile2 = { version = "0.15", default-features = false }
|
||||
cargo-mobile2 = { version = "0.15.1", default-features = false }
|
||||
|
||||
[dependencies]
|
||||
jsonrpsee = { version = "0.24", features = ["server"] }
|
||||
|
@ -230,12 +230,14 @@ impl Pbxproj {
|
||||
.iter_mut()
|
||||
.find(|s| s.key == key)
|
||||
{
|
||||
let Some(line) = self.raw_lines.get_mut(build_setting.line_number) else {
|
||||
return;
|
||||
};
|
||||
if build_setting.value != value {
|
||||
let Some(line) = self.raw_lines.get_mut(build_setting.line_number) else {
|
||||
return;
|
||||
};
|
||||
|
||||
*line = format!("{}{key} = {value};", build_setting.identation);
|
||||
self.has_changes = true;
|
||||
*line = format!("{}{key} = {value};", build_setting.identation);
|
||||
self.has_changes = true;
|
||||
}
|
||||
} else {
|
||||
let Some(last_build_setting) = build_configuration.build_settings.last().cloned() else {
|
||||
return;
|
||||
|
@ -146,7 +146,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
tauri_utils::platform::Target::Ios,
|
||||
options.config.as_ref().map(|c| &c.0),
|
||||
)?;
|
||||
let (interface, app, mut config) = {
|
||||
let (interface, mut config) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
|
||||
|
||||
@ -160,7 +160,7 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
build_options.features.as_ref(),
|
||||
&Default::default(),
|
||||
);
|
||||
(interface, app, config)
|
||||
(interface, config)
|
||||
};
|
||||
|
||||
let tauri_path = tauri_dir();
|
||||
@ -198,7 +198,8 @@ pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
|
||||
// synchronize pbxproj and exportoptions
|
||||
synchronize_project_config(
|
||||
&app,
|
||||
&config,
|
||||
&tauri_config,
|
||||
&mut pbxproj,
|
||||
&mut export_options_plist,
|
||||
&project_config,
|
||||
|
@ -3,8 +3,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::{
|
||||
device_prompt, ensure_init, env, get_app, get_config, inject_resources, merge_plist,
|
||||
open_and_wait, MobileTarget,
|
||||
device_prompt, ensure_init, env, get_app, get_config, inject_resources, load_pbxproj,
|
||||
merge_plist, open_and_wait, synchronize_project_config, MobileTarget, ProjectConfig,
|
||||
};
|
||||
use crate::{
|
||||
dev::Options as DevOptions,
|
||||
@ -191,6 +191,25 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
])?;
|
||||
merged_info_plist.to_file_xml(&info_plist_path)?;
|
||||
|
||||
let mut pbxproj = load_pbxproj(&config)?;
|
||||
|
||||
// synchronize pbxproj
|
||||
synchronize_project_config(
|
||||
&config,
|
||||
&tauri_config,
|
||||
&mut pbxproj,
|
||||
&mut plist::Dictionary::new(),
|
||||
&ProjectConfig {
|
||||
code_sign_identity: None,
|
||||
team_id: None,
|
||||
provisioning_profile_uuid: None,
|
||||
},
|
||||
!options.release_mode,
|
||||
)?;
|
||||
if pbxproj.has_changes() {
|
||||
pbxproj.save()?;
|
||||
}
|
||||
|
||||
run_dev(
|
||||
interface,
|
||||
options,
|
||||
|
@ -29,7 +29,7 @@ use super::{
|
||||
use crate::{
|
||||
helpers::{
|
||||
app_paths::tauri_dir,
|
||||
config::{BundleResources, Config as TauriConfig},
|
||||
config::{BundleResources, Config as TauriConfig, ConfigHandle},
|
||||
pbxproj,
|
||||
},
|
||||
Result,
|
||||
@ -49,6 +49,7 @@ pub(crate) mod project;
|
||||
mod xcode_script;
|
||||
|
||||
pub const APPLE_DEVELOPMENT_TEAM_ENV_VAR_NAME: &str = "APPLE_DEVELOPMENT_TEAM";
|
||||
pub const LIB_OUTPUT_FILE_NAME: &str = "libapp.a";
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(
|
||||
@ -131,7 +132,7 @@ pub fn get_config(
|
||||
log::warn!("No code signing certificates found. You must add one and set the certificate development team ID on the `bundle > iOS > developmentTeam` config value or the `{APPLE_DEVELOPMENT_TEAM_ENV_VAR_NAME}` environment variable. To list the available certificates, run `tauri info`.");
|
||||
None
|
||||
}
|
||||
1 => Some(teams.first().unwrap().id.clone()),
|
||||
1 =>None,
|
||||
_ => {
|
||||
log::warn!("You must set the code signing certificate development team ID on the `bundle > iOS > developmentTeam` config value or the `{APPLE_DEVELOPMENT_TEAM_ENV_VAR_NAME}` environment variable. Available certificates: {}", teams.iter().map(|t| format!("{} (ID: {})", t.name, t.id)).collect::<Vec<String>>().join(", "));
|
||||
None
|
||||
@ -421,12 +422,21 @@ pub fn load_pbxproj(config: &AppleConfig) -> Result<pbxproj::Pbxproj> {
|
||||
}
|
||||
|
||||
pub fn synchronize_project_config(
|
||||
app: &App,
|
||||
config: &AppleConfig,
|
||||
tauri_config: &ConfigHandle,
|
||||
pbxproj: &mut pbxproj::Pbxproj,
|
||||
export_options_list: &mut plist::Dictionary,
|
||||
project_config: &ProjectConfig,
|
||||
debug: bool,
|
||||
) -> Result<()> {
|
||||
let identifier = tauri_config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.identifier
|
||||
.clone();
|
||||
|
||||
let manual_signing = project_config.code_sign_identity.is_some()
|
||||
|| project_config.provisioning_profile_uuid.is_some();
|
||||
|
||||
@ -437,10 +447,26 @@ pub fn synchronize_project_config(
|
||||
.find(|l| l.comment.contains("_iOS"))
|
||||
{
|
||||
for build_configuration_ref in xc_configuration_list.build_configurations {
|
||||
if manual_signing {
|
||||
pbxproj.set_build_settings(&build_configuration_ref.id, "CODE_SIGN_STYLE", "Manual");
|
||||
pbxproj.set_build_settings(
|
||||
&build_configuration_ref.id,
|
||||
"CODE_SIGN_STYLE",
|
||||
if manual_signing {
|
||||
"Manual"
|
||||
} else {
|
||||
"Automatic"
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(team) = config.development_team() {
|
||||
pbxproj.set_build_settings(&build_configuration_ref.id, "DEVELOPMENT_TEAM", team);
|
||||
}
|
||||
|
||||
pbxproj.set_build_settings(
|
||||
&build_configuration_ref.id,
|
||||
"PRODUCT_BUNDLE_IDENTIFIER",
|
||||
&identifier,
|
||||
);
|
||||
|
||||
if let Some(identity) = &project_config.code_sign_identity {
|
||||
let identity = format!("\"{identity}\"");
|
||||
pbxproj.set_build_settings(&build_configuration_ref.id, "CODE_SIGN_IDENTITY", &identity);
|
||||
@ -536,7 +562,7 @@ pub fn synchronize_project_config(
|
||||
});
|
||||
if let Some(profile_uuid) = profile_uuid {
|
||||
let mut provisioning_profiles = plist::Dictionary::new();
|
||||
provisioning_profiles.insert(app.identifier().to_string(), profile_uuid.into());
|
||||
provisioning_profiles.insert(config.app().identifier().to_string(), profile_uuid.into());
|
||||
export_options_list.insert(
|
||||
"provisioningProfiles".to_string(),
|
||||
provisioning_profiles.into(),
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
use crate::{
|
||||
helpers::{config::Config as TauriConfig, template},
|
||||
mobile::ios::LIB_OUTPUT_FILE_NAME,
|
||||
Result,
|
||||
};
|
||||
use anyhow::Context;
|
||||
@ -76,6 +77,8 @@ pub fn gen(
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
let default_archs = ["arm64", "x86_64"];
|
||||
|
||||
map.insert("lib-output-file-name", LIB_OUTPUT_FILE_NAME);
|
||||
|
||||
map.insert("file-groups", &source_dirs);
|
||||
map.insert("ios-frameworks", metadata.ios().frameworks());
|
||||
map.insert("ios-valid-archs", default_archs);
|
||||
|
@ -6,9 +6,11 @@ use super::{ensure_init, env, get_app, get_config, read_options, MobileTarget};
|
||||
use crate::{
|
||||
helpers::config::get as get_tauri_config,
|
||||
interface::{AppInterface, AppSettings, Interface, Options as InterfaceOptions},
|
||||
mobile::ios::LIB_OUTPUT_FILE_NAME,
|
||||
Result,
|
||||
};
|
||||
|
||||
use anyhow::Context;
|
||||
use cargo_mobile2::{apple::target::Target, opts::Profile};
|
||||
use clap::Parser;
|
||||
|
||||
@ -16,6 +18,7 @@ use std::{
|
||||
collections::HashMap,
|
||||
env::{current_dir, set_current_dir, var, var_os},
|
||||
ffi::OsStr,
|
||||
fs::read_to_string,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
};
|
||||
@ -233,10 +236,26 @@ pub fn command(options: Options) -> Result<()> {
|
||||
let project_dir = config.project_dir();
|
||||
let externals_lib_dir = project_dir.join(format!("Externals/{arch}/{}", profile.as_str()));
|
||||
std::fs::create_dir_all(&externals_lib_dir)?;
|
||||
std::fs::copy(
|
||||
lib_path,
|
||||
externals_lib_dir.join(format!("lib{}.a", config.app().lib_name())),
|
||||
)?;
|
||||
|
||||
// backwards compatible lib output file name
|
||||
let uses_new_lib_output_file_name = {
|
||||
let pbxproj_contents = read_to_string(
|
||||
project_dir
|
||||
.join(format!("{}.xcodeproj", config.app().name()))
|
||||
.join("project.pbxproj"),
|
||||
)
|
||||
.context("missing project.pbxproj file in the Xcode project")?;
|
||||
|
||||
pbxproj_contents.contains(LIB_OUTPUT_FILE_NAME)
|
||||
};
|
||||
|
||||
let lib_output_file_name = if uses_new_lib_output_file_name {
|
||||
LIB_OUTPUT_FILE_NAME.to_string()
|
||||
} else {
|
||||
format!("lib{}.a", config.app().lib_name())
|
||||
};
|
||||
|
||||
std::fs::copy(lib_path, externals_lib_dir.join(lib_output_file_name))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -329,17 +329,16 @@ fn ensure_init(
|
||||
}
|
||||
#[cfg(target_os = "macos")]
|
||||
Target::Ios => {
|
||||
let project_yml = read_to_string(project_dir.join("project.yml"))
|
||||
.context("missing project.yml file in the Xcode project directory")?;
|
||||
if !project_yml.contains(&format!(
|
||||
"PRODUCT_BUNDLE_IDENTIFIER: {}",
|
||||
tauri_config_.identifier.replace('_', "-")
|
||||
)) {
|
||||
project_outdated_reasons
|
||||
.push("you have modified your \"identifier\" in the Tauri configuration");
|
||||
}
|
||||
let pbxproj_contents = read_to_string(
|
||||
project_dir
|
||||
.join(format!("{}.xcodeproj", app.name()))
|
||||
.join("project.pbxproj"),
|
||||
)
|
||||
.context("missing project.yml file in the Xcode project directory")?;
|
||||
|
||||
if !project_yml.contains(&format!("framework: lib{}.a", app.lib_name())) {
|
||||
if !(pbxproj_contents.contains(ios::LIB_OUTPUT_FILE_NAME)
|
||||
|| pbxproj_contents.contains(&format!("lib{}.a", app.lib_name())))
|
||||
{
|
||||
project_outdated_reasons
|
||||
.push("you have modified your [lib.name] or [package.name] in the Cargo.toml file");
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ targets:
|
||||
EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64
|
||||
groups: [app]
|
||||
dependencies:
|
||||
- framework: lib{{app.lib-name}}.a
|
||||
- framework: {{ lib-output-file-name }}
|
||||
embed: false
|
||||
{{~#each ios-libraries}}
|
||||
- framework: {{this}}
|
||||
@ -125,9 +125,9 @@ targets:
|
||||
name: Build Rust Code
|
||||
basedOnDependencyAnalysis: false
|
||||
outputFiles:
|
||||
- $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/lib{{app.lib-name}}.a
|
||||
- $(SRCROOT)/Externals/arm64/${CONFIGURATION}/lib{{app.lib-name}}.a
|
||||
- $(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/lib{{app.lib-name}}.a
|
||||
- $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/{{ lib-output-file-name }}
|
||||
- $(SRCROOT)/Externals/arm64/${CONFIGURATION}/{{ lib-output-file-name }}
|
||||
- $(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/{{ lib-output-file-name }}
|
||||
{{~#if ios-post-compile-scripts}}
|
||||
postCompileScripts:
|
||||
{{~#each ios-post-compile-scripts}}{{#if this.path}}
|
||||
|
Loading…
Reference in New Issue
Block a user