diff --git a/Makefile b/Makefile index 92f0fd4..b5a4874 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ clean: coverage: rm -rf game* - cargo tarpaulin --all-features --ignore-tests -o Html -t 300 -- --test-threads=1 --skip=test_process_ftw_command_cross_build_ios_target --skip=test_ftw_cross_build_ios_target + cargo tarpaulin --all-features --ignore-tests -o Html -t 300 -- --test-threads=1 ${BROWSER} tarpaulin-report.html doc: clean @@ -52,7 +52,7 @@ shell: nix-shell -p clang openssl pkg-config test: - cargo test -- --test-threads=1 --skip=test_process_ftw_command_cross_build_ios_target --skip=test_ftw_cross_build_ios_target + cargo test -- --test-threads=1 udeps: cargo udeps diff --git a/src/ftw_command.rs b/src/ftw_command.rs index 322135f..5c21b49 100644 --- a/src/ftw_command.rs +++ b/src/ftw_command.rs @@ -911,6 +911,7 @@ enable-cross-compilation=true FtwTarget::LinuxX86_64, FtwTarget::WindowsX86_64Gnu, FtwTarget::MacOsAarch64, + FtwTarget::IosAarch64, ]; let cmd = FtwCommand::Build { targets: targets.clone(), @@ -1275,6 +1276,52 @@ enable-cross-compilation=true ))); } + #[test] + fn test_process_ftw_command_cross_export_ios_target() { + let project = Project::new(); + let cmd = FtwCommand::New { + project_name: project.get_name(), + template: FtwTemplate::default(), + tag: FtwTag::default(), + }; + let _ = cmd.process(); + let contents = r#"[ftw] +enable-cross-compilation=true +"#; + let _ = project.create(".ftw", contents); + assert!(project + .read(".ftw") + .contains("enable-cross-compilation=true")); + let _ = env::set_current_dir(Path::new(&project.get_name())); + let target = FtwTarget::IosAarch64; + let targets = vec![target]; + let cmd = FtwCommand::Export { + targets: targets.clone(), + build_type: FtwBuildType::Debug, + }; + let _ = cmd.process(); + let cmd = FtwCommand::Clean; + let _ = cmd.process(); + let _ = env::set_current_dir(Path::new("../")); + assert!(project + .read("rust/Cargo.toml") + .contains(&project.get_name())); + let target_cli_arg = target.to_cli_arg(); + let project_name = project.get_name(); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.pck" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.xcframework" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.xcodeproj" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}" + ))); + } + #[test] fn test_process_ftw_command_cross_export_multi_target() { let project = Project::new(); @@ -1297,6 +1344,7 @@ enable-cross-compilation=true FtwTarget::MacOsX86_64, FtwTarget::WindowsX86_64Gnu, FtwTarget::MacOsAarch64, + FtwTarget::IosAarch64, ]; let cmd = FtwCommand::Export { targets: targets.clone(), @@ -1323,9 +1371,25 @@ enable-cross-compilation=true "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.pck" ))); } - assert!(project.exists(&format!( - "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}{target_app_ext}" - ))); + if target == FtwTarget::IosAarch64 { + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.pck" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.xcframework" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}.xcodeproj" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}" + ))); + } + if target != FtwTarget::IosAarch64 { + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{project_name}.debug.{target_cli_arg}{target_app_ext}" + ))); + } } } diff --git a/src/ftw_compiler.rs b/src/ftw_compiler.rs index 38000b0..8bfa868 100644 --- a/src/ftw_compiler.rs +++ b/src/ftw_compiler.rs @@ -21,10 +21,12 @@ pub enum FtwCompiler { }, } -const DOCKER_IMAGE: &str = "macalimlim/godot-rust-cross-compiler:0.6.0"; +const DOCKER_IMAGE: &str = "macalimlim/godot-rust-cross-compiler:0.7.0"; const MACOSX_CROSS_COMPILER_PATH: &str = "/opt/macosx-build-tools/cross-compiler"; const MIN_MACOSX_SDK_VERSION: &str = "11.3"; const MIN_OSXCROSS_TARGET_VERSION: &str = "20.4"; +const IOS_CROSS_COMPILER_PATH: &str = "/opt/ios-build-tools/cross-compiler"; +const MIN_IOS_SDK_VERSION: &str = "14.5"; const SHELL: &str = "/bin/bash"; #[rustfmt::skip::macros(cmd, format)] @@ -91,9 +93,18 @@ impl Compiler for FtwCompiler { let osxcross_target_version = String::from_utf8(osxcross_target_output.stdout) .unwrap_or(String::from(MIN_OSXCROSS_TARGET_VERSION)); let macosx_cc = format!("CC={MACOSX_CROSS_COMPILER_PATH}/bin/{target_cli_arg}{osxcross_target_version}-cc"); + let ios_sdk_version_output = + cmd!(docker run (DOCKER_IMAGE) ("/bin/bash") ("-c") ("echo $IOS_SDK_VERSION")) + .output()?; + let ios_sdk_version = String::from_utf8(ios_sdk_version_output.stdout) + .unwrap_or(String::from(MIN_IOS_SDK_VERSION)); + let ios_sdk_version = ios_sdk_version.trim(); + let ios_c_include_path = format!("C_INCLUDE_PATH={IOS_CROSS_COMPILER_PATH}/SDK/iPhoneOS{ios_sdk_version}.sdk/usr/include"); + let ios_ld_library_path = format!("LD_LIBRARY_PATH={IOS_CROSS_COMPILER_PATH}/lib"); cmd!(docker run ("-v") (volume_mount) if (target == &FtwTarget::WindowsX86_64Gnu || target == &FtwTarget::WindowsX86_64Msvc) {("-e") ("C_INCLUDE_PATH=/usr/x86_64-w64-mingw32/include")} if (target == &FtwTarget::MacOsAarch64 || target == &FtwTarget::MacOsX86_64) {("-e") (macosx_cc) ("-e") (macosx_c_include_path)} + if (target == &FtwTarget::IosAarch64) {("-e") (ios_c_include_path) ("-e") (ios_ld_library_path)} (DOCKER_IMAGE) (SHELL) ("-c") (cargo_build_cmd)).run() } diff --git a/tests/test_ftw_build.rs b/tests/test_ftw_build.rs index 415d863..34a16fe 100644 --- a/tests/test_ftw_build.rs +++ b/tests/test_ftw_build.rs @@ -295,7 +295,7 @@ enable-cross-compilation=true .contains("enable-cross-compilation=true")); ftw() .arg("build") - .arg("macos-aarch64,windows-x86_64-gnu,linux-x86_64,macos-x86_64,android-aarch64") + .arg("macos-aarch64,windows-x86_64-gnu,linux-x86_64,macos-x86_64,android-aarch64,ios-aarch64") .current_dir(&project.get_name()) .assert() .success(); @@ -303,9 +303,12 @@ enable-cross-compilation=true .read("rust/Cargo.toml") .contains(&project.get_name())); let targets = vec![ + FtwTarget::AndroidLinuxAarch64, FtwTarget::MacOsAarch64, FtwTarget::LinuxX86_64, FtwTarget::MacOsX86_64, + FtwTarget::WindowsX86_64Gnu, + FtwTarget::IosAarch64, ]; for target in targets { let target_cli_arg = target.to_cli_arg(); diff --git a/tests/test_ftw_export.rs b/tests/test_ftw_export.rs index 08f6923..1418f2a 100644 --- a/tests/test_ftw_export.rs +++ b/tests/test_ftw_export.rs @@ -175,6 +175,52 @@ enable-cross-compilation=true ))); } +#[test] +fn test_ftw_cross_export_ios_target() { + let project = Project::new(); + let project_name = project.get_name(); + ftw() + .arg("new") + .arg(&project_name) + .assert() + .success() + .stdout(predicates::str::contains("SUCCESS").from_utf8()); + let contents = r#"[ftw] +enable-cross-compilation=true +"#; + let _ = project.create(".ftw", contents); + assert!(project + .read(".ftw") + .contains("enable-cross-compilation=true")); + let target = FtwTarget::IosAarch64; + ftw() + .arg("export") + .arg("ios-aarch64") + .current_dir(&project_name) + .assert() + .success(); + ftw() + .arg("clean") + .current_dir(&project_name) + .assert() + .success(); + let crate_name = get_crate_name_from_path(&format!("{project_name}/rust/")).unwrap(); + assert!(project.read("rust/Cargo.toml").contains(&project_name)); + let target_cli_arg = target.to_cli_arg(); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.pck" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.xcframework" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.xcodeproj" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}" + ))); +} + #[test] fn test_ftw_cross_export_multi_target() { let project = Project::new(); @@ -193,7 +239,7 @@ enable-cross-compilation=true .contains("enable-cross-compilation=true")); ftw() .arg("export") - .arg("macos-aarch64,linux-x86_64,macos-x86_64") + .arg("macos-aarch64,linux-x86_64,macos-x86_64,ios-aarch64") .current_dir(&project.get_name()) .assert() .success(); @@ -211,6 +257,7 @@ enable-cross-compilation=true FtwTarget::MacOsAarch64, FtwTarget::LinuxX86_64, FtwTarget::MacOsX86_64, + FtwTarget::IosAarch64, ]; for target in targets { let target_cli_arg = target.to_cli_arg(); @@ -225,8 +272,24 @@ enable-cross-compilation=true "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.pck" ))); } - assert!(project.exists(&format!( - "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}{target_app_ext}" - ))); + if target == FtwTarget::IosAarch64 { + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.pck" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.xcframework" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}.xcodeproj" + ))); + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}" + ))); + } + if target != FtwTarget::IosAarch64 { + assert!(project.exists(&format!( + "bin/{target_cli_arg}/{crate_name}.debug.{target_cli_arg}{target_app_ext}" + ))); + } } }