diff --git a/Cargo.toml b/Cargo.toml index 97c0367..799c36b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,16 +8,12 @@ edition = "2018" [lib] name = "test1" -crate-type = ["staticlib", "lib"] +crate-type = ["staticlib"] [build-dependencies] cbindgen = "*" [dependencies] -lazy_static = "1.4.0" -twox-hash = "1.5.0" -foreign-types = "*" -libc = "*" [profile.dev] panic = 'unwind' diff --git a/Readme.md b/Readme.md index 05c8caf..d0470e0 100644 --- a/Readme.md +++ b/Readme.md @@ -1,84 +1,69 @@ # Rust Catalyst Example -This is an example that shows how to build a static library supporting Catalyst from Rust. +This is an example that shows how to build a static library supporting Mac Catalyst (X86_64 and ARM64) from Rust. -## Requirements - -1. [Xargo](https://github.com/japaric/xargo) -2. Rust Nightly -3. Rust Source (after switching to nightly) -4. Xcode 11+ -## Not Required -- the `XARGO_RUST_SRC` env variable - -## Full Local Installation - -``` bash -cargo install xargo -rustup toolchain install nightly -rustup toolchain default nightly +# Usage -# Or use a directory override -rustup override set nightly -``` +Until [this PR that adds Catalyst ARM64 support to Rust](https://github.com/rust-lang/rust/pull/77484) is merged, you need to build the Rust compiler. Hence, jump to the end to see how to build and use a custom Rust toolchain based on 77484. -## Using It +This repo contains an Xcode project that sets up everything to include a library written in Rust and call functions in it. The repo is set up to use ARM64 and X86_64 Catalyst. It should compile fine if you select the `My Mac` target. If you select the `Any Mac` target, it requires the above mentioned PR / a custom toolchain. -Just do a release build with the correct target +The Xcode project also contains all the required binaries to try this out immediately. You can just open `XcodeIntegration.xcodeproj` and build. -``` bash -xargo build --target x86_64-apple-ios-macabi --release -``` +# Usage with normal nightly Rust -## Caveats -- Building for other archs (such as the host arch) also requires setting the target. -- Non-Release builds fail on some targets -- Lipo can be used to make a fat binary (see below) +## Requirements -## Fat Binary +1. Rustup / Rust Nightly +2. Xcode 12 -This requires that the correct targets are installed for non-macabi: +## Full Local Installation ``` bash +rustup toolchain install nightly +rustup toolchain default nightly rustup target add aarch64-apple-ios -``` +rustup target add x86_64-apple-ios -Then the following will generate a fat binary. You can also just call the `make_fat.sh` included in the example project. +# Or use a directory override +rustup override set nightly -``` bash -# lipo together the different architectures into a universal 'fat' file -xargo build --target x86_64-apple-ios-macabi --release -xargo build --target aarch64-apple-ios --release -lipo -create -output target/libtest1.a target/{x86_64-apple-darwin,aarch64-apple-ios,x86_64-apple-darwin}/release/libtest1.a +./make_fat.sh ``` -Note that we're not including `x86_64-apple-darwin` because a fat binary cannot contain darwing x86_64 and iOS x86_64 together. +It will automatically generate the binaries and write them to `XcodeIntegration/Rust` -# How it works +Open Xcode, hit compile. -Tx86_64-he `x86_64-apple-ios-macabi.json` file contains the information that `Xargo` needs to build a custom sysroot to compile your project with. -A sysroot is the `libstd`, `libcore` and so on. +### build-std -## Cargo.toml +Catalyst is not a tier 1 Rust platform, so there is no pre-build standard library. This repository uses `cargo build-std` to automatically build the standard library for the given platform. This takes a bit longer but works reliably (at least for me). -The panic line: +## Custom Rust Toolchain -``` toml -[profile.release] -panic = "abort" +``` +git clone https://github.com/rust-lang/rust.git +cd rust +cp config.toml.sample config.toml ``` -Seems to be required as `panic_unwind` leads to a failing build. - -## Xargo.toml +Edit config.toml and change `build-stage = 1` to `build-stage = 2` (line 149) + +``` +./x.py build +``` + +Install with +``` +rustup toolchain link myrust ~/rust/build/x86_64-apple-darwin/stage2/ +``` -Just copy the contents verbatim. Otherwise it fails to build `libstd`. +Go back to this directory +``` +rustup default myrust +``` -``` toml -std = {features = ["jemalloc"]} +Now you can continue with (Full Local Installation) above. -[dependencies] -std = {} -``` diff --git a/XcodeIntegration/XcodeIntegration.xcodeproj/project.pbxproj b/XcodeIntegration/XcodeIntegration.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8d4cc22 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration.xcodeproj/project.pbxproj @@ -0,0 +1,392 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 52; + objects = { + +/* Begin PBXBuildFile section */ + 4DF9883A2529A7DD0088E92B /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF988392529A7DD0088E92B /* AppDelegate.swift */; }; + 4DF9883C2529A7DD0088E92B /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF9883B2529A7DD0088E92B /* SceneDelegate.swift */; }; + 4DF9883E2529A7DD0088E92B /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DF9883D2529A7DD0088E92B /* ContentView.swift */; }; + 4DF988402529A7DE0088E92B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4DF9883F2529A7DE0088E92B /* Assets.xcassets */; }; + 4DF988432529A7DE0088E92B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4DF988422529A7DE0088E92B /* Preview Assets.xcassets */; }; + 4DF988462529A7DE0088E92B /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4DF988442529A7DE0088E92B /* LaunchScreen.storyboard */; }; + 4DF988502529A8150088E92B /* Rust in Resources */ = {isa = PBXBuildFile; fileRef = 4DF9884F2529A8150088E92B /* Rust */; }; + 4DF9886E2529B69D0088E92B /* libtest1_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF9886D2529B69D0088E92B /* libtest1_ios.a */; platformFilter = ios; }; + 4DF988712529B69F0088E92B /* libtest1_mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF988702529B69F0088E92B /* libtest1_mac.a */; platformFilter = maccatalyst; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 4DF988362529A7DD0088E92B /* XcodeIntegration.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = XcodeIntegration.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 4DF988392529A7DD0088E92B /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 4DF9883B2529A7DD0088E92B /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + 4DF9883D2529A7DD0088E92B /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 4DF9883F2529A7DE0088E92B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 4DF988422529A7DE0088E92B /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 4DF988452529A7DE0088E92B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 4DF988472529A7DE0088E92B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 4DF9884F2529A8150088E92B /* Rust */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Rust; sourceTree = ""; }; + 4DF988532529A8770088E92B /* libtest1.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtest1.a; path = Rust/libtest1.a; sourceTree = ""; }; + 4DF988572529A9D90088E92B /* XcodeIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = XcodeIntegration.h; sourceTree = ""; }; + 4DF9885B2529ABBB0088E92B /* XcodeIntegration.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = XcodeIntegration.entitlements; sourceTree = ""; }; + 4DF9886D2529B69D0088E92B /* libtest1_ios.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtest1_ios.a; path = XcodeIntegration/Rust/libtest1_ios.a; sourceTree = ""; }; + 4DF988702529B69F0088E92B /* libtest1_mac.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtest1_mac.a; path = XcodeIntegration/Rust/libtest1_mac.a; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4DF988332529A7DD0088E92B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF9886E2529B69D0088E92B /* libtest1_ios.a in Frameworks */, + 4DF988712529B69F0088E92B /* libtest1_mac.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4DF9882D2529A7DD0088E92B = { + isa = PBXGroup; + children = ( + 4DF988382529A7DD0088E92B /* XcodeIntegration */, + 4DF988372529A7DD0088E92B /* Products */, + 4DF988522529A8770088E92B /* Frameworks */, + ); + sourceTree = ""; + }; + 4DF988372529A7DD0088E92B /* Products */ = { + isa = PBXGroup; + children = ( + 4DF988362529A7DD0088E92B /* XcodeIntegration.app */, + ); + name = Products; + sourceTree = ""; + }; + 4DF988382529A7DD0088E92B /* XcodeIntegration */ = { + isa = PBXGroup; + children = ( + 4DF9885B2529ABBB0088E92B /* XcodeIntegration.entitlements */, + 4DF9884F2529A8150088E92B /* Rust */, + 4DF988392529A7DD0088E92B /* AppDelegate.swift */, + 4DF9883B2529A7DD0088E92B /* SceneDelegate.swift */, + 4DF9883D2529A7DD0088E92B /* ContentView.swift */, + 4DF9883F2529A7DE0088E92B /* Assets.xcassets */, + 4DF988442529A7DE0088E92B /* LaunchScreen.storyboard */, + 4DF988472529A7DE0088E92B /* Info.plist */, + 4DF988412529A7DE0088E92B /* Preview Content */, + 4DF988572529A9D90088E92B /* XcodeIntegration.h */, + ); + path = XcodeIntegration; + sourceTree = ""; + }; + 4DF988412529A7DE0088E92B /* Preview Content */ = { + isa = PBXGroup; + children = ( + 4DF988422529A7DE0088E92B /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 4DF988522529A8770088E92B /* Frameworks */ = { + isa = PBXGroup; + children = ( + 4DF9886D2529B69D0088E92B /* libtest1_ios.a */, + 4DF988702529B69F0088E92B /* libtest1_mac.a */, + 4DF988532529A8770088E92B /* libtest1.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 4DF988352529A7DD0088E92B /* XcodeIntegration */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4DF9884A2529A7DE0088E92B /* Build configuration list for PBXNativeTarget "XcodeIntegration" */; + buildPhases = ( + 4DF988322529A7DD0088E92B /* Sources */, + 4DF988332529A7DD0088E92B /* Frameworks */, + 4DF988342529A7DD0088E92B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = XcodeIntegration; + productName = XcodeIntegration; + productReference = 4DF988362529A7DD0088E92B /* XcodeIntegration.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4DF9882E2529A7DD0088E92B /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1220; + LastUpgradeCheck = 1220; + TargetAttributes = { + 4DF988352529A7DD0088E92B = { + CreatedOnToolsVersion = 12.2; + }; + }; + }; + buildConfigurationList = 4DF988312529A7DD0088E92B /* Build configuration list for PBXProject "XcodeIntegration" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 4DF9882D2529A7DD0088E92B; + productRefGroup = 4DF988372529A7DD0088E92B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4DF988352529A7DD0088E92B /* XcodeIntegration */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 4DF988342529A7DD0088E92B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF988462529A7DE0088E92B /* LaunchScreen.storyboard in Resources */, + 4DF988432529A7DE0088E92B /* Preview Assets.xcassets in Resources */, + 4DF988502529A8150088E92B /* Rust in Resources */, + 4DF988402529A7DE0088E92B /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 4DF988322529A7DD0088E92B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF9883A2529A7DD0088E92B /* AppDelegate.swift in Sources */, + 4DF9883C2529A7DD0088E92B /* SceneDelegate.swift in Sources */, + 4DF9883E2529A7DD0088E92B /* ContentView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 4DF988442529A7DE0088E92B /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 4DF988452529A7DE0088E92B /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 4DF988482529A7DE0088E92B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 4DF988492529A7DE0088E92B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 14.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 4DF9884B2529A7DE0088E92B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = XcodeIntegration/XcodeIntegration.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"XcodeIntegration/Preview Content\""; + DEVELOPMENT_TEAM = 76VT9VZ6GK; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = XcodeIntegration/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/XcodeIntegration/Rust", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.stylemac.XcodeIntegration; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/XcodeIntegration/XcodeIntegration.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 4DF9884C2529A7DE0088E92B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = XcodeIntegration/XcodeIntegration.entitlements; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_ASSET_PATHS = "\"XcodeIntegration/Preview Content\""; + DEVELOPMENT_TEAM = 76VT9VZ6GK; + ENABLE_PREVIEWS = YES; + INFOPLIST_FILE = XcodeIntegration/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 14.2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/XcodeIntegration/Rust", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.stylemac.XcodeIntegration; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTS_MACCATALYST = YES; + SWIFT_OBJC_BRIDGING_HEADER = "$(PROJECT_DIR)/XcodeIntegration/XcodeIntegration.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4DF988312529A7DD0088E92B /* Build configuration list for PBXProject "XcodeIntegration" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4DF988482529A7DE0088E92B /* Debug */, + 4DF988492529A7DE0088E92B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4DF9884A2529A7DE0088E92B /* Build configuration list for PBXNativeTarget "XcodeIntegration" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4DF9884B2529A7DE0088E92B /* Debug */, + 4DF9884C2529A7DE0088E92B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4DF9882E2529A7DD0088E92B /* Project object */; +} diff --git a/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/xcuserdata/terhechte.xcuserdatad/UserInterfaceState.xcuserstate b/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/xcuserdata/terhechte.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..09f478e Binary files /dev/null and b/XcodeIntegration/XcodeIntegration.xcodeproj/project.xcworkspace/xcuserdata/terhechte.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/XcodeIntegration/XcodeIntegration.xcodeproj/xcuserdata/terhechte.xcuserdatad/xcschemes/xcschememanagement.plist b/XcodeIntegration/XcodeIntegration.xcodeproj/xcuserdata/terhechte.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..0e2b457 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration.xcodeproj/xcuserdata/terhechte.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + XcodeIntegration.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/XcodeIntegration/XcodeIntegration/.DS_Store b/XcodeIntegration/XcodeIntegration/.DS_Store new file mode 100644 index 0000000..0bf1a6a Binary files /dev/null and b/XcodeIntegration/XcodeIntegration/.DS_Store differ diff --git a/XcodeIntegration/XcodeIntegration/AppDelegate.swift b/XcodeIntegration/XcodeIntegration/AppDelegate.swift new file mode 100644 index 0000000..788e718 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/AppDelegate.swift @@ -0,0 +1,40 @@ +// +// AppDelegate.swift +// XcodeIntegration +// +// Created by terhechte on 04.10.20. +// + +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + // call into rust + let payload = "Hello from Swift" + example(payload, UInt(payload.lengthOfBytes(using: .utf8))) + + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/XcodeIntegration/XcodeIntegration/Assets.xcassets/AccentColor.colorset/Contents.json b/XcodeIntegration/XcodeIntegration/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/XcodeIntegration/XcodeIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json b/XcodeIntegration/XcodeIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..9221b9b --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/XcodeIntegration/XcodeIntegration/Assets.xcassets/Contents.json b/XcodeIntegration/XcodeIntegration/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/XcodeIntegration/XcodeIntegration/Base.lproj/LaunchScreen.storyboard b/XcodeIntegration/XcodeIntegration/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/XcodeIntegration/XcodeIntegration/ContentView.swift b/XcodeIntegration/XcodeIntegration/ContentView.swift new file mode 100644 index 0000000..4f9d004 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/ContentView.swift @@ -0,0 +1,21 @@ +// +// ContentView.swift +// XcodeIntegration +// +// Created by terhechte on 04.10.20. +// + +import SwiftUI + +struct ContentView: View { + var body: some View { + Text("Hello, world!") + .padding() + } +} + +struct ContentView_Previews: PreviewProvider { + static var previews: some View { + ContentView() + } +} diff --git a/XcodeIntegration/XcodeIntegration/Info.plist b/XcodeIntegration/XcodeIntegration/Info.plist new file mode 100644 index 0000000..2688b32 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Info.plist @@ -0,0 +1,62 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + + + + + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/XcodeIntegration/XcodeIntegration/Preview Content/Preview Assets.xcassets/Contents.json b/XcodeIntegration/XcodeIntegration/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/XcodeIntegration/XcodeIntegration/Rust/libtest1_ios.a b/XcodeIntegration/XcodeIntegration/Rust/libtest1_ios.a new file mode 100644 index 0000000..45477c6 Binary files /dev/null and b/XcodeIntegration/XcodeIntegration/Rust/libtest1_ios.a differ diff --git a/XcodeIntegration/XcodeIntegration/Rust/libtest1_mac.a b/XcodeIntegration/XcodeIntegration/Rust/libtest1_mac.a new file mode 100644 index 0000000..dcad7c7 Binary files /dev/null and b/XcodeIntegration/XcodeIntegration/Rust/libtest1_mac.a differ diff --git a/XcodeIntegration/XcodeIntegration/Rust/test1_rust.h b/XcodeIntegration/XcodeIntegration/Rust/test1_rust.h new file mode 100644 index 0000000..56fede6 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/Rust/test1_rust.h @@ -0,0 +1,6 @@ +#include +#include +#include +#include + +void example(const void *swift_string, uintptr_t len); diff --git a/XcodeIntegration/XcodeIntegration/SceneDelegate.swift b/XcodeIntegration/XcodeIntegration/SceneDelegate.swift new file mode 100644 index 0000000..122b583 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/SceneDelegate.swift @@ -0,0 +1,63 @@ +// +// SceneDelegate.swift +// XcodeIntegration +// +// Created by terhechte on 04.10.20. +// + +import UIKit +import SwiftUI + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + + // Create the SwiftUI view that provides the window contents. + let contentView = ContentView() + + // Use a UIHostingController as window root view controller. + if let windowScene = scene as? UIWindowScene { + let window = UIWindow(windowScene: windowScene) + window.rootViewController = UIHostingController(rootView: contentView) + self.window = window + window.makeKeyAndVisible() + } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/XcodeIntegration/XcodeIntegration/XcodeIntegration.entitlements b/XcodeIntegration/XcodeIntegration/XcodeIntegration.entitlements new file mode 100644 index 0000000..ee95ab7 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/XcodeIntegration.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/XcodeIntegration/XcodeIntegration/XcodeIntegration.h b/XcodeIntegration/XcodeIntegration/XcodeIntegration.h new file mode 100644 index 0000000..5d41129 --- /dev/null +++ b/XcodeIntegration/XcodeIntegration/XcodeIntegration.h @@ -0,0 +1,13 @@ +// +// XcodeIntegration.h +// XcodeIntegration +// +// Created by terhechte on 04.10.20. +// + +#ifndef XcodeIntegration_h +#define XcodeIntegration_h + +#import "Rust/test1_rust.h" + +#endif /* XcodeIntegration_h */ diff --git a/build.rs b/build.rs index db247e2..baec349 100644 --- a/build.rs +++ b/build.rs @@ -4,7 +4,7 @@ use std::env; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - let filename = "test1_rust.h"; + let filename = "XcodeIntegration/XcodeIntegration/Rust/test1_rust.h"; let _build = cbindgen::Builder::new() .with_crate(crate_dir) diff --git a/make_fat.sh b/make_fat.sh index 9a9da1e..daaeaca 100755 --- a/make_fat.sh +++ b/make_fat.sh @@ -3,9 +3,42 @@ # We need the SDK Root export SDKROOT=`xcrun --sdk macosx --show-sdk-path` -# lipo together the different architectures into a universal 'fat' file +# We will build two different frameworks: +# The first one contains X86_64 iOS (Simulator) and ARM iOS +# The other contains Catalyst ARM and Catalyst X86_64 +# Then we tell Xcode to only use the first one for iOS builds, +# and the second one for macOS builds. +# The reason is that fat binaries can't contain the same architecture +# slice twice (i.e. ARM64 iOS and ARM64 Catalyst) + +# Simulator: +echo "Building for iOS X86_64 (Simulator)..." +cargo build -Z build-std --target x86_64-apple-ios --release > /dev/null 2>&1 + +# X86 Catalyst # use `cargo build-std` to automatically build the std for non-tier1 platforms -# such as catalyst -cargo +nightly build -Z build-std --target x86_64-apple-ios-macabi --release -cargo build --target aarch64-apple-ios --release -lipo -create -output target/libtest1.a target/{aarch64-apple-ios,x86_64-apple-ios-macabi}/release/libtest1.a +echo "Building for Mac Catalyst X86_64..." +cargo +nightly build -Z build-std --target x86_64-apple-ios-macabi --release > /dev/null 2>&1 + +# ARM64 Catalyst +echo "Building for Mac Catalyst ARM64..." +cargo +myrust build -Z build-std --target aarch64-apple-ios-macabi --release > /dev/null 2>&1 + +# iOS +echo "Building for ARM iOS..." +cargo build -Z build-std --target aarch64-apple-ios --release > /dev/null 2>&1 + + +# Build Fat Libraries: +# lipo together the different architectures into a universal 'fat' file + +# macOS +echo "Building Fat Libaries" +lipo -create -output XcodeIntegration/XcodeIntegration/Rust/libtest1_mac.a target/{aarch64-apple-ios-macabi,x86_64-apple-ios-macabi}/release/libtest1.a + +echo "Wrote XcodeIntegration/XcodeIntegration/Rust/libtest1_ios.a" + +# iOS +lipo -create -output XcodeIntegration/XcodeIntegration/Rust/libtest1_ios.a target/{aarch64-apple-ios,x86_64-apple-ios}/release/libtest1.a + +echo "Wrote XcodeIntegration/XcodeIntegration/Rust/libtest1_mac.a" diff --git a/src/lib.rs b/src/lib.rs index 7cb80e4..5af3874 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,30 +1,14 @@ -use std::collections::HashMap; -use libc::c_char; +use std::os::raw::c_void; +use std::slice; +use std::str; -/// Free a markdown slide buffer. #[no_mangle] -pub unsafe extern "C" fn example(buffer: *mut c_char) { - println!("Yeah"); +pub unsafe extern "C" fn example( + swift_string: *const c_void, + len: usize + ) { + let bytes: &[u8] = slice::from_raw_parts(swift_string as *mut u8 as _, len); + let string = str::from_utf8_unchecked(&bytes); + println!("String: {}", &string); } -pub fn makeit() { - // Type inference lets us omit an explicit type signature (which - // would be `HashMap` in this example). - let mut book_reviews = HashMap::new(); - - // Review some books. - book_reviews.insert( - "Adventures of Huckleberry Finn".to_string(), - "My favorite book.".to_string(), - ); - - println!("{:?}", &book_reviews); -} - -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - assert_eq!(2 + 2, 4); - } -}