diff --git a/swift/toolchains/config/compile_config.bzl b/swift/toolchains/config/compile_config.bzl index b8f6c5dc2..b9683a2c0 100644 --- a/swift/toolchains/config/compile_config.bzl +++ b/swift/toolchains/config/compile_config.bzl @@ -1861,7 +1861,7 @@ def _disable_autolink_framework_copts(library_path): ) def _swift_module_search_path_map_fn(module): - """Returns the path to the directory containing a `.swiftmodule` file. + """Returns the path to the directory containing a Swift module file. This function is intended to be used as a mapping function for modules passed into `Args.add_all`. @@ -1872,10 +1872,16 @@ def _swift_module_search_path_map_fn(module): modules of a `SwiftInfo` provider. Returns: - The dirname of the module's `.swiftmodule` file. + The dirname of the module's `.swiftmodule` or `.swiftinterface` file. """ if module.swift: - search_path = module.swift.swiftmodule.dirname + # For modules with .swiftinterface files (like swift_import), we need + # to use the directory containing the .swiftinterface so that Swift + # can find it when compiling dependent module interfaces. + if module.swift.swiftinterface: + search_path = module.swift.swiftinterface.dirname + else: + search_path = module.swift.swiftmodule.dirname # If the dirname also ends in .swiftmodule, remove it as well so that # the compiler finds the module *directory*. diff --git a/test/fixtures/module_interface/BUILD b/test/fixtures/module_interface/BUILD index e2a18f8a4..f15160532 100644 --- a/test/fixtures/module_interface/BUILD +++ b/test/fixtures/module_interface/BUILD @@ -13,7 +13,10 @@ swift_binary( name = "client", srcs = ["Client.swift"], tags = FIXTURE_TAGS, - deps = [":toy_module"], + deps = [ + ":toy_module", + ":toy_module_consumer", + ], ) swift_import( @@ -26,3 +29,15 @@ swift_import( swiftinterface = "//test/fixtures/module_interface/library:toy_outputs/ToyModule.swiftinterface", tags = FIXTURE_TAGS, ) + +swift_import( + name = "toy_module_consumer", + archives = [ + "//test/fixtures/module_interface/library_consumer:toy_consumer_outputs/libToyModuleConsumer.a", + ], + module_name = "ToyModuleConsumer", + swiftdoc = "//test/fixtures/module_interface/library_consumer:toy_consumer_outputs/ToyModuleConsumer.swiftdoc", + swiftinterface = "//test/fixtures/module_interface/library_consumer:toy_consumer_outputs/ToyModuleConsumer.swiftinterface", + tags = FIXTURE_TAGS, + deps = [":toy_module"], +) diff --git a/test/fixtures/module_interface/Client.swift b/test/fixtures/module_interface/Client.swift index 953a80760..ebc632342 100644 --- a/test/fixtures/module_interface/Client.swift +++ b/test/fixtures/module_interface/Client.swift @@ -13,6 +13,7 @@ // limitations under the License. import ToyModule +import ToyModuleConsumer @main struct Main { @@ -20,5 +21,6 @@ struct Main { let value = ToyValue(number: 10) print(value.stringValue) print(value.squared()) + printToyValue() } } diff --git a/test/fixtures/module_interface/library_consumer/BUILD b/test/fixtures/module_interface/library_consumer/BUILD new file mode 100644 index 000000000..61dd49540 --- /dev/null +++ b/test/fixtures/module_interface/library_consumer/BUILD @@ -0,0 +1,52 @@ +load("//swift:swift_library.bzl", "swift_library") +load( + "//test/fixtures:common.bzl", + "FIXTURE_TAGS", +) +load( + "//test/rules:swift_library_artifact_collector.bzl", + "swift_library_artifact_collector", +) + +package( + default_testonly = True, + default_visibility = ["//test:__subpackages__"], +) + +licenses(["notice"]) + +# Checking in pre-built artifacts like a `.swiftinterface` and static libraries +# would require different artifacts for every platform the test might run on. +# Instead, build it on-demand but forward the outputs using the "artifact +# collector" rule below to make them act as if they were pre-built outputs when +# referenced by the `swift_import` rule. +# +# These must be in a separate package than the `swift_import` target because +# that rule propagates its pre-built inputs in `DefaultInfo`. + +swift_library( + name = "toy_module_consumer", + srcs = ["ToyConsumer.swift"], + library_evolution = True, + module_name = "ToyModuleConsumer", + tags = FIXTURE_TAGS, + deps = ["//test/fixtures/module_interface/library:toy_module_library"], +) + +swift_library_artifact_collector( + name = "toy_module_consumer_artifact_collector", + static_library = "toy_consumer_outputs/libToyModuleConsumer.a", + swiftdoc = "toy_consumer_outputs/ToyModuleConsumer.swiftdoc", + swiftinterface = "toy_consumer_outputs/ToyModuleConsumer.swiftinterface", + tags = FIXTURE_TAGS, + target = ":toy_module_consumer", + target_compatible_with = ["@platforms//os:macos"], +) + +swift_library( + name = "toy_module_consumer_without_library_evolution", + srcs = ["ToyConsumer.swift"], + library_evolution = False, + module_name = "ToyModuleConsumerNoEvolution", + tags = FIXTURE_TAGS, +) diff --git a/test/fixtures/module_interface/library_consumer/ToyConsumer.swift b/test/fixtures/module_interface/library_consumer/ToyConsumer.swift new file mode 100644 index 000000000..75ba90d09 --- /dev/null +++ b/test/fixtures/module_interface/library_consumer/ToyConsumer.swift @@ -0,0 +1,19 @@ +// Copyright 2024 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. + +import ToyModule + +public func printToyValue() { + print(ToyValue(number: 42)) +}