From 3ecb2c54451da5f02fab8cc6facfdf6e43016736 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Thu, 8 Sep 2022 14:46:44 -0700 Subject: [PATCH] Add iOS examples --- .bazelci/presubmit.yml | 6 ++ examples/.bazelignore | 1 + examples/WORKSPACE.bazel | 4 ++ examples/ios/.gitignore | 1 + examples/ios/BUILD.bazel | 91 +++++++++++++++++++++++++++++++ examples/ios/Info.plist | 38 +++++++++++++ examples/ios/WORKSPACE.bazel | 50 +++++++++++++++++ examples/ios/allocator_library.cc | 52 ++++++++++++++++++ examples/ios/demo.rs | 9 +++ examples/ios/main_lib.m | 11 ++++ examples/ios/platform_mappings | 20 +++++++ 11 files changed, 283 insertions(+) create mode 100644 examples/ios/.gitignore create mode 100644 examples/ios/BUILD.bazel create mode 100644 examples/ios/Info.plist create mode 100644 examples/ios/WORKSPACE.bazel create mode 100644 examples/ios/allocator_library.cc create mode 100644 examples/ios/demo.rs create mode 100644 examples/ios/main_lib.m create mode 100644 examples/ios/platform_mappings diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index a15fc6994f..c56b788823 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -359,6 +359,12 @@ tasks: working_directory: examples/android build_targets: - "//:android_app" + ios_examples: + name: iOS Examples + platform: macos + working_directory: examples/ios + build_targets: + - "//..." buildifier: version: latest diff --git a/examples/.bazelignore b/examples/.bazelignore index 1ee0b3f956..61093694df 100644 --- a/examples/.bazelignore +++ b/examples/.bazelignore @@ -1,3 +1,4 @@ android cargo_manifest_dir/external_crate crate_universe +ios diff --git a/examples/WORKSPACE.bazel b/examples/WORKSPACE.bazel index afa56db7e0..c027e4ebeb 100644 --- a/examples/WORKSPACE.bazel +++ b/examples/WORKSPACE.bazel @@ -14,6 +14,10 @@ rules_rust_dependencies() rust_register_toolchains( edition = "2018", + extra_target_triples = [ + "aarch64-apple-ios-sim", + "x86_64-apple-ios", + ], ) load("@rules_rust//crate_universe:repositories.bzl", "crate_universe_dependencies") diff --git a/examples/ios/.gitignore b/examples/ios/.gitignore new file mode 100644 index 0000000000..a6ef824c1f --- /dev/null +++ b/examples/ios/.gitignore @@ -0,0 +1 @@ +/bazel-* diff --git a/examples/ios/BUILD.bazel b/examples/ios/BUILD.bazel new file mode 100644 index 0000000000..a3bcb70e32 --- /dev/null +++ b/examples/ios/BUILD.bazel @@ -0,0 +1,91 @@ +load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application") +load("@build_bazel_rules_apple//apple:macos.bzl", "macos_application") +load("@rules_rust//rust:defs.bzl", "rust_library") + +cc_library( + name = "allocator_library", + srcs = ["allocator_library.cc"], + tags = ["manual"], +) + +rust_library( + name = "rust_lib", + srcs = ["demo.rs"], + edition = "2018", + tags = ["manual"], + deps = [":allocator_library"], +) + +# This being required is a bug in objc_library, ideally 'main_lib' could depend directly on 'rust_lib' +cc_library( + name = "shim", + tags = ["manual"], + deps = [":rust_lib"], +) + +objc_library( + name = "main_lib", + srcs = ["main_lib.m"], + tags = ["manual"], + deps = [":shim"], +) + +ios_application( + name = "ios_app", + bundle_id = "com.example.iosapp", + families = ["iphone"], + infoplists = ["Info.plist"], + minimum_os_version = "13.0", + deps = [":main_lib"], +) + +macos_application( + name = "macos_app", + bundle_id = "com.example.macosapp", + infoplists = ["Info.plist"], + minimum_os_version = "10.15", + deps = [":main_lib"], +) + +platform( + name = "macos_x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:macos", + ], +) + +platform( + name = "macos_arm64", + constraint_values = [ + "@platforms//cpu:arm64", + "@platforms//os:macos", + ], +) + +platform( + name = "ios_x86_64", + constraint_values = [ + "@platforms//cpu:x86_64", + "@platforms//os:ios", + "@build_bazel_apple_support//constraints:simulator", + ], +) + +platform( + name = "ios_sim_arm64", + constraint_values = [ + "@platforms//cpu:arm64", + "@platforms//os:ios", + "@build_bazel_apple_support//constraints:simulator", + ], +) + +platform( + name = "ios_arm64", + constraint_values = [ + "@platforms//cpu:arm64", + "@platforms//os:ios", + "@build_bazel_apple_support//constraints:device", + ], +) diff --git a/examples/ios/Info.plist b/examples/ios/Info.plist new file mode 100644 index 0000000000..64f09f3754 --- /dev/null +++ b/examples/ios/Info.plist @@ -0,0 +1,38 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + ITSAppUsesNonExemptEncryption + + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + arm64 + + UIStatusBarHidden + + UIStatusBarStyle + UIStatusBarStyleDefault + + diff --git a/examples/ios/WORKSPACE.bazel b/examples/ios/WORKSPACE.bazel new file mode 100644 index 0000000000..6986aa77ea --- /dev/null +++ b/examples/ios/WORKSPACE.bazel @@ -0,0 +1,50 @@ +workspace(name = "ios_examples") + +# Users of `rules_rust` will commonly be unable to load it +# using a `local_repository`. Instead, to setup the rules, +# please see https://bazelbuild.github.io/rules_rust/#setup +local_repository( + name = "rules_rust", + path = "../..", +) + +load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains") + +rules_rust_dependencies() + +rust_register_toolchains( + edition = "2018", + extra_target_triples = [ + "aarch64-apple-ios-sim", + "x86_64-apple-ios", + ], +) + +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "build_bazel_rules_apple", + sha256 = "a5f00fd89eff67291f6cd3efdc8fad30f4727e6ebb90718f3f05bbf3c3dd5ed7", + url = "https://github.com/bazelbuild/rules_apple/releases/download/0.33.0/rules_apple.0.33.0.tar.gz", +) + +load( + "@build_bazel_rules_apple//apple:repositories.bzl", + "apple_rules_dependencies", +) + +apple_rules_dependencies() + +load( + "@build_bazel_rules_swift//swift:repositories.bzl", + "swift_rules_dependencies", +) + +swift_rules_dependencies() + +load( + "@build_bazel_apple_support//lib:repositories.bzl", + "apple_support_dependencies", +) + +apple_support_dependencies() diff --git a/examples/ios/allocator_library.cc b/examples/ios/allocator_library.cc new file mode 100644 index 0000000000..be82631b07 --- /dev/null +++ b/examples/ios/allocator_library.cc @@ -0,0 +1,52 @@ +#include + +// This file has some exciting magic to get Rust code linking in a cc_binary. +// The Rust compiler generates some similar symbol aliases when it links, so we +// have to do it manually. We mark all our symbols as weak so that linking this +// via Rust tooling to produce a binary with a Rust main works. +// +// It is intended to be used in rust_toolchain.allocator_library. +// +// https://github.com/rust-lang/rust/blob/master/library/alloc/src/alloc.rs +// and https://github.com/rust-lang/rust/blob/master/library/std/src/alloc.rs +// are the best source of docs I've found on these functions and variables. +// https://doc.rust-lang.org/std/alloc/index.html talks about how this is +// intended to be used. +// +// Also note +// https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html for +// the sizes of the various integer types. +// +// This file strongly assumes that the default allocator is used. It will +// not work with any other allocated switched in via `#[global_allocator]`. + +// New feature as of https://github.com/rust-lang/rust/pull/88098. +__attribute__((weak)) uint8_t __rust_alloc_error_handler_should_panic = 0; + +extern "C" uint8_t *__rdl_alloc(uintptr_t size, uintptr_t align); +extern "C" __attribute__((weak)) +uint8_t *__rust_alloc(uintptr_t size, uintptr_t align) { + return __rdl_alloc(size, align); +} +extern "C" void __rdl_dealloc(uint8_t *ptr, uintptr_t size, uintptr_t align); +extern "C" __attribute__((weak)) +void __rust_dealloc(uint8_t *ptr, uintptr_t size, uintptr_t align) { + __rdl_dealloc(ptr, size, align); +} +extern "C" uint8_t *__rdl_realloc(uint8_t *ptr, uintptr_t old_size, uintptr_t align, + uintptr_t new_size); +extern "C" __attribute__((weak)) +uint8_t *__rust_realloc(uint8_t *ptr, uintptr_t old_size, uintptr_t align, + uintptr_t new_size) { + return __rdl_realloc(ptr, old_size, align, new_size); +} +extern "C" uint8_t *__rdl_alloc_zeroed(uintptr_t size, uintptr_t align); +extern "C" __attribute__((weak)) +uint8_t *__rust_alloc_zeroed(uintptr_t size, uintptr_t align) { + return __rdl_alloc_zeroed(size, align); +} +extern "C" void __rdl_oom(uintptr_t size, uintptr_t align); +extern "C" __attribute__((weak)) +void __rust_alloc_error_handler(uintptr_t size, uintptr_t align) { + __rdl_oom(size, align); +} diff --git a/examples/ios/demo.rs b/examples/ios/demo.rs new file mode 100644 index 0000000000..37b75877e2 --- /dev/null +++ b/examples/ios/demo.rs @@ -0,0 +1,9 @@ +#[no_mangle] +pub extern fn print_something_from_rust() { + println!("Ferris says hello!"); +} + +#[no_mangle] +pub extern fn get_a_value_from_rust() -> i32 { + 42 +} diff --git a/examples/ios/main_lib.m b/examples/ios/main_lib.m new file mode 100644 index 0000000000..2d287cd775 --- /dev/null +++ b/examples/ios/main_lib.m @@ -0,0 +1,11 @@ +#include + +// Instead of doing this manually https://github.com/dtolnay/cxx could be used for complex examples +extern int32_t get_a_value_from_rust(void); +extern void print_something_from_rust(void); + +int main() { + print_something_from_rust(); + printf("Some value from rust: %d\n", get_a_value_from_rust()); + return 0; +} diff --git a/examples/ios/platform_mappings b/examples/ios/platform_mappings new file mode 100644 index 0000000000..77555f3251 --- /dev/null +++ b/examples/ios/platform_mappings @@ -0,0 +1,20 @@ +flags: + --cpu=darwin_x86_64 + --apple_platform_type=macos + //:macos_x86_64 + + --cpu=darwin_arm64 + --apple_platform_type=macos + //:macos_arm64 + + --cpu=ios_x86_64 + --apple_platform_type=ios + //:ios_x86_64 + + --cpu=ios_sim_arm64 + --apple_platform_type=ios + //:ios_sim_arm64 + + --cpu=ios_arm64 + --apple_platform_type=ios + //:ios_arm64