Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate the iOS setup #52

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Fix the compilation error, still have linking error
  • Loading branch information
fantasy-fish committed Nov 26, 2024
commit f78e61f14252342edc944f3f4326b7b239cdd171
12 changes: 12 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[target.aarch64-apple-ios]
linker = "xcrun --sdk iphoneos clang"
ar = "xcrun ar"
rustflags = [
"-C", "link-arg=-target",
"-C", "link-arg=arm64-apple-ios",
"-C", "link-arg=-isysroot",
"-C", "link-arg=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
]

[build]
target = "aarch64-apple-ios"
16 changes: 16 additions & 0 deletions crates/brush-ios/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[target.aarch64-apple-ios]
linker = "xcrun"
ar = "xcrun ar"
rustflags = [
"-C", "link-arg=-target",
"-C", "link-arg=arm64-apple-ios",
"-C", "link-arg=-isysroot",
"-C", "link-arg=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk",
"-C", "link-arg=-L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib",
"-C", "link-arg=-F/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/System/Library/Frameworks",
"-C", "link-arg=-syslibroot",
"-C", "link-arg=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
]

[build]
target = "aarch64-apple-ios"
13 changes: 10 additions & 3 deletions crates/brush-ios/Cargo.toml
Original file line number Diff line number Diff line change
@@ -5,21 +5,28 @@ edition = "2021"

[lib]
name = "brush_ios"
crate-type = ["staticlib", "cdylib"]
crate-type = ["staticlib"]

[dependencies]
log = "0.4"
env_logger = "0.11"
brush-viewer = { path = "../brush-viewer"}
rrfd = { path = "../rrfd" }
brush-train = { path = "../brush-train"}
rrfd = { path = "../rrfd", features = ["ios"] }
eframe = { git = "https://github.com/emilk/egui/", rev = "5bfff316c9818b3c140d02bb6cdc488556d46ab7", default-features = false, features = [
"accesskit",
"default_fonts",
"wgpu",
] }
raw-window-handle = "0.6.2"
tokio_with_wasm = { workspace = true, features = ["rt"] }
tokio = { workspace = true, features = ["io-util", "rt"] }

[target.'cfg(target_os = "ios")'.dependencies]
objc = "0.2.7"

[package.metadata]
cargo-xcode = { ios-target = "aarch64-apple-ios" }
cargo-xcode = { ios-target = "aarch64-apple-ios" }

[package.metadata.ios]
deployment_target = "18.1" # Update this to match your device
101 changes: 33 additions & 68 deletions crates/brush-ios/ios-cargo
Original file line number Diff line number Diff line change
@@ -15,33 +15,29 @@ def parse_cargo_toml():
app_id = cargo_toml['package']['metadata']['bundle']['identifier']
return app_name, app_id

def get_sdk_path():
return subprocess.check_output(['xcrun', '--sdk', 'iphoneos', '--show-sdk-path']).decode().strip()

SDK_PATH = get_sdk_path()

env_vars = {
'PATH': f"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:{os.environ.get('PATH', '')}",
'SDKROOT': SDK_PATH,
'IPHONEOS_DEPLOYMENT_TARGET': '14.0',
'CARGO_BUILD_TARGET': 'aarch64-apple-ios',
'TARGET_CC': 'xcrun --sdk iphoneos clang',
'TARGET_AR': 'xcrun ar'
}

def build(args):
# First, ensure iOS target is installed
subprocess.run(['rustup', 'target', 'add', 'aarch64-apple-ios'], check=True)

# Clean previous build artifacts
subprocess.run(['cargo', 'clean'], check=True)

# Set environment variables for the build
build_env = os.environ.copy()

# Remove any flags that might interfere with target_os
if 'RUSTFLAGS' in build_env:
del build_env['RUSTFLAGS']
if 'CARGO_XCODE_TARGET_OS' in build_env:
del build_env['CARGO_XCODE_TARGET_OS']

build_env.update({
'CARGO_BUILD_TARGET': 'aarch64-apple-ios',
'TARGET_CC': 'clang',
'TARGET_AR': 'ar',
'CFLAGS_aarch64_apple_ios': '--target=arm64-apple-ios',
'CARGO_TARGET_AARCH64_APPLE_IOS_LINKER': 'clang',
'CARGO_TARGET_AARCH64_APPLE_IOS_AR': 'ar',
'CARGO_TARGET_DIR': 'target/cargo-ios',
})

# First build all workspace dependencies
# Build scripts will use the host target (macOS)
env_vars = {
'PATH': f"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin:{os.environ.get('PATH', '')}",
'MACOSX_DEPLOYMENT_TARGET': '11.0',
'SDKROOT': subprocess.check_output(['xcrun', '--sdk', 'macosx', '--show-sdk-path']).decode().strip(),
}

# Only specify iOS target for the actual build command
deps_command = [
'cargo', 'build',
'--target', 'aarch64-apple-ios',
@@ -51,52 +47,13 @@ def build(args):
'-p', 'brush-wgsl',
'-p', 'brush-ui',
'-p', 'brush-train',
'-p', 'brush-render',
'-p', 'brush-render'
]

if args.release:
deps_command.append('--release')

print(f"Building dependencies: {' '.join(deps_command)}")
subprocess.run(deps_command, env=build_env, check=True)

# For xcodebuild, use a separate environment
xcode_env = build_env.copy()
xcode_env['CARGO_XCODE_TARGET_OS'] = 'ios' # Only set for xcodebuild

# Generate Xcode project
command = ['cargo', 'xcode']
print(f"Generating Xcode project: {' '.join(command)}")
subprocess.run(command, env=build_env, check=True) # Use build_env without CARGO_XCODE_TARGET_OS

# Build using xcodebuild
build_type = 'Release' if args.release else 'Debug'
xcode_command = [
'xcodebuild',
'-project', 'brush-ios.xcodeproj',
'-scheme', 'brush_ios.dylib (cdylib)',
'-configuration', build_type,
'-sdk', 'iphoneos',
'-destination', 'platform=iOS,id=00008101-001E44560200001E',
'CARGO_TARGET_DIR=target/cargo-ios',
'CARGO_BUILD_TARGET=aarch64-apple-ios',
'CODE_SIGN_IDENTITY=Apple Development',
'DEVELOPMENT_TEAM=783337X36X',
'CODE_SIGN_STYLE=Automatic',
'IPHONEOS_DEPLOYMENT_TARGET=18.1',
'BUILD_LIBRARY_FOR_DISTRIBUTION=YES',
'ENABLE_BITCODE=NO',
'ONLY_ACTIVE_ARCH=YES',
'VALID_ARCHS=arm64',
'ARCHS=arm64',
'SUPPORTED_PLATFORMS=iphoneos',
'SKIP_INSTALL=NO',
'DYLIB_INSTALL_NAME_BASE=@rpath',
'LD_RUNPATH_SEARCH_PATHS=@executable_path/Frameworks',
'OTHER_LDFLAGS=-ObjC',
]

print(f"Building: {' '.join(xcode_command)}")
subprocess.run(xcode_command, env=xcode_env, check=True) # Use xcode_env with CARGO_XCODE_TARGET_OS
subprocess.run(deps_command, env=env_vars, check=True)

def ipa(args):
print("Creating IPA...")
@@ -138,6 +95,14 @@ def get_target(args):
target = args.target
return target

def get_xcrun_path():
try:
return subprocess.check_output(['which', 'xcrun']).decode().strip()
except:
return '/usr/bin/xcrun'

XCRUN_PATH = get_xcrun_path()

def main():
parser = argparse.ArgumentParser()
parser.add_argument('command', choices=['build', 'ipa'])
46 changes: 35 additions & 11 deletions crates/brush-ios/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
use brush_viewer::viewer::Viewer;
use eframe::NativeOptions;
use tokio_with_wasm::alias as tokio;
use brush_train::create_wgpu_setup;
use eframe::egui_wgpu::{WgpuConfiguration, WgpuSetup};

pub fn create_viewer() -> Viewer {
let native_options = NativeOptions {
// Mobile platforms handle viewport differently
..Default::default()
};

Viewer::new(&eframe::CreationContext {
options: &native_options,
..Default::default()
})
}
pub fn create_viewer() {
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();

runtime.block_on(async {
let setup = create_wgpu_setup().await;

let native_options = NativeOptions {
viewport: eframe::egui::ViewportBuilder::default()
.with_inner_size([800.0, 600.0])
.with_active(true),
wgpu_options: WgpuConfiguration {
wgpu_setup: WgpuSetup::Existing {
instance: setup.instance,
adapter: setup.adapter,
device: setup.device,
queue: setup.queue,
},
..Default::default()
},
..Default::default()
};

eframe::run_native(
"Brush",
native_options,
Box::new(|cc| Ok(Box::new(Viewer::new(cc)))),
).unwrap();
});
}
17 changes: 14 additions & 3 deletions crates/brush-viewer/src/viewer.rs
Original file line number Diff line number Diff line change
@@ -177,9 +177,20 @@ impl DataSource {
async fn read(&self) -> anyhow::Result<DataRead> {
match self {
DataSource::PickFile => {
let picked = rrfd::pick_file().await?;
let data = picked.read().await;
Ok(Box::pin(std::io::Cursor::new(data)))
#[cfg(any(target_os = "android", target_os = "ios"))]
{
let picked_file = rrfd::ios::pick_file().await?;
return Ok(Box::pin(std::io::Cursor::new(picked_file.data)));
}

#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
let picked = rrfd::FileDialog::new()
.pick_file()
.ok_or_else(|| anyhow::anyhow!("No file selected"))?;
let contents = tokio::fs::read(&picked).await?;
Ok(Box::pin(std::io::Cursor::new(contents)))
}
}
DataSource::Url(url) => {
let mut url = url.to_owned();