| #!/bin/bash |
| # |
| # Copyright 2016 The Bazel Authors. All rights reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # |
| # Tests the examples provided in Bazel |
| # |
| |
| # Load the test setup defined in the parent directory |
| CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| source "${CURRENT_DIR}/../../integration_test_setup.sh" \ |
| || { echo "integration_test_setup.sh not found!" >&2; exit 1; } |
| |
| if [ "${PLATFORM}" != "darwin" ]; then |
| echo "This test suite requires running on OS X" >&2 |
| exit 0 |
| fi |
| |
| function set_up() { |
| copy_examples |
| setup_objc_test_support |
| |
| # Find the version number for an installed 7-series or 8-series Xcode |
| # (any sub-version will do) |
| bazel query "labels('versions', '@local_config_xcode//:host_xcodes')" \ |
| --output xml | grep 'name="version"' \ |
| | sed -E 's/.*(value=\"(([0-9]|.)+))\".*/\2/' > xcode_versions |
| |
| XCODE_VERSION=$(cat xcode_versions | grep -m1 '7\|8') |
| |
| # Allow access to //external:xcrunwrapper. |
| rm WORKSPACE |
| ln -sv ${workspace_file} WORKSPACE |
| } |
| |
| function make_app() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/app.swift <<EOF |
| import UIKit |
| |
| @UIApplicationMain |
| class AppDelegate: UIResponder, UIApplicationDelegate { |
| var window: UIWindow? |
| func application( |
| application: UIApplication, |
| didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) |
| -> Bool { |
| NSLog("Hello, world") |
| return true |
| } |
| } |
| EOF |
| |
| cat >ios/App-Info.plist <<EOF |
| <plist version="1.0"> |
| <dict> |
| <key>CFBundleExecutable</key> |
| <string>app</string> |
| <key>CFBundleName</key> |
| <string>app</string> |
| <key>CFBundleDisplayName</key> |
| <string>app</string> |
| <key>CFBundlePackageType</key> |
| <string>APPL</string> |
| <key>CFBundleIdentifier</key> |
| <string>com.google.app</string> |
| <key>CFBundleSignature</key> |
| <string>????</string> |
| <key>CFBundleVersion</key> |
| <string>1.0</string> |
| <key>LSRequiresIPhoneOS</key> |
| <true/> |
| </dict> |
| </plist> |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "SwiftMain", |
| srcs = ["app.swift"]) |
| |
| objc_binary(name = "bin", |
| srcs = ["//tools/objc:dummy.c"], |
| deps = [":SwiftMain"]) |
| |
| ios_application(name = "app", |
| binary = ':bin', |
| infoplist = 'App-Info.plist') |
| EOF |
| } |
| |
| function test_swift_library() { |
| local swift_lib_pkg=examples/swift |
| assert_build_output ./bazel-genfiles/${swift_lib_pkg}/swift_lib/_objs/examples_swift_swift_lib.a \ |
| ${swift_lib_pkg}:swift_lib --xcode_version=$XCODE_VERSION |
| assert_build_output ./bazel-genfiles/${swift_lib_pkg}/swift_lib/_objs/examples_swift_swift_lib.swiftmodule \ |
| ${swift_lib_pkg}:swift_lib --xcode_version=$XCODE_VERSION |
| } |
| |
| function test_build_app() { |
| make_app |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:app >$TEST_log 2>&1 || fail "should pass" |
| ls bazel-bin/ios/app.ipa || fail "should generate app.ipa" |
| } |
| |
| function test_objc_depends_on_swift() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/main.swift <<EOF |
| import Foundation |
| |
| @objc public class Foo: NSObject { |
| public func bar() -> Int { return 42; } |
| } |
| EOF |
| |
| cat >ios/app.m <<EOF |
| #import <UIKit/UIKit.h> |
| #import "ios/SwiftMain-Swift.h" |
| |
| int main(int argc, char *argv[]) { |
| @autoreleasepool { |
| NSLog(@"%d", [[[Foo alloc] init] bar]); |
| return UIApplicationMain(argc, argv, nil, nil); |
| } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "SwiftMain", |
| srcs = ["main.swift"]) |
| |
| objc_binary(name = "bin", |
| srcs = ['app.m',], |
| deps = [":SwiftMain"]) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:bin >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_swift_imports_objc() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/main.swift <<EOF |
| import Foundation |
| import ios_ObjcLib |
| |
| public class SwiftClass { |
| public func bar() -> String { |
| return ObjcClass().foo() |
| } |
| } |
| EOF |
| |
| cat >ios/ObjcClass.h <<EOF |
| #import <Foundation/Foundation.h> |
| |
| #if !DEFINE_FOO |
| #error "Define is not passed in" |
| #endif |
| |
| #if !COPTS_FOO |
| #error "Copt is not passed in |
| #endif |
| |
| @interface ObjcClass : NSObject |
| - (NSString *)foo; |
| @end |
| EOF |
| |
| cat >ios/ObjcClass.m <<EOF |
| #import "ObjcClass.h" |
| @implementation ObjcClass |
| - (NSString *)foo { return @"Hello ObjcClass"; } |
| @end |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"], |
| deps = [":ObjcLib"]) |
| |
| objc_library(name = "ObjcLib", |
| hdrs = ['ObjcClass.h'], |
| srcs = ['ObjcClass.m'], |
| defines = ["DEFINE_FOO=1"]) |
| EOF |
| |
| bazel build --verbose_failures --objccopt=-DCOPTS_FOO=1 -s \ |
| --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| expect_log "-module-cache-path bazel-out/local-fastbuild/genfiles/_objc_module_cache" |
| } |
| |
| function test_swift_import_objc_framework() { |
| rm -rf ios |
| mkdir -p ios |
| |
| # Copy the prebuilt framework into app's directory. |
| cp -RL "${BAZEL_RUNFILES}/tools/build_defs/apple/test/testdata/BlazeFramework.framework" ios |
| |
| cat >ios/app.swift <<EOF |
| import UIKit |
| |
| import BlazeFramework |
| |
| @UIApplicationMain |
| class AppDelegate: UIResponder, UIApplicationDelegate { |
| var window: UIWindow? |
| func application( |
| application: UIApplication, |
| didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) |
| -> Bool { |
| NSLog("\(Multiplier().foo())") |
| return true |
| } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| objc_binary(name = "bin", |
| srcs = ["//tools/objc:dummy.c"], |
| deps = [":swift_lib"]) |
| |
| swift_library(name = "swift_lib", |
| srcs = ["app.swift"], |
| deps = [":dylib"]) |
| |
| objc_framework(name = "dylib", |
| framework_imports = glob(["BlazeFramework.framework/**"]), |
| is_dynamic = 1) |
| EOF |
| |
| bazel build --verbose_failures --ios_minimum_os=8.0 \ |
| --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_fat_apple_binary() { |
| rm -rf package |
| mkdir -p package |
| cat > package/BUILD <<EOF |
| objc_library( |
| name = "lib_a", |
| srcs = ["a.m"], |
| ) |
| objc_library( |
| name = "lib_b", |
| srcs = ["b.m"], |
| ) |
| apple_binary( |
| name = "main_binary", |
| deps = [":lib_a", ":lib_b"], |
| srcs = ["main.m"], |
| ) |
| genrule( |
| name = "lipo_run", |
| srcs = [":main_binary_lipobin"], |
| outs = ["lipo_out"], |
| cmd = |
| "set -e && " + |
| "lipo -info \$(location :main_binary_lipobin) > \$(@)", |
| tags = ["requires-darwin"], |
| ) |
| EOF |
| touch package/a.m |
| touch package/b.m |
| cat > package/main.m <<EOF |
| int main() { |
| return 0; |
| } |
| EOF |
| |
| bazel build --verbose_failures //package:lipo_out \ |
| --ios_multi_cpus=i386,x86_64 \ |
| --xcode_version=$XCODE_VERSION \ |
| || fail "should build apple_binary and obtain info via lipo" |
| |
| cat bazel-genfiles/package/lipo_out | grep "i386 x86_64" \ |
| || fail "expected output binary to contain 2 architectures" |
| } |
| |
| function test_swift_imports_swift() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/main.swift <<EOF |
| import Foundation |
| import ios_util |
| |
| public class SwiftClass { |
| public func bar() -> String { |
| return Utility().foo() |
| } |
| } |
| EOF |
| |
| cat >ios/Utility.swift <<EOF |
| public class Utility { |
| public init() {} |
| public func foo() -> String { return "foo" } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"], |
| deps = [":util"]) |
| |
| swift_library(name = "util", |
| srcs = ['Utility.swift']) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_swift_tests() { |
| make_app |
| |
| cat >ios/internal.swift <<EOF |
| internal class InternalClass { |
| func foo() -> String { return "bar" } |
| } |
| EOF |
| |
| cat >ios/tests.swift <<EOF |
| import XCTest |
| @testable import ios_SwiftMain |
| |
| class FooTest: XCTestCase { |
| func testFoo() { XCTAssertEqual(2, 3) } |
| func testInternalClass() { XCTAssertEqual(InternalClass().foo(), "bar") } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "SwiftMain", |
| srcs = ["app.swift", "internal.swift"]) |
| |
| objc_binary(name = "bin", |
| srcs = ["//tools/objc:dummy.c"], |
| deps = [":SwiftMain"]) |
| |
| ios_application(name = "app", |
| binary = ':bin', |
| infoplist = 'App-Info.plist') |
| |
| swift_library(name = "SwiftTest", |
| srcs = ["tests.swift"], |
| deps = [":SwiftMain"]) |
| |
| ios_test(name = "app_test", |
| srcs = ["//tools/objc:dummy.c"], |
| deps = [":SwiftTest"], |
| xctest_app = "app") |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:app_test >$TEST_log 2>&1 || fail "should build" |
| |
| otool -lv bazel-bin/ios/app_test_bin \ |
| | grep @executable_path/Frameworks -sq \ |
| || fail "expected test binary to contain @executable_path in LC_RPATH" |
| |
| otool -lv bazel-bin/ios/app_test_bin \ |
| | grep @loader_path/Frameworks -sq \ |
| || fail "expected test binary to contain @loader_path in LC_RPATH" |
| |
| } |
| |
| function test_swift_compilation_mode_flags() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/debug.swift <<EOF |
| // A trick to break compilation when DEBUG is not set. |
| func foo() { |
| #if DEBUG |
| var x: Int |
| #endif |
| x = 3 |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "swift_lib", |
| srcs = ["debug.swift"]) |
| EOF |
| |
| ! bazel build --verbose_failures -c opt \ |
| --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should not build" |
| expect_log "error: use of unresolved identifier 'x'" |
| |
| bazel build --verbose_failures -c dbg \ |
| --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_fat_binary_no_srcs() { |
| mkdir -p package |
| cat > package/BUILD <<EOF |
| objc_library( |
| name = "lib_a", |
| srcs = ["a.m"], |
| ) |
| objc_library( |
| name = "lib_b", |
| srcs = ["b.m"], |
| ) |
| apple_binary( |
| name = "main_binary", |
| deps = [":lib_a", ":lib_b"], |
| ) |
| genrule( |
| name = "lipo_run", |
| srcs = [":main_binary_lipobin"], |
| outs = ["lipo_out"], |
| cmd = |
| "set -e && " + |
| "lipo -info \$(location :main_binary_lipobin) > \$(@)", |
| tags = ["requires-darwin"], |
| ) |
| EOF |
| touch package/a.m |
| cat > package/b.m <<EOF |
| int main() { |
| return 0; |
| } |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //package:lipo_out --ios_multi_cpus=i386,x86_64 \ |
| || fail "should build apple_binary and obtain info via lipo" |
| |
| cat bazel-genfiles/package/lipo_out | grep "i386 x86_64" \ |
| || fail "expected output binary to contain 2 architectures" |
| } |
| |
| function test_swift_defines() { |
| rm -rf ios |
| mkdir -p ios |
| touch ios/dummy.swift |
| |
| cat >ios/main.swift <<EOF |
| import Foundation |
| |
| public class SwiftClass { |
| public func bar() { |
| #if !FLAG |
| let x: String = 1 // Invalid statement, should throw compiler error when FLAG is not set |
| #endif |
| |
| #if !DEP_FLAG |
| let x: String = 2 // Invalid statement, should throw compiler error when DEP_FLAG is not set |
| #endif |
| } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "dep_lib", |
| srcs = ["dummy.swift"], |
| defines = ["DEP_FLAG"]) |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"], |
| defines = ["FLAG"], |
| deps = [":dep_lib"]) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_apple_watch_with_swift() { |
| make_app |
| |
| cat >ios/watchapp.swift <<EOF |
| import WatchKit |
| class ExtensionDelegate: NSObject, WKExtensionDelegate { |
| func applicationDidFinishLaunching() {} |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "WatchModule", |
| srcs = ["watchapp.swift"]) |
| |
| apple_binary(name = "bin", |
| deps = [":WatchModule"], |
| platform_type = "watchos") |
| |
| apple_watch2_extension( |
| name = "WatchExtension", |
| app_bundle_id = "com.google.app.watchkit", |
| app_name = "WatchApp", |
| binary = ":bin", |
| ext_bundle_id = "com.google.app.extension", |
| ) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:WatchExtension >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_host_xcodes() { |
| XCODE_VERSION=$(xcodebuild -version | grep "Xcode" \ |
| | sed -E "s/Xcode (([0-9]|.)+).*/\1/") |
| IOS_SDK=$(xcodebuild -version -sdk | grep iphoneos \ |
| | sed -E "s/.*\(iphoneos(([0-9]|.)+)\).*/\1/") |
| MACOSX_SDK=$(xcodebuild -version -sdk | grep macosx \ |
| | sed -E "s/.*\(macosx(([0-9]|.)+)\).*/\1/" | head -n 1) |
| |
| # Unfortunately xcodebuild -version doesn't always pad with trailing .0, so, |
| # for example, may produce "6.4", which is bad for this test. |
| if [[ ! $XCODE_VERSION =~ [0-9].[0-9].[0-9] ]] |
| then |
| XCODE_VERSION="${XCODE_VERSION}.0" |
| fi |
| |
| bazel build @local_config_xcode//:host_xcodes >"${TEST_log}" 2>&1 \ |
| || fail "Expected host_xcodes to build" |
| |
| bazel query "attr(version, $XCODE_VERSION, \ |
| attr(default_ios_sdk_version, $IOS_SDK, \ |
| attr(default_macosx_sdk_version, $MACOSX_SDK, \ |
| labels('versions', '@local_config_xcode//:host_xcodes'))))" \ |
| > xcode_version_target |
| |
| assert_contains "local_config_xcode" xcode_version_target |
| |
| DEFAULT_LABEL=$(bazel query \ |
| "labels('default', '@local_config_xcode//:host_xcodes')") |
| |
| assert_equals $DEFAULT_LABEL $(cat xcode_version_target) |
| } |
| |
| function test_no_object_file_collisions() { |
| rm -rf ios |
| mkdir -p ios |
| |
| touch ios/foo.swift |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "Foo", |
| srcs = ["foo.swift"]) |
| swift_library(name = "Bar", |
| srcs = ["foo.swift"]) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:{Foo,Bar} >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| function test_minimum_os() { |
| rm -rf ios |
| mkdir -p ios |
| |
| touch ios/foo.swift |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "foo", |
| srcs = ["foo.swift"]) |
| EOF |
| |
| bazel build --verbose_failures -s --announce_rc \ |
| --xcode_version=$XCODE_VERSION --ios_minimum_os=9.0 \ |
| //ios:foo >$TEST_log 2>&1 || fail "should build" |
| |
| # Get the min OS version encoded as "version" argument of |
| # LC_VERSION_MIN_IPHONEOS load command in Mach-O |
| MIN_OS=$(otool -l bazel-genfiles/ios/foo/_objs/ios_foo.a | \ |
| grep -A 3 LC_VERSION_MIN_IPHONEOS | grep version | cut -d " " -f4) |
| assert_equals $MIN_OS "9.0" |
| } |
| |
| function test_swift_copts() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/main.swift <<EOF |
| import Foundation |
| |
| public class SwiftClass { |
| public func bar() { |
| #if !FLAG |
| let x: String = 1 // Invalid statement, should throw compiler error when FLAG is not set |
| #endif |
| } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"], |
| copts = ["-DFLAG"]) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| test_swift_bitcode() { |
| rm -rf ios |
| mkdir -p ios |
| |
| cat >ios/main.swift <<EOF |
| func f() {} |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"]) |
| EOF |
| |
| ARCHIVE=bazel-genfiles/ios/swift_lib/_objs/ios_swift_lib.a |
| |
| # No bitcode |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| ! otool -l $ARCHIVE | grep __bitcode -sq \ |
| || fail "expected a.o to contain bitcode" |
| |
| # Bitcode marker |
| bazel build --verbose_failures \ |
| --xcode_version=$XCODE_VERSION --apple_bitcode=embedded_markers \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| # Bitcode marker has a length of 1. |
| assert_equals $(size -m $ARCHIVE | grep __bitcode | cut -d: -f2 | tr -d ' ') "1" |
| |
| # Full bitcode |
| bazel build --verbose_failures \ |
| --xcode_version=$XCODE_VERSION --apple_bitcode=embedded \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should build" |
| otool -l $ARCHIVE | grep __bitcode -sq \ |
| || fail "expected a.o to contain bitcode" |
| } |
| |
| function test_swift_name_validation() { |
| rm -rf ios |
| mkdir -p ios |
| |
| touch ios/main.swift |
| touch ios/main.m |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "swift-lib", |
| srcs = ["main.swift"]) |
| EOF |
| |
| ! bazel build --verbose_failures \ |
| --xcode_version=$XCODE_VERSION \ |
| //ios:swift-lib >$TEST_log 2>&1 || fail "should fail" |
| expect_log "Error in target '//ios:swift-lib'" |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| objc_library(name = "bad-dep", srcs = ["main.m"]) |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"], deps=[":bad-dep"]) |
| EOF |
| |
| ! bazel build --verbose_failures \ |
| --xcode_version=$XCODE_VERSION \ |
| //ios:swift_lib >$TEST_log 2>&1 || fail "should fail" |
| expect_log "Error in target '//ios:bad-dep'" |
| } |
| |
| function test_swift_ast_is_recorded() { |
| rm -rf ios |
| mkdir -p ios |
| |
| touch ios/main.swift |
| cat >ios/dep.swift <<EOF |
| import UIKit |
| // Add dummy code so that Swift symbols are exported into final binary, which |
| // will cause runtime libraries to be packaged into the IPA |
| class X: UIViewController {} |
| EOF |
| |
| cat >ios/main.m <<EOF |
| #import <UIKit/UIKit.h> |
| |
| int main(int argc, char *argv[]) { |
| @autoreleasepool { |
| return UIApplicationMain(argc, argv, nil, nil); |
| } |
| } |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "dep", |
| srcs = ["dep.swift"]) |
| |
| swift_library(name = "swift_lib", |
| srcs = ["main.swift"], |
| deps = [":dep"]) |
| objc_binary(name = "bin", |
| srcs = ["main.m"], |
| deps = [":swift_lib"]) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION -s \ |
| //ios:bin >$TEST_log 2>&1 || fail "should build" |
| expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/local-fastbuild/genfiles/ios/dep/_objs/ios_dep.swiftmodule" |
| expect_log "-Xlinker -add_ast_path -Xlinker bazel-out/local-fastbuild/genfiles/ios/swift_lib/_objs/ios_swift_lib.swiftmodule" |
| } |
| |
| function test_swiftc_script_mode() { |
| rm -rf ios |
| mkdir -p ios |
| touch ios/foo.swift |
| |
| cat >ios/top.swift <<EOF |
| print() // Top level expression outside of main.swift, should fail. |
| EOF |
| |
| cat >ios/main.swift <<EOF |
| import UIKit |
| |
| class AppDelegate: UIResponder, UIApplicationDelegate {} |
| |
| #if swift(>=3) |
| UIApplicationMain( |
| CommandLine.argc, |
| UnsafeMutableRawPointer(CommandLine.unsafeArgv) |
| .bindMemory( |
| to: UnsafeMutablePointer<Int8>.self, |
| capacity: Int(CommandLine.argc)), |
| nil, |
| NSStringFromClass(AppDelegate.self) |
| ) |
| #else |
| UIApplicationMain( |
| Process.argc, UnsafeMutablePointer<UnsafeMutablePointer<CChar>>(Process.unsafeArgv), |
| nil, NSStringFromClass(AppDelegate) |
| ) |
| #endif |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| swift_library(name = "main_should_compile_as_script", |
| srcs = ["main.swift", "foo.swift"]) |
| swift_library(name = "top_should_not_compile_as_script", |
| srcs = ["top.swift"]) |
| swift_library(name = "single_source_should_compile_as_library", |
| srcs = ["foo.swift"]) |
| EOF |
| |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:single_source_should_compile_as_library \ |
| //ios:main_should_compile_as_script >$TEST_log 2>&1 || fail "should build" |
| |
| ! bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:top_should_not_compile_as_script >$TEST_log 2>&1 || fail "should not build" |
| expect_log "ios/top.swift:1:1: error: expressions are not allowed at the top level" |
| } |
| |
| # Test that it's possible to import Clang module of a target that contains private headers. |
| function test_import_module_with_private_hdrs() { |
| rm -rf ios |
| mkdir -p ios |
| touch ios/Foo.h ios/Foo_Private.h |
| |
| cat >ios/main.swift <<EOF |
| import ios_lib |
| EOF |
| |
| cat >ios/BUILD <<EOF |
| load("//tools/build_defs/apple:swift.bzl", "swift_library") |
| |
| objc_library(name = "lib", |
| srcs = ["Foo_Private.h"], |
| hdrs = ["Foo.h"]) |
| |
| swift_library(name = "swiftmodule", |
| srcs = ["main.swift"], |
| deps = [":lib"]) |
| EOF |
| bazel build --verbose_failures --xcode_version=$XCODE_VERSION \ |
| //ios:swiftmodule >$TEST_log 2>&1 || fail "should build" |
| } |
| |
| run_suite "apple_tests" |