From 758a73e794756add970a08a16890167296923376 Mon Sep 17 00:00:00 2001 From: Dmitry Shevchenko Date: Fri, 8 Jul 2016 17:13:22 +0000 Subject: Make swift_library explicitly specify the module maps it is using. * This seems to fix an issue with Clang loading the same header twice when it's discovering module maps implicitly. Also makes the command line cleaner. -- MOS_MIGRATED_REVID=126922449 --- src/test/shell/bazel/BUILD | 1 + src/test/shell/bazel/bazel_apple_test.sh | 25 ++++++++++++++++++++++--- tools/build_defs/apple/swift.bzl | 24 ++++++++++++++++++------ 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD index e064d72f87..f70d852cd1 100644 --- a/src/test/shell/bazel/BUILD +++ b/src/test/shell/bazel/BUILD @@ -39,6 +39,7 @@ filegroup( "//src/tools/xcode/stdredirect:StdRedirect.dylib", "//src/tools/xcode/swiftstdlibtoolwrapper", "//src/tools/xcode/xcrunwrapper", + "//src/tools/xcode/xcodelocator:xcode-locator", "//third_party/iossim", ], "//conditions:default": [], diff --git a/src/test/shell/bazel/bazel_apple_test.sh b/src/test/shell/bazel/bazel_apple_test.sh index 4f2eeb6d8b..efa81ffa57 100755 --- a/src/test/shell/bazel/bazel_apple_test.sh +++ b/src/test/shell/bazel/bazel_apple_test.sh @@ -30,6 +30,16 @@ function set_up() { copy_examples setup_objc_test_support + # Find where Xcode 7 (any sub-version will do) is located and get the iOS SDK + # version it contains. + # TODO(b/27267941): This is a hack until the bug is fixed. + XCODE_LOCATOR="$(bazel info output_base)/external/bazel_tools/tools/objc/xcode-locator" + XCODE_INFO=$($XCODE_LOCATOR -v | grep -m1 7) + XCODE_DIR=$(echo $XCODE_INFO | cut -d ':' -f3) + XCODE_VERSION=$(echo $XCODE_INFO | cut -d ':' -f1) + IOS_SDK_VERSION=$(DEVELOPER_DIR=$XCODE_DIR xcodebuild -sdk -version \ + | grep iphonesimulator | cut -d ' ' -f6) + # Allow access to //external:xcrunwrapper. rm WORKSPACE ln -sv ${workspace_file} WORKSPACE @@ -97,15 +107,16 @@ EOF function test_swift_library() { local swift_lib_pkg=examples/swift assert_build_output ./bazel-genfiles/${swift_lib_pkg}/examples_swift_swift_lib.a \ - ${swift_lib_pkg}:swift_lib --ios_sdk_version=$IOS_SDK_VERSION + ${swift_lib_pkg}:swift_lib --ios_sdk_version=$IOS_SDK_VERSION --xcode_version=$XCODE_VERSION assert_build_output ./bazel-genfiles/${swift_lib_pkg}/examples_swift_swift_lib.swiftmodule \ - ${swift_lib_pkg}:swift_lib --ios_sdk_version=$IOS_SDK_VERSION + ${swift_lib_pkg}:swift_lib --ios_sdk_version=$IOS_SDK_VERSION --xcode_version=$XCODE_VERSION } function test_build_app() { make_app bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION \ + --xcode_version=$XCODE_VERSION \ //ios:app >$TEST_log 2>&1 || fail "should pass" ls bazel-bin/ios/app.ipa || fail "should generate app.ipa" } @@ -146,6 +157,7 @@ objc_binary(name = "bin", EOF bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION \ + --xcode_version=$XCODE_VERSION \ //ios:bin >$TEST_log 2>&1 || fail "should build" } @@ -202,6 +214,7 @@ EOF bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION \ --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" } @@ -248,7 +261,7 @@ objc_framework(name = "dylib", EOF bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION \ - --ios_minimum_os=8.0 \ + --ios_minimum_os=8.0 --xcode_version=$XCODE_VERSION \ //ios:swift_lib >$TEST_log 2>&1 || fail "should build" } @@ -289,6 +302,7 @@ EOF bazel build --verbose_failures //package:lipo_out \ --ios_multi_cpus=i386,x86_64 \ + --xcode_version=$XCODE_VERSION \ --ios_sdk_version=$IOS_SDK_VERSION \ || fail "should build apple_binary and obtain info via lipo" @@ -328,6 +342,7 @@ EOF bazel build --verbose_failures //package:extract_archives \ --ios_multi_cpus=i386,x86_64 \ + --xcode_version=$XCODE_VERSION \ --ios_sdk_version=$IOS_SDK_VERSION \ || fail "should build multi-architecture archive" @@ -369,6 +384,7 @@ swift_library(name = "util", EOF bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION \ + --xcode_version=$XCODE_VERSION \ //ios:swift_lib >$TEST_log 2>&1 || fail "should build" } @@ -407,6 +423,7 @@ ios_test(name = "app_test", EOF bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION \ + --xcode_version=$XCODE_VERSION \ //ios:app_test >$TEST_log 2>&1 || fail "should build" otool -lv bazel-bin/ios/app_test_bin \ @@ -441,10 +458,12 @@ swift_library(name = "swift_lib", EOF ! bazel build --verbose_failures --ios_sdk_version=$IOS_SDK_VERSION -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 --ios_sdk_version=$IOS_SDK_VERSION -c dbg \ + --xcode_version=$XCODE_VERSION \ //ios:swift_lib >$TEST_log 2>&1 || fail "should build" } diff --git a/tools/build_defs/apple/swift.bzl b/tools/build_defs/apple/swift.bzl index ce946a44c4..7df084208b 100644 --- a/tools/build_defs/apple/swift.bzl +++ b/tools/build_defs/apple/swift.bzl @@ -60,6 +60,7 @@ def _module_name(ctx): def _swift_library_impl(ctx): """Implementation for swift_library Skylark rule.""" + # TODO(b/29772303): Assert xcode version. cpu = ctx.fragments.apple.ios_cpu() platform = ctx.fragments.apple.ios_cpu_platform() sdk_version = ctx.fragments.apple.sdk_version_for_platform(platform) @@ -83,16 +84,18 @@ def _swift_library_impl(ctx): dep_libs += swift.transitive_libs dep_modules += swift.transitive_modules - objc_includes = set() # Everything that needs to be included with -I - objc_files = set() # All inputs required for the compile action + objc_includes = set() # Everything that needs to be included with -I + objc_files = set() # All inputs required for the compile action + objc_module_maps = set() # Module maps for dependent targets objc_defines = set() for objc in objc_providers: objc_includes += objc.include - objc_includes = objc_includes.union([x.dirname for x in objc.module_map]) objc_files += objc.header objc_files += objc.module_map + objc_module_maps += objc.module_map + files = set(objc.static_framework_file) + set(objc.dynamic_framework_file) objc_files += files framework_dirs += _parent_dirs(objc.framework_dir) @@ -137,13 +140,22 @@ def _swift_library_impl(ctx): clang_args = _intersperse( "-Xcc", + # Add the current directory to clang's search path. - # This instance of clang is spawned by swiftc to compile module maps and is - # not passed the current directory as a search path by default. + # This instance of clang is spawned by swiftc to compile module maps and + # is not passed the current directory as a search path by default. ["-iquote", "."] + # Pass DEFINE or copt values from objc configuration and rules to clang + ["-D" + x for x in objc_defines] + ctx.fragments.objc.copts - + _clang_compilation_mode_flags(ctx)) + + _clang_compilation_mode_flags(ctx) + + # Load module maps explicitly instead of letting Clang discover them on + # search paths. This is needed to avoid a case where Clang may load the + # same header both in modular and non-modular contexts, leading to + # duplicate definitions in the same file. + # https://llvm.org/bugs/show_bug.cgi?id=19501 + + ["-fmodule-map-file=%s" % x.path for x in objc_module_maps]) args = [ "swiftc", -- cgit v1.2.3