Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Example/HelloWorld/BUILD
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template_rule")
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application", "ios_unit_test")
load("@build_bazel_rules_apple//apple:ios.bzl", "ios_application", "ios_unit_test", "ios_build_test")
load("@build_bazel_rules_apple//apple:macos.bzl", "macos_application", "macos_command_line_application", "macos_unit_test")
load("@build_bazel_rules_apple//apple:watchos.bzl", "watchos_application", "watchos_extension", "watchos_unit_test")
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_interop_hint", "swift_library")
Expand Down Expand Up @@ -242,6 +242,12 @@ macos_command_line_application(
deps = [":MacCLIAppLib"],
)

ios_build_test(
name = "HelloWorldLibBuildTest",
minimum_os_version = IOS_MINIMUM_OS_VERSION,
targets = [":HelloWorldLib"],
)

# Project setup

setup_sourcekit_bsp(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ enum BazelTargetQuerierParserError: Error, LocalizedError {
"Multiple parent actions found for \(parent) in the aquery output. This means your project is building multiple variants of the same top-level target, which the BSP cannot handle today."
case .configurationNotFound(let id):
return "Configuration \(id) not found in the aquery output."
case .sdkNameNotFound(let label):
return "SDK info not found for \(label) in the aquery output."
case .sdkNameNotFound(let cpuAndArch):
return "SDK info could not be inferred for \(cpuAndArch)."
case .indexOutOfBounds(let index, let line):
return "Index \(index) is out of bounds for array at line \(line)"
case .unexpectedLanguageRule(let target, let ruleClass):
Expand Down Expand Up @@ -573,18 +573,16 @@ extension BazelTargetQuerierParserImpl {
guard let fullConfig = aqueryConfigurations[configId]?.mnemonic else {
throw BazelTargetQuerierParserError.configurationNotFound(configId)
}
guard let sdkName = parentAction.environmentVariables.first(where: { $0.key == "APPLE_SDK_PLATFORM" })?.value
else {
throw BazelTargetQuerierParserError.sdkNameNotFound(effectiveParentLabel)
}
let configComponents = fullConfig.components(separatedBy: "-")
// min15.0 -> 15.0
let minTargetArg = String(try configComponents.getIndexThrowing(4).dropFirst(3))
// The first component contains the platform and arch info.
// e.g darwin_arm64 -> (darwin, arm64)
let cpuComponents = try configComponents.getIndexThrowing(0).split(separator: "_", maxSplits: 1)
let platform = try cpuComponents.getIndexThrowing(0)
let cpuArch = try cpuComponents.getIndexThrowing(1)
let cpuAndArch = try configComponents.getIndexThrowing(0)
let sdkName = try inferSdkName(from: cpuAndArch)
let cpuComponents = cpuAndArch.split(separator: "_", maxSplits: 1)
let platform = String(try cpuComponents.getIndexThrowing(0))
let cpuArch = String(try cpuComponents.getIndexThrowing(1))

// To support compiling libraries directly, we need to additionally strip out
// the transition and distinguisher parts of the configuration name, as those will not
Expand All @@ -600,11 +598,44 @@ extension BazelTargetQuerierParserImpl {
configurationName: fullConfig,
effectiveConfigurationName: effectiveConfigurationName,
minimumOsVersion: minTargetArg,
platform: String(platform),
cpuArch: String(cpuArch),
platform: platform,
cpuArch: cpuArch,
sdkName: sdkName.lowercased()
)
}

private func inferSdkName(from cpuAndArch: String) throws -> String {
// Source: https://github.com/bazelbuild/apple_support/blob/main/crosstool/cc_toolchain_config.bzl
// We can't rely on APPLE_SDK_PLATFORM in all cases because build_test rules won't have it at the top-level.
if cpuAndArch.hasPrefix("darwin") {
return "macosx"
} else if cpuAndArch.hasPrefix("ios") {
switch cpuAndArch {
case "ios_arm64", "ios_arm64e": return "iphoneos"
case "ios_sim_arm64", "ios_x86_64": return "iphonesimulator"
default: break
}
} else if cpuAndArch.hasPrefix("tvos") {
switch cpuAndArch {
case "tvos_arm64": return "appletvos"
case "tvos_sim_arm64", "tvos_x86_64": return "appletvsimulator"
default: break
}
} else if cpuAndArch.hasPrefix("watchos") {
switch cpuAndArch {
case "watchos_arm64_32", "watchos_armv7k", "watchos_device_arm64", "watchos_device_arm64e": return "watchos"
case "watchos_arm64", "watchos_x86_64": return "watchsimulator"
default: break
}
} else if cpuAndArch.hasPrefix("visionos") {
switch cpuAndArch {
case "visionos_arm64": return "xros"
case "visionos_sim_arm64": return "xrsimulator"
default: break
}
}
throw BazelTargetQuerierParserError.sdkNameNotFound(cpuAndArch)
}
}

// MARK: - Bazel label parsing helpers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ struct BazelTargetCompilerArgsExtractorTests {
== expectedSwiftResult.map {
$0.replacingOccurrences(
of: "ios_sim_arm64-dbg-ios-sim_arm64-min17.0",
with: "ios_sim_arm64-dbg-ios-sim_arm64-min17.0-applebin_ios-ST-faa571ec622f"
with: "ios_sim_arm64-dbg-ios-sim_arm64-min17.0-ST-2842469f5300"
)
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,14 @@ struct BazelTargetQuerierParserImplTests {

// Top level targets - verify label and rule type (config IDs are assigned during parsing)
let expectedTopLevelTargets: [(String, TopLevelRuleType)] = [
("//HelloWorld:HelloWorldMacTests", .macosUnitTest),
("//HelloWorld:HelloWorldTests", .iosUnitTest),
("//HelloWorld:HelloWorld", .iosApplication),
("//HelloWorld:HelloWorldWatchExtension", .watchosExtension),
("//HelloWorld:HelloWorldWatchTests", .watchosUnitTest),
("//HelloWorld:HelloWorldMacCLIApp", .macosCommandLineApplication),
("//HelloWorld:HelloWorld", .iosApplication),
("//HelloWorld:HelloWorldMacApp", .macosApplication),
("//HelloWorld:HelloWorldTests", .iosUnitTest),
("//HelloWorld:HelloWorldMacTests", .macosUnitTest),
("//HelloWorld:HelloWorldWatchApp", .watchosApplication),
("//HelloWorld:HelloWorldWatchExtension", .watchosExtension),
("//HelloWorld:HelloWorldMacCLIApp", .macosCommandLineApplication),
]
#expect(result.topLevelTargets.count == expectedTopLevelTargets.count)
for (index, expected) in expectedTopLevelTargets.enumerated() {
Expand Down Expand Up @@ -320,7 +320,7 @@ struct BazelTargetQuerierParserImplTests {
#expect(
result.topLevelConfigIdToInfoMap[1]
== BazelTargetConfigurationInfo(
configurationName: "ios_sim_arm64-dbg-ios-sim_arm64-min17.0-applebin_ios-ST-faa571ec622f",
configurationName: "ios_sim_arm64-dbg-ios-sim_arm64-min17.0-ST-2842469f5300",
effectiveConfigurationName: "ios_sim_arm64-dbg-ios-sim_arm64-min17.0",
minimumOsVersion: "17.0",
platform: "ios",
Expand All @@ -333,7 +333,7 @@ struct BazelTargetQuerierParserImplTests {
#expect(
result.topLevelConfigIdToInfoMap[2]
== BazelTargetConfigurationInfo(
configurationName: "darwin_arm64-dbg-macos-arm64-min15.0-applebin_macos-ST-d1334902beb6",
configurationName: "darwin_arm64-dbg-macos-arm64-min15.0-ST-3b9f41d61db6",
effectiveConfigurationName: "darwin_arm64-dbg-macos-arm64-min15.0",
minimumOsVersion: "15.0",
platform: "darwin",
Expand All @@ -346,11 +346,11 @@ struct BazelTargetQuerierParserImplTests {
#expect(
result.topLevelConfigIdToInfoMap[3]
== BazelTargetConfigurationInfo(
configurationName: "watchos_x86_64-dbg-watchos-x86_64-min7.0-applebin_watchos-ST-74f4ed91ef5d",
effectiveConfigurationName: "watchos_x86_64-dbg-watchos-x86_64-min7.0",
configurationName: "watchos_arm64-dbg-watchos-arm64-min7.0-ST-f4f2bb7e56ed",
effectiveConfigurationName: "watchos_arm64-dbg-watchos-arm64-min7.0",
minimumOsVersion: "7.0",
platform: "watchos",
cpuArch: "x86_64",
cpuArch: "arm64",
sdkName: "watchsimulator"
)
)
Expand Down
6 changes: 3 additions & 3 deletions Tests/SourceKitBazelBSPTests/BazelTargetQuerierTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,16 +369,16 @@ struct BazelTargetQuerierTests {
}

/// Example aquery output for the example app shipped with this repo.
/// bazelisk aquery "mnemonic('CppCompile|ObjcCompile|SwiftCompile|BundleTreeApp|SignBinary|TestRunner', deps(//HelloWorld:HelloWorldMacTests) union deps(//HelloWorld:HelloWorldTests) union deps(//HelloWorld:HelloWorld) union deps(//HelloWorld:HelloWorldWatchExtension) union deps(//HelloWorld:HelloWorldWatchTests) union deps(//HelloWorld:HelloWorldMacCLIApp) union deps(//HelloWorld:HelloWorldMacApp) union deps(//HelloWorld:HelloWorldWatchApp))" --noinclude_artifacts --noinclude_aspects --features=-compiler_param_file --output proto --config=index_build > aquery.pb
/// bazelisk aquery "mnemonic('CppCompile|ObjcCompile|SwiftCompile|BundleTreeApp|SignBinary|TestRunner', deps(//HelloWorld:HelloWorldMacTests) union deps(//HelloWorld:HelloWorldTests) union deps(//HelloWorld:HelloWorldLibBuildTest) union deps(//HelloWorld:HelloWorld) union deps(//HelloWorld:HelloWorldWatchExtension) union deps(//HelloWorld:HelloWorldWatchTests) union deps(//HelloWorld:HelloWorldMacCLIApp) union deps(//HelloWorld:HelloWorldMacApp) union deps(//HelloWorld:HelloWorldWatchApp))" --noinclude_artifacts --noinclude_aspects --features=-compiler_param_file --output proto --config=index_build > aquery.pb
let exampleAqueryOutput: Data = {
guard let url = Bundle.module.url(forResource: "aquery", withExtension: "pb"),
let data = try? Data.init(contentsOf: url)
else { fatalError("aquery.pb is not found in Resources folder") }
return data
}()

// Example cquery output for the example app shipped with this repo.
/// bazelisk cquery 'let topLevelTargets = kind("ios_application|ios_unit_test|macos_application|macos_command_line_application|macos_unit_test|watchos_application|watchos_extension|watchos_unit_test", deps(//HelloWorld:HelloWorld) union deps(//HelloWorld:HelloWorldMacApp) union deps(//HelloWorld:HelloWorldMacCLIApp) union deps(//HelloWorld:HelloWorldMacTests) union deps(//HelloWorld:HelloWorldTests) union deps(//HelloWorld:HelloWorldWatchApp) union deps(//HelloWorld:HelloWorldWatchExtension) union deps(//HelloWorld:HelloWorldWatchTests)) in $topLevelTargets union (kind("swift_library|objc_library|cc_library|alias|source file|_ios_internal_unit_test_bundle|_ios_internal_ui_test_bundle|_watchos_internal_unit_test_bundle|_watchos_internal_ui_test_bundle|_macos_internal_unit_test_bundle|_macos_internal_ui_test_bundle|_tvos_internal_unit_test_bundle|_tvos_internal_ui_test_bundle|_visionos_internal_unit_test_bundle|_visionos_internal_ui_test_bundle", deps($topLevelTargets)))' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=index_build > cquery.pb
/// Example cquery output for the example app shipped with this repo.
/// bazelisk cquery 'let topLevelTargets = kind("ios_application|ios_unit_test|macos_application|macos_command_line_application|macos_unit_test|watchos_application|watchos_extension|watchos_unit_test", deps(//HelloWorld/...)) in $topLevelTargets union (kind("swift_library|objc_library|cc_library|alias|source file|_ios_internal_unit_test_bundle|_ios_internal_ui_test_bundle|_watchos_internal_unit_test_bundle|_watchos_internal_ui_test_bundle|_macos_internal_unit_test_bundle|_macos_internal_ui_test_bundle|_tvos_internal_unit_test_bundle|_tvos_internal_ui_test_bundle|_visionos_internal_unit_test_bundle|_visionos_internal_ui_test_bundle", deps($topLevelTargets)))' --noinclude_aspects --notool_deps --noimplicit_deps --output proto --config=index_build > cquery.pb
let exampleCqueryOutput: Data = {
guard let url = Bundle.module.url(forResource: "cquery", withExtension: "pb"),
let data = try? Data.init(contentsOf: url)
Expand Down
Loading