mirror of
https://gitlab.com/futo-org/fcast.git
synced 2025-08-24 00:02:50 +00:00
Sender SDK
This commit is contained in:
parent
fdbefc63e0
commit
afc46f3022
147 changed files with 17638 additions and 114 deletions
14
sdk/sender/xtask/Cargo.toml
Normal file
14
sdk/sender/xtask/Cargo.toml
Normal file
|
@ -0,0 +1,14 @@
|
|||
[package]
|
||||
name = "xtask"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.40", features = [ "derive" ] }
|
||||
xshell = "0.2.7"
|
||||
serde = { version = "1.0.219", features = [ "derive" ] }
|
||||
serde_json = "1.0.140"
|
||||
anyhow = "1.0.98"
|
||||
camino = { version = "1.1.10", features = [ "serde1" ] }
|
||||
# uniffi_bindgen = "0.29.4"
|
||||
uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "c66ce860d2832c42b4b24052bbb0608c419f5503" }
|
121
sdk/sender/xtask/src/kotlin.rs
Normal file
121
sdk/sender/xtask/src/kotlin.rs
Normal file
|
@ -0,0 +1,121 @@
|
|||
use anyhow::Result;
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use clap::{Args, Subcommand};
|
||||
use uniffi_bindgen::{
|
||||
bindings::KotlinBindingGenerator, library_mode::generate_bindings, EmptyCrateConfigSupplier,
|
||||
};
|
||||
use xshell::cmd;
|
||||
|
||||
use crate::{sh, workspace};
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum KotlinCommand {
|
||||
BuildAndroidLibrary {
|
||||
#[clap(long)]
|
||||
release: bool,
|
||||
#[clap(long)]
|
||||
src_dir: Utf8PathBuf,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct KotlinArgs {
|
||||
#[clap(subcommand)]
|
||||
pub cmd: KotlinCommand,
|
||||
}
|
||||
|
||||
fn build_for_android_target(
|
||||
target: &str,
|
||||
profile: &str,
|
||||
dest_dir: &str,
|
||||
package_name: &str,
|
||||
) -> Result<Utf8PathBuf> {
|
||||
let sh = sh();
|
||||
let _p = sh.push_dir(workspace::root_path()?);
|
||||
cmd!(
|
||||
sh,
|
||||
"cargo ndk --target {target} -o {dest_dir} build --profile {profile} -p {package_name} --no-default-features --features _android_defaults"
|
||||
)
|
||||
.run()?;
|
||||
|
||||
let profile_dir_name = if profile == "dev" { "debug" } else { profile };
|
||||
let package_camel = package_name.replace('-', "_");
|
||||
let lib_name = format!("lib{package_camel}.so");
|
||||
Ok(workspace::target_path()?
|
||||
.join(target)
|
||||
.join(profile_dir_name)
|
||||
.join(lib_name))
|
||||
}
|
||||
|
||||
fn generate_uniffi_bindings(library_path: &Utf8Path, ffi_generated_dir: &Utf8Path) -> Result<()> {
|
||||
let config_path = workspace::root_path()?.join("sdk/sender/fcast-sender-sdk/uniffi.toml");
|
||||
|
||||
generate_bindings(
|
||||
library_path,
|
||||
None,
|
||||
&KotlinBindingGenerator,
|
||||
&EmptyCrateConfigSupplier,
|
||||
Some(&config_path),
|
||||
ffi_generated_dir,
|
||||
false,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_android_library(release: bool, src_dir: Utf8PathBuf) -> Result<()> {
|
||||
let package_name = "fcast-sender-sdk";
|
||||
|
||||
let jni_libs_dir = src_dir.join("jniLibs");
|
||||
let sh = sh();
|
||||
let _p = sh.push_dir(workspace::root_path()?);
|
||||
sh.create_dir(&jni_libs_dir)?;
|
||||
let jni_libs_dir_str = jni_libs_dir.as_str();
|
||||
|
||||
let kotlin_generated_dir = src_dir.join("kotlin");
|
||||
sh.create_dir(&kotlin_generated_dir)?;
|
||||
|
||||
let profile = if release { "release" } else { "dev" };
|
||||
|
||||
build_for_android_target(
|
||||
"x86_64-linux-android",
|
||||
profile,
|
||||
jni_libs_dir_str,
|
||||
package_name,
|
||||
)?;
|
||||
build_for_android_target(
|
||||
"i686-linux-android",
|
||||
profile,
|
||||
jni_libs_dir_str,
|
||||
package_name,
|
||||
)?;
|
||||
build_for_android_target(
|
||||
"armv7-linux-androideabi",
|
||||
profile,
|
||||
jni_libs_dir_str,
|
||||
package_name,
|
||||
)?;
|
||||
let uniffi_lib_path = build_for_android_target(
|
||||
"aarch64-linux-android",
|
||||
profile,
|
||||
jni_libs_dir_str,
|
||||
package_name,
|
||||
)?;
|
||||
|
||||
generate_uniffi_bindings(&uniffi_lib_path, &kotlin_generated_dir)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl KotlinArgs {
|
||||
pub fn run(self) -> Result<()> {
|
||||
let sh = sh();
|
||||
let _p = sh.push_dir(workspace::root_path()?);
|
||||
|
||||
match self.cmd {
|
||||
KotlinCommand::BuildAndroidLibrary { release, src_dir } => {
|
||||
build_android_library(release, src_dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
sdk/sender/xtask/src/lib.rs
Normal file
15
sdk/sender/xtask/src/lib.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
use xshell::Shell;
|
||||
|
||||
pub mod kotlin;
|
||||
pub mod swift;
|
||||
pub mod workspace;
|
||||
|
||||
thread_local! {
|
||||
static SH: Rc<Shell> = Rc::new(Shell::new().unwrap())
|
||||
}
|
||||
|
||||
pub fn sh() -> Rc<Shell> {
|
||||
SH.with(|sh| sh.clone())
|
||||
}
|
41
sdk/sender/xtask/src/main.rs
Normal file
41
sdk/sender/xtask/src/main.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use xshell::cmd;
|
||||
use xtask::{
|
||||
kotlin,
|
||||
swift::{self, SwiftArgs, SwiftCommand},
|
||||
};
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
Kotlin(kotlin::KotlinArgs),
|
||||
Swift(swift::SwiftArgs),
|
||||
GenerateIos,
|
||||
Hack,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
struct Xtask {
|
||||
#[clap(subcommand)]
|
||||
cmd: Command,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
match Xtask::parse().cmd {
|
||||
Command::Kotlin(cmd) => cmd.run(),
|
||||
Command::Hack => {
|
||||
let sh = xtask::sh();
|
||||
cmd!(sh, "cargo hack check --each-feature").run()?;
|
||||
Ok(())
|
||||
}
|
||||
Command::Swift(cmd) => cmd.run(),
|
||||
Command::GenerateIos => {
|
||||
SwiftArgs {
|
||||
cmd: SwiftCommand::BuildIosLibrary { release: true },
|
||||
}
|
||||
.run()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
89
sdk/sender/xtask/src/swift.rs
Normal file
89
sdk/sender/xtask/src/swift.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
use std::fs::rename;
|
||||
|
||||
use anyhow::Result;
|
||||
use camino::Utf8Path;
|
||||
use clap::{Args, Subcommand};
|
||||
use uniffi_bindgen::{
|
||||
bindings::SwiftBindingGenerator, library_mode::generate_bindings, EmptyCrateConfigSupplier,
|
||||
};
|
||||
use xshell::cmd;
|
||||
|
||||
use crate::{sh, workspace};
|
||||
|
||||
#[derive(Subcommand)]
|
||||
pub enum SwiftCommand {
|
||||
BuildIosLibrary {
|
||||
#[clap(long)]
|
||||
release: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct SwiftArgs {
|
||||
#[clap(subcommand)]
|
||||
pub cmd: SwiftCommand,
|
||||
}
|
||||
|
||||
fn generate_uniffi_bindings(library_path: &Utf8Path, ffi_generated_dir: &Utf8Path) -> Result<()> {
|
||||
generate_bindings(
|
||||
library_path,
|
||||
None,
|
||||
&SwiftBindingGenerator,
|
||||
&EmptyCrateConfigSupplier,
|
||||
None,
|
||||
ffi_generated_dir,
|
||||
false,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_ios_library(release: bool) -> Result<()> {
|
||||
let package_name = "fcast-sender-sdk";
|
||||
let sh = sh();
|
||||
let _p = sh.push_dir(workspace::root_path()?);
|
||||
let profile = if release { "release" } else { "dev" };
|
||||
|
||||
for target in ["aarch64-apple-ios-sim", "aarch64-apple-ios"] {
|
||||
cmd!(
|
||||
sh,
|
||||
"cargo build -p {package_name} --profile={profile} --target={target} --no-default-features --features _ios_defaults"
|
||||
)
|
||||
.run()?;
|
||||
}
|
||||
|
||||
let package_camel = package_name.replace('-', "_");
|
||||
generate_uniffi_bindings(
|
||||
Utf8Path::new(&format!(
|
||||
"target/aarch64-apple-ios-sim/{}/lib{package_camel}.dylib",
|
||||
if release { "release" } else { "debug" }
|
||||
)),
|
||||
"ios-bindings/uniffi/".into(),
|
||||
)?;
|
||||
|
||||
rename(
|
||||
format!("ios-bindings/uniffi/{package_camel}FFI.modulemap"),
|
||||
format!("ios-bindings/uniffi/{package_camel}.modulemap"),
|
||||
)?;
|
||||
|
||||
sh.remove_path(format!("ios-bindings/{package_camel}.xcframework"))?;
|
||||
|
||||
let profile = if release { "release" } else { "debug" };
|
||||
cmd!(
|
||||
sh,
|
||||
"xcodebuild -create-xcframework -library target/aarch64-apple-ios-sim/{profile}/lib{package_camel}.a -library target/aarch64-apple-ios/{profile}/lib{package_camel}.a -headers ios-bindings/uniffi -output ios-bindings/{package_camel}.xcframework"
|
||||
).run()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl SwiftArgs {
|
||||
pub fn run(self) -> Result<()> {
|
||||
let sh = sh();
|
||||
let _p = sh.push_dir(workspace::root_path()?);
|
||||
|
||||
match self.cmd {
|
||||
SwiftCommand::BuildIosLibrary { release } => build_ios_library(release),
|
||||
}
|
||||
}
|
||||
}
|
30
sdk/sender/xtask/src/workspace.rs
Normal file
30
sdk/sender/xtask/src/workspace.rs
Normal file
|
@ -0,0 +1,30 @@
|
|||
use std::env;
|
||||
|
||||
use crate::sh;
|
||||
use anyhow::Result;
|
||||
use camino::Utf8PathBuf;
|
||||
use xshell::cmd;
|
||||
|
||||
pub fn root_path() -> Result<Utf8PathBuf> {
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Metadata {
|
||||
workspace_root: Utf8PathBuf,
|
||||
}
|
||||
|
||||
let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned());
|
||||
let sh = sh();
|
||||
let metadata_json = cmd!(sh, "{cargo} metadata --no-deps --format-version 1").read()?;
|
||||
Ok(serde_json::from_str::<Metadata>(&metadata_json)?.workspace_root)
|
||||
}
|
||||
|
||||
pub fn target_path() -> Result<Utf8PathBuf> {
|
||||
#[derive(serde::Deserialize)]
|
||||
struct Metadata {
|
||||
target_directory: Utf8PathBuf,
|
||||
}
|
||||
|
||||
let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned());
|
||||
let sh = sh();
|
||||
let metadata_json = cmd!(sh, "{cargo} metadata --no-deps --format-version 1").read()?;
|
||||
Ok(serde_json::from_str::<Metadata>(&metadata_json)?.target_directory)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue