mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 06:26:15 +01:00
Create xcproj for idevice++
This commit is contained in:
130
cpp/xcode_build_rust.sh
Executable file
130
cpp/xcode_build_rust.sh
Executable file
@@ -0,0 +1,130 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script builds a Rust library for use in an Xcode project.
|
||||
# It's designed to be used as a "Run Script" build phase on a native Xcode target.
|
||||
# It handles multiple architectures by building for each and combining them with `lipo`.
|
||||
|
||||
# --- Configuration ---
|
||||
# The name of your Rust crate (the name in Cargo.toml)
|
||||
CRATE_NAME="idevice_ffi"
|
||||
# The path to your Rust project's root directory (containing Cargo.toml)
|
||||
RUST_PROJECT_PATH="${PROJECT_DIR}/../ffi"
|
||||
|
||||
# --- Environment Setup ---
|
||||
# Augment the PATH to include common locations for build tools like cmake and go.
|
||||
export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/local/go/bin:$PATH"
|
||||
|
||||
# --- Locate Cargo ---
|
||||
# Xcode's build environment often has a minimal PATH, so we need to find cargo explicitly.
|
||||
if [ -x "${HOME}/.cargo/bin/cargo" ]; then
|
||||
CARGO="${HOME}/.cargo/bin/cargo"
|
||||
else
|
||||
CARGO=$(command -v cargo)
|
||||
if [ -z "$CARGO" ]; then
|
||||
echo "Error: cargo executable not found." >&2
|
||||
echo "Please ensure Rust is installed and cargo is in your PATH or at ~/.cargo/bin/" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# --- Script Logic ---
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status.
|
||||
set -e
|
||||
|
||||
# --- Platform & SDK Configuration ---
|
||||
# In a "Run Script" phase on a native target, PLATFORM_NAME is reliable.
|
||||
# We use it to determine the correct SDK and build parameters.
|
||||
PLATFORM_SUFFIX=""
|
||||
SDK_NAME=""
|
||||
|
||||
if [ "$PLATFORM_NAME" = "iphoneos" ]; then
|
||||
PLATFORM_SUFFIX="-iphoneos"
|
||||
SDK_NAME="iphoneos"
|
||||
elif [ "$PLATFORM_NAME" = "iphonesimulator" ]; then
|
||||
PLATFORM_SUFFIX="-iphonesimulator"
|
||||
SDK_NAME="iphonesimulator"
|
||||
elif [ "$PLATFORM_NAME" = "macosx" ]; then
|
||||
PLATFORM_SUFFIX=""
|
||||
SDK_NAME="macosx"
|
||||
else
|
||||
echo "Error: Unsupported platform '$PLATFORM_NAME'" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the SDK path. This is crucial for cross-compilation.
|
||||
SDK_PATH=$(xcrun --sdk ${SDK_NAME} --show-sdk-path)
|
||||
echo "Configured for cross-compilation with SDK: ${SDK_PATH}"
|
||||
|
||||
# Export variables needed by crates like `bindgen` to find the correct headers.
|
||||
export BINDGEN_EXTRA_CLANG_ARGS="--sysroot=${SDK_PATH}"
|
||||
export SDKROOT="${SDK_PATH}" # Also respected by some build scripts.
|
||||
|
||||
STATIC_LIB_NAME="lib$(echo $CRATE_NAME | sed 's/-/_/g').a"
|
||||
LIPO_INPUT_FILES=""
|
||||
|
||||
# Determine if this is a release or debug build.
|
||||
if [ "$CONFIGURATION" = "Release" ]; then
|
||||
RELEASE_FLAG="--release"
|
||||
RUST_BUILD_SUBDIR="release"
|
||||
else
|
||||
RELEASE_FLAG=""
|
||||
RUST_BUILD_SUBDIR="debug"
|
||||
fi
|
||||
|
||||
# Loop through each architecture specified by Xcode.
|
||||
for ARCH in $ARCHS; do
|
||||
# Determine the Rust target triple based on the architecture and platform.
|
||||
if [ "$PLATFORM_NAME" = "macosx" ]; then
|
||||
if [ "$ARCH" = "arm64" ]; then
|
||||
RUST_TARGET="aarch64-apple-darwin"
|
||||
else
|
||||
RUST_TARGET="x86_64-apple-darwin"
|
||||
fi
|
||||
elif [ "$PLATFORM_NAME" = "iphoneos" ]; then
|
||||
RUST_TARGET="aarch64-apple-ios"
|
||||
elif [ "$PLATFORM_NAME" = "iphonesimulator" ]; then
|
||||
if [ "$ARCH" = "arm64" ]; then
|
||||
RUST_TARGET="aarch64-apple-ios-sim"
|
||||
else
|
||||
RUST_TARGET="x86_64-apple-ios"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Building for arch: ${ARCH}, Rust target: ${RUST_TARGET}"
|
||||
|
||||
# --- Configure Linker for Cargo ---
|
||||
# Use RUSTFLAGS to pass linker arguments directly to rustc. This is the most
|
||||
# reliable way to ensure the linker finds system libraries in the correct SDK.
|
||||
export RUSTFLAGS="-C link-arg=-L${SDK_PATH}/usr/lib"
|
||||
# export PATH="${SDK_PATH}:$PATH"
|
||||
|
||||
# Run the cargo build command. It will inherit the exported RUSTFLAGS.
|
||||
(cd "$RUST_PROJECT_PATH" && ${CARGO} build ${RELEASE_FLAG} --target ${RUST_TARGET})
|
||||
|
||||
BUILT_LIB_PATH="${RUST_PROJECT_PATH}/../target/${RUST_TARGET}/${RUST_BUILD_SUBDIR}/${STATIC_LIB_NAME}"
|
||||
|
||||
# Add the path of the built library to our list for `lipo`.
|
||||
LIPO_INPUT_FILES="${LIPO_INPUT_FILES} ${BUILT_LIB_PATH}"
|
||||
done
|
||||
|
||||
# --- Universal Library Creation ---
|
||||
|
||||
# Construct the correct, platform-specific destination directory.
|
||||
DESTINATION_DIR="${BUILT_PRODUCTS_DIR}"
|
||||
mkdir -p "${DESTINATION_DIR}"
|
||||
DESTINATION_PATH="${DESTINATION_DIR}/${STATIC_LIB_NAME}"
|
||||
|
||||
echo "Creating universal library for architectures: $ARCHS"
|
||||
echo "Input files: ${LIPO_INPUT_FILES}"
|
||||
echo "Output path: ${DESTINATION_PATH}"
|
||||
|
||||
# Use `lipo` to combine the individual architecture libraries into one universal library.
|
||||
lipo -create ${LIPO_INPUT_FILES} -output "${DESTINATION_PATH}"
|
||||
|
||||
echo "Universal library created successfully."
|
||||
|
||||
# Verify the architectures in the final library.
|
||||
lipo -info "${DESTINATION_PATH}"
|
||||
|
||||
echo "Rust build script finished successfully."
|
||||
Reference in New Issue
Block a user