Skip to content

Commit

Permalink
feat: add iOS CI (#520)
Browse files Browse the repository at this point in the history
* add cargo run -- export --target ios
add cargo run -- run --target ios
add iOS ci

* [REVERT] only iOS ci

* fix

* format and split build and run

* test

* add target

* fix presets

* fix paths

* fix ios

* test

* add code signing

* debug

* test

* w

* test

* w

* test

* fixx

* FIX

* export project only

* fixes

* restore ci

* fmt

* fix android
  • Loading branch information
kuruk-mm authored Dec 12, 2024
1 parent bf51014 commit fb48da6
Show file tree
Hide file tree
Showing 12 changed files with 590 additions and 234 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/ios_builds.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: 🍏 iOS
on:
workflow_call:

concurrency:
group: ci-${{ github.actor }}-${{ github.head_ref || github.run_number }}-${{ github.ref }}-ios
cancel-in-progress: true

jobs:
build:
name: Build iOS
strategy:
fail-fast: false
matrix:
os: [macos-14-xlarge]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4

- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: 1.77.2
override: true
target: aarch64-apple-ios

# Dependencies section
- name: Install dependencies
uses: ./.github/actions/install-deps

# Build section
- name: Cargo install
run: cargo run -- install --platforms ios

- name: Build
run: cargo run -- build --release --target ios

- name: Import Assets
uses: ./.github/actions/import-assets

- name: Export
run: cargo run -- export --target ios

- uses: actions/upload-artifact@v4
with:
name: decentraland-godot-ios
path: |
exports/**/*
5 changes: 5 additions & 0 deletions .github/workflows/runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ jobs:
needs: static-checks
uses: ./.github/workflows/macos_builds.yml

ios-build:
name: 🍏 iOS
needs: static-checks
uses: ./.github/workflows/ios_builds.yml

windows-build:
name: 🏁 Windows
needs: static-checks
Expand Down
3 changes: 1 addition & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"command": "run",
"args": [
"--",
"run",
"--only-build"
"build",
],
"problemMatcher": [
"$rustc"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ cd ../../ # return

# Compile for Linux
cargo run -- install --platforms android
cargo run -- run --only-build
cargo run -- build
cd ../../ # return

# Generate .APK
Expand Down
10 changes: 5 additions & 5 deletions build-android-apk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fi
echo "Build for Linux x86_64"
cd ${EXPLORER_PATH}
cargo run -- install --platforms android
cargo run -- run --only-build
cargo run -- build

echo "Link export templates"
mkdir -p ${HOME}/.local/share/godot/export_templates/
Expand Down Expand Up @@ -53,7 +53,7 @@ cd ${EXPLORER_PATH}/godot/
echo "Export Godot android.apk"

# Define the command to be executed
COMMAND="${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-debug Android ${EXPLORER_PATH}/android.apk"
COMMAND="${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-debug android ${EXPLORER_PATH}/android.apk"

# Try executing the command
if ! $COMMAND; then
Expand All @@ -70,7 +70,7 @@ else
echo "First attempt succeeded."
fi

${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-debug Quest ${EXPLORER_PATH}/meta-quest.apk || true
${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-debug quest ${EXPLORER_PATH}/meta-quest.apk || true


# Build the .aab without x86_64 architecture
Expand All @@ -84,7 +84,7 @@ sed -i 's/package\/signed=true/package\/signed=false/' ${EXPLORER_PATH}/godot/ex

# Build the .aab without x86_64 architecture
echo "Export Godot AAB"
${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-release Android ${EXPLORER_PATH}/android-unsigned.aab || true
${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-release Quest ${EXPLORER_PATH}/meta-quest-unsigned.aab || true
${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-release android ${EXPLORER_PATH}/android-unsigned.aab || true
${EXPLORER_PATH}/.bin/godot/godot4_bin -e --headless --export-release quest ${EXPLORER_PATH}/meta-quest-unsigned.aab || true

echo "Finished"
12 changes: 6 additions & 6 deletions godot/export_presets.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ texture_format/etc2=false

[preset.3]

name="Android"
name="android"
platform="Android"
runnable=true
advanced_options=true
Expand Down Expand Up @@ -601,7 +601,7 @@ pico_xr_features/face_tracking=0

[preset.4]

name="iOS"
name="ios"
platform="iOS"
runnable=true
advanced_options=true
Expand Down Expand Up @@ -635,9 +635,9 @@ application/version="13"
application/min_ios_version="16.0"
application/additional_plist_content=""
application/icon_interpolation=4
application/export_project_only=false
application/delete_old_export_files_unconditionally=false
application/generate_simulator_library_if_missing=true
application/export_project_only=true
application/delete_old_export_files_unconditionally=true
application/generate_simulator_library_if_missing=false
plugins/WebKit=true
capabilities/access_wifi=false
capabilities/push_notifications=false
Expand Down Expand Up @@ -831,7 +831,7 @@ portrait_launch_screens/iphone_1242x2208=""

[preset.5]

name="Quest"
name="quest"
platform="Android"
runnable=false
advanced_options=true
Expand Down
4 changes: 4 additions & 0 deletions lib/ios-build.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#!/bin/bash

echo "Please use 'cargo run -- build --release --target ios'"
echo "Waiting 5 seconds to execute the legacy script..."
sleep 5

export FFMPEG_DIR=~/github/ffmpeg-kit/prebuilt/apple-ios-arm64/ffmpeg
export RUSTY_V8_MIRROR=https://github.com/leanmendoza/rusty_v8/releases/download

Expand Down
196 changes: 159 additions & 37 deletions src/copy_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,51 +45,173 @@ pub fn copy_if_modified<P: AsRef<Path>, Q: AsRef<Path>>(
Ok(())
}

pub fn copy_library(debug_mode: bool, link_libs: bool) -> Result<(), anyhow::Error> {
let os = env::consts::OS;
let arch = env::consts::ARCH;
let file_name = match (os, arch) {
("linux", _) => Some("libdclgodot.so".to_string()),
("windows", _) => Some("dclgodot.dll".to_string()),
("macos", _) => Some("libdclgodot.dylib".to_string()),
_ => None,
pub fn copy_library(
target: &String,
debug_mode: bool,
link_libs: bool,
) -> Result<(), anyhow::Error> {
let mode = if debug_mode { "debug" } else { "release" };

match target.as_str() {
"ios" => {
let source_file = format!(
"{RUST_LIB_PROJECT_FOLDER}target/aarch64-apple-ios/{mode}/libdclgodot.dylib"
);
let dest = format!("{}lib/ios/libdclgodot.dylib", GODOT_PROJECT_FOLDER);

copy_with_error_context(&source_file, &dest, link_libs)?;

// If you need ffmpeg for iOS specifically:
// copy_ffmpeg_libraries(target, format!("{}ios/", GODOT_PROJECT_FOLDER), link_libs)?;
}

"android" => {
let source_file = format!(
"{RUST_LIB_PROJECT_FOLDER}target/aarch64-linux-android/{mode}/libdclgodot.so"
);

let dest1 = format!("{}lib/android/arm64/libdclgodot.so", GODOT_PROJECT_FOLDER);
copy_with_error_context(&source_file, &dest1, link_libs)?;

let dest2 = format!(
"{}android/build/libs/release/arm64-v8a/libdclgodot.so",
GODOT_PROJECT_FOLDER
);
copy_with_error_context(&source_file, &dest2, link_libs)?;

// If you need ffmpeg for Android specifically:
// copy_ffmpeg_libraries(target, format!("{}android/arm64/", GODOT_PROJECT_FOLDER), link_libs)?;
}

"win64" | "linux" | "macos" => {
// For Windows, Linux, Mac we revert to the old logic:
let file_name = match target.as_str() {
"win64" => "dclgodot.dll",
"linux" => "libdclgodot.so",
"macos" => "libdclgodot.dylib",
_ => unreachable!(), // already covered by the match above
};

let source_folder = format!("{RUST_LIB_PROJECT_FOLDER}target/{}/", mode);
let source_path = adjust_canonicalization(
std::fs::canonicalize(&source_folder)
.map_err(|e| {
anyhow::anyhow!(
"Failed to canonicalize source folder {}: {}",
source_folder,
e
)
})?
.join(file_name),
);

let lib_folder = format!("{}lib/", GODOT_PROJECT_FOLDER);
let destination_path = adjust_canonicalization(
std::fs::canonicalize(&lib_folder)
.map_err(|e| {
anyhow::anyhow!(
"Failed to canonicalize destination folder {}: {}",
lib_folder.to_string(),
e
)
})?
.join(file_name),
);

copy_if_modified(source_path.clone(), destination_path.clone(), link_libs).map_err(
|e| {
anyhow::anyhow!(
"Failed to copy from {:?} to {:?}: {}",
source_path,
destination_path,
e
)
},
)?;

// If on Windows and debug mode, also copy PDB
if debug_mode && target == "win64" {
let pdb_name = "dclgodot.pdb";
let pdb_source = adjust_canonicalization(
std::fs::canonicalize(&source_folder)
.map_err(|e| {
anyhow::anyhow!(
"Failed to canonicalize source folder {}: {}",
source_folder,
e
)
})?
.join(pdb_name),
);
let pdb_dest = adjust_canonicalization(
std::fs::canonicalize(&lib_folder)
.map_err(|e| {
anyhow::anyhow!(
"Failed to canonicalize destination folder {}: {}",
lib_folder,
e
)
})?
.join(pdb_name),
);

copy_if_modified(pdb_source.clone(), pdb_dest.clone(), link_libs).map_err(|e| {
anyhow::anyhow!(
"Failed to copy PDB from {:?} to {:?}: {}",
pdb_source,
pdb_dest,
e
)
})?;
}

copy_ffmpeg_libraries(target, lib_folder.clone(), link_libs).map_err(|e| {
anyhow::anyhow!("Failed to copy FFmpeg libraries to {}: {}", lib_folder, e)
})?;
}

other => return Err(anyhow::anyhow!("Unknown target: {}", other)),
}
.expect("Couldn't find a library for this platform");

let source_folder: &str = if debug_mode {
"target/debug/"
} else {
"target/release/"
};

let source_folder = format!("{RUST_LIB_PROJECT_FOLDER}{source_folder}");

let source_file =
adjust_canonicalization(fs::canonicalize(source_folder.clone())?.join(file_name.clone()));

let lib_folder = format!("{GODOT_PROJECT_FOLDER}lib/");
let destination_file =
adjust_canonicalization(fs::canonicalize(lib_folder.as_str())?.join(file_name.clone()));
copy_if_modified(source_file, destination_file, link_libs)?;

if debug_mode && os == "windows" {
let source_file = adjust_canonicalization(
fs::canonicalize(source_folder)?.join("dclgodot.pdb".to_string()),
);
let destination_file = adjust_canonicalization(
fs::canonicalize(lib_folder.as_str())?.join("dclgodot.pdb".to_string()),
);
copy_if_modified(source_file, destination_file, link_libs)?;
Ok(())
}

/// A small helper to copy a file and provide better error messages.
fn copy_with_error_context(
source: &str,
destination: &str,
link_libs: bool,
) -> Result<(), anyhow::Error> {
// Ensure destination directory exists
if let Some(parent) = std::path::Path::new(destination).parent() {
std::fs::create_dir_all(parent).map_err(|e| {
anyhow::anyhow!("Failed to create directory {}: {}", parent.display(), e)
})?;
}

copy_ffmpeg_libraries(lib_folder, link_libs)?;
let source_path = std::fs::canonicalize(source)
.map_err(|e| anyhow::anyhow!("Failed to canonicalize {}: {}", source, e))?;

let dest_path = std::path::PathBuf::from(destination);

copy_if_modified(source_path.clone(), dest_path.clone(), link_libs).map_err(|e| {
anyhow::anyhow!(
"Failed to copy from {:?} to {:?}: {}",
source_path,
dest_path,
e
)
})?;

Ok(())
}

pub fn copy_ffmpeg_libraries(dest_folder: String, link_libs: bool) -> Result<(), anyhow::Error> {
let os = env::consts::OS;
if os == "windows" {
pub fn copy_ffmpeg_libraries(
target: &String,
dest_folder: String,
link_libs: bool,
) -> Result<(), anyhow::Error> {
if target == "windows" {
// copy ffmpeg .dll
let ffmpeg_dll_folder = format!("{BIN_FOLDER}ffmpeg/ffmpeg-6.0-full_build-shared/bin");

Expand Down
Loading

0 comments on commit fb48da6

Please sign in to comment.