diff options
-rwxr-xr-x | src/test/shell/bazel/apple/bazel_apple_test.sh | 56 | ||||
-rw-r--r-- | tools/build_defs/apple/swift.bzl | 21 |
2 files changed, 73 insertions, 4 deletions
diff --git a/src/test/shell/bazel/apple/bazel_apple_test.sh b/src/test/shell/bazel/apple/bazel_apple_test.sh index 667e98e174..1f8f9ea485 100755 --- a/src/test/shell/bazel/apple/bazel_apple_test.sh +++ b/src/test/shell/bazel/apple/bazel_apple_test.sh @@ -222,7 +222,7 @@ function test_swift_import_objc_framework() { # Copy the prebuilt framework into app's directory. cp -RL "${BAZEL_RUNFILES}/tools/build_defs/apple/test/testdata/BlazeFramework.framework" ios - cat >ios/main.swift <<EOF + cat >ios/app.swift <<EOF import UIKit import BlazeFramework @@ -248,7 +248,7 @@ objc_binary(name = "bin", deps = [":swift_lib"]) swift_library(name = "swift_lib", - srcs = ["main.swift"], + srcs = ["app.swift"], deps = [":dylib"]) objc_framework(name = "dylib", @@ -752,4 +752,56 @@ EOF 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" +} + run_suite "apple_tests" diff --git a/tools/build_defs/apple/swift.bzl b/tools/build_defs/apple/swift.bzl index 336329f537..447134377e 100644 --- a/tools/build_defs/apple/swift.bzl +++ b/tools/build_defs/apple/swift.bzl @@ -116,6 +116,21 @@ def _swift_xcrun_args(ctx): return [] +def _swift_parsing_flags(ctx): + """Returns additional parsing flags for swiftc.""" + srcs = ctx.files.srcs + + # swiftc has two different parsing modes: script and library. + # The difference is that in script mode top-level expressions are allowed. + # This mode is triggered when the file compiled is called main.swift. + # Additionally, script mode is used when there's just one file in the + # compilation. we would like to avoid that and therefore force library mode + # when there's only one source and it's not called main. + if len(srcs) == 1 and srcs[0].basename != "main.swift": + return ["-parse-as-library"] + return [] + + def _is_valid_swift_module_name(string): """Returns True if the string is a valid Swift module name.""" if not string: @@ -288,7 +303,6 @@ def _swift_library_impl(ctx): module_name, "-emit-objc-header-path", output_header.path, - "-parse-as-library", "-target", target, "-sdk", @@ -297,11 +311,14 @@ def _swift_library_impl(ctx): module_cache_path(ctx), "-output-file-map", swiftc_output_map_file.path, - ] + _swift_compilation_mode_flags(ctx) + _swift_bitcode_flags(ctx) + ] if ctx.configuration.coverage_enabled: args.extend(["-profile-generate", "-profile-coverage-mapping"]) + args.extend(_swift_compilation_mode_flags(ctx)) + args.extend(_swift_bitcode_flags(ctx)) + args.extend(_swift_parsing_flags(ctx)) args.extend(srcs_args) args.extend(include_args) args.extend(framework_args) |