From 4ab6f1a9bc6df8572fa221f5beddaf56666c5d44 Mon Sep 17 00:00:00 2001 From: Ebrahim Tahernejad Date: Thu, 29 Feb 2024 07:08:44 +0330 Subject: [PATCH] XCFramework build for apple (#93) --- README.md | 6 ++++ apple/tun2proxy/Tun2proxyWrapper.m | 4 +-- build-apple.sh | 44 ++++++++++++++++++++++++++++++ cbindgen.toml | 7 +++-- src/{ios.rs => apple.rs} | 12 ++++++-- src/desktop_api.rs | 11 ++++++-- src/lib.rs | 5 +++- src/mobile_api.rs | 11 +++++--- 8 files changed, 85 insertions(+), 15 deletions(-) create mode 100755 build-apple.sh rename src/{ios.rs => apple.rs} (67%) diff --git a/README.md b/README.md index 15ab769..952ed3a 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ Clone the repository and `cd` into the project folder. Then run the following: cargo build --release ``` +### Building Framework for Apple Devices +To build an XCFramework for macOS and iOS, run the following: +``` +./build-apple.sh +``` + ## Installation ### Install from binary diff --git a/apple/tun2proxy/Tun2proxyWrapper.m b/apple/tun2proxy/Tun2proxyWrapper.m index dd8c75d..d6a088e 100644 --- a/apple/tun2proxy/Tun2proxyWrapper.m +++ b/apple/tun2proxy/Tun2proxyWrapper.m @@ -19,11 +19,11 @@ verbose:(bool)verbose { ArgDns dns_strategy = dns_over_tcp ? OverTcp : Direct; ArgVerbosity v = verbose ? Trace : Info; - tun2proxy_run_with_fd(proxy_url.UTF8String, tun_fd, tun_mtu, dns_strategy, v); + tun2proxy_with_fd_run(proxy_url.UTF8String, tun_fd, tun_mtu, dns_strategy, v); } + (void)shutdown { - tun2proxy_stop(); + tun2proxy_with_fd_stop(); } @end diff --git a/build-apple.sh b/build-apple.sh new file mode 100755 index 0000000..7470b9a --- /dev/null +++ b/build-apple.sh @@ -0,0 +1,44 @@ +#! /bin/sh + +echo "Setting up the rust environment..." +rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios x86_64-apple-darwin aarch64-apple-darwin +cargo install cbindgen + +echo "Building..." +cargo build --release --target x86_64-apple-darwin +cargo build --release --target aarch64-apple-darwin +cargo build --release --target aarch64-apple-ios +cargo build --release --target x86_64-apple-ios +cargo build --release --target aarch64-apple-ios-sim + +echo "Generating includes..." +mkdir -p target/include/ +cbindgen --config cbindgen.toml -l C -o target/include/tun2proxy.h +cat > target/include/module.modulemap < c_int { +pub unsafe extern "C" fn tun2proxy_with_fd_stop() -> c_int { crate::mobile_api::mobile_stop() } diff --git a/src/desktop_api.rs b/src/desktop_api.rs index 61dab33..5d8bb69 100644 --- a/src/desktop_api.rs +++ b/src/desktop_api.rs @@ -13,8 +13,15 @@ static TUN_QUIT: std::sync::Mutex> = /// # Safety /// /// Run the tun2proxy component with some arguments. +/// Parameters: +/// - proxy_url: the proxy url, e.g. "socks5://127.0.0.1:1080" +/// - tun: the tun device name, e.g. "utun5" +/// - bypass: the bypass ip, e.g. "123.45.67.89" +/// - dns_strategy: the dns strategy, see ArgDns enum +/// - root_privilege: whether to run with root privilege +/// - verbosity: the verbosity level, see ArgVerbosity enum #[no_mangle] -pub unsafe extern "C" fn tun2proxy_run_with_name( +pub unsafe extern "C" fn tun2proxy_with_name_run( proxy_url: *const c_char, tun: *const c_char, bypass: *const c_char, @@ -142,7 +149,7 @@ pub async fn desktop_run_async(args: Args, shutdown_token: tokio_util::sync::Can /// /// Shutdown the tun2proxy component. #[no_mangle] -pub unsafe extern "C" fn tun2proxy_stop() -> c_int { +pub unsafe extern "C" fn tun2proxy_with_name_stop() -> c_int { if let Ok(lock) = TUN_QUIT.lock() { if let Some(shutdown_token) = lock.as_ref() { shutdown_token.cancel(); diff --git a/src/lib.rs b/src/lib.rs index c37be76..9020cb3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -29,7 +29,11 @@ pub use desktop_api::desktop_run_async; #[cfg(any(target_os = "ios", target_os = "android"))] pub use mobile_api::{desktop_run_async, mobile_run, mobile_stop}; +#[cfg(target_os = "macos")] +pub use mobile_api::{mobile_run, mobile_stop}; + mod android; +mod apple; mod args; mod desktop_api; mod directions; @@ -37,7 +41,6 @@ mod dns; mod dump_logger; mod error; mod http; -mod ios; mod mobile_api; mod proxy_handler; mod session_info; diff --git a/src/mobile_api.rs b/src/mobile_api.rs index bf2573c..6d04390 100644 --- a/src/mobile_api.rs +++ b/src/mobile_api.rs @@ -1,4 +1,4 @@ -#![cfg(any(target_os = "ios", target_os = "android"))] +#![cfg(any(target_os = "ios", target_os = "android", target_os = "macos"))] use crate::Args; use std::os::raw::c_int; @@ -7,6 +7,7 @@ static TUN_QUIT: std::sync::Mutex> = /// Dummy function to make the build pass. #[doc(hidden)] +#[cfg(not(target_os = "macos"))] pub async fn desktop_run_async(_: Args, _: tokio_util::sync::CancellationToken) -> std::io::Result<()> { Ok(()) } @@ -28,11 +29,13 @@ pub fn mobile_run(args: Args, tun_mtu: u16) -> c_int { #[cfg(unix)] if let Some(fd) = args.tun_fd { config.raw_fd(fd); - } else { - config.name(&args.tun); + } else if let Some(ref tun) = args.tun { + config.tun_name(tun); } #[cfg(windows)] - config.name(&args.tun); + if let Some(ref tun) = args.tun { + config.tun_name(tun); + } let device = tun2::create_as_async(&config).map_err(std::io::Error::from)?; let join_handle = tokio::spawn(crate::run(device, tun_mtu, args, shutdown_token));