Skip to content
Draft
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
4 changes: 2 additions & 2 deletions tools/generators/pbxnativetargets/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ Here is an example output:
PRODUCT_NAME = pbxtargetdependencies_tests;
SDKROOT = macosx;
SUPPORTED_PLATFORMS = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_COMPILATION_MODE = "$(BAZEL_SWIFT_COMPILATION_MODE)";
TARGET_NAME = pbxtargetdependencies_tests;
};
name = Release;
Expand Down Expand Up @@ -255,7 +255,7 @@ Here is an example output:
PRODUCT_NAME = XCTestDynamicOverlay;
SDKROOT = macosx;
SUPPORTED_PLATFORMS = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_COMPILATION_MODE = "$(BAZEL_SWIFT_COMPILATION_MODE)";
TARGET_NAME = XCTestDynamicOverlay;
};
name = Release;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ extension Generator {
platformVariant: Target.PlatformVariant
) async throws -> [PlatformVariantBuildSetting] {
return try await callable(
/*isBundle:*/ isBundle,
/*originalProductBasename:*/ originalProductBasename,
/*productType:*/ productType,
/*platformVariant:*/ platformVariant
/* isBundle: */ isBundle,
/* originalProductBasename: */ originalProductBasename,
/* productType: */ productType,
/* platformVariant: */ platformVariant
)
}
}
Expand Down Expand Up @@ -146,6 +146,14 @@ extension Generator.CalculatePlatformVariantBuildSettings {
}

if let testHost = platformVariant.unitTestHost {
// Let Xcode select the host's native image, including its debug
// dylib. Bazel's bundle_loader points to a different executable.
buildSettings += [
.init(key: "BUNDLE_LOADER", value: "$(BAZEL_BUNDLE_LOADER__$(BAZEL_NATIVE_PREVIEWS))".pbxProjEscaped),
.init(key: "BAZEL_BUNDLE_LOADER__", value: #""""#),
.init(key: "BAZEL_BUNDLE_LOADER__NO", value: #""""#),
.init(key: "BAZEL_BUNDLE_LOADER__YES", value: "$(TEST_HOST)".pbxProjEscaped),
]
buildSettings.append(
.init(
key: "TARGET_BUILD_DIR",
Expand All @@ -165,6 +173,16 @@ extension Generator.CalculatePlatformVariantBuildSettings {
}

if let linkParams = platformVariant.linkParams {
if platformVariant.platform == .iOSSimulator {
buildSettings.append(
.init(
key: "LIBRARY_SEARCH_PATHS",
value:
#""$(inherited) $(PREVIEW_SDK_LIBRARY_SEARCH_PATH)""#
)
)
}

// Drop the `bazel-out` prefix since we use the env var for this
// portion of the path
buildSettings.append(
Expand All @@ -175,15 +193,56 @@ extension Generator.CalculatePlatformVariantBuildSettings {
"""#
)
)
buildSettings.append(
.init(
key: "OTHER_LDFLAGS",
value: #""@$(DERIVED_FILE_DIR)/link.params""#
if productType == .staticLibrary {
// Index preparation requests compile/index inputs, not bl.
// Reuse the existing input in inactive configurations so the
// phase never requires an unprepared runtime-policy sidecar.
buildSettings += [
.init(
key: "BAZEL_PREVIEW_RUNTIME_POLICY_SUFFIX",
value: (
"$(BAZEL_PREVIEW_RUNTIME_POLICY_SUFFIX_$(ACTION)_" +
"$(BAZEL_NATIVE_PREVIEWS)_$(INDEX_ENABLE_BUILD_ARENA))"
).pbxProjEscaped
),
.init(key: "BAZEL_PREVIEW_RUNTIME_POLICY_SUFFIX_build_YES_", value: ".runtime.json"),
.init(key: "BAZEL_PREVIEW_RUNTIME_POLICY_SUFFIX_build_YES_NO", value: ".runtime.json"),
]
// Xcode 26 derives a static-library target's Preview link
// closure from its Libtool task, not from OTHER_LDFLAGS.
// Create Link Dependencies truncates this response file for
// ordinary builds, preserving normal archive membership.
buildSettings.append(
.init(
key: "OTHER_LIBTOOLFLAGS",
value: #""@$(DERIVED_FILE_DIR)/link.params""#
)
)
)
} else {
buildSettings.append(
.init(
key: "OTHER_LDFLAGS",
value: #""-working-directory $(PROJECT_DIR) @$(DERIVED_FILE_DIR)/link.params""#
)
)
}
}

buildSettings.append(contentsOf: platformVariant.buildSettingsFromFile)
buildSettings.append(
contentsOf: platformVariant.buildSettingsFromFile.map { buildSetting in
guard platformVariant.platform.supportsXcodePreviews,
buildSetting.key == "SWIFT_COMPILATION_MODE",
buildSetting.value == "wholemodule"
else {
return buildSetting
}

// Unlike ENABLE_XOJIT_PREVIEWS, this configuration-scoped value
// is fixed before Preview eligibility checks. Ordinary builds
// retain WMO; only an opted-in Preview configuration is incremental.
return .init(key: buildSetting.key, value: #""$(BAZEL_SWIFT_COMPILATION_MODE)""#)
}
)

return buildSettings
}
Expand Down Expand Up @@ -216,6 +275,24 @@ private extension Platform.OS {
}
}

private extension Platform {
var supportsXcodePreviews: Bool {
switch self {
case .macOS,
.iOSSimulator,
.tvOSSimulator,
.visionOSSimulator,
.watchOSSimulator:
return true
case .iOSDevice,
.tvOSDevice,
.visionOSDevice,
.watchOSDevice:
return false
}
}
}

private extension PBXProductType {
var fileExtension: String? {
switch self {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ extension Generator {
allConditionalFiles: Set<BazelPath>
) -> [BuildSetting] {
return callable(
/*platformBuildSettings:*/ platformBuildSettings,
/*allConditionalFiles:*/ allConditionalFiles
/* platformBuildSettings: */ platformBuildSettings,
/* allConditionalFiles: */ allConditionalFiles
)
}
}
Expand Down Expand Up @@ -71,7 +71,7 @@ extension Generator.CalculateXcodeConfigurationBuildSettings {
// Lots of code just to quote and `.pbxProjEscaped`
// the paths
platformBuildSettings.conditionalFiles
.map { $0.path.quoteIfNeeded }
.map(\.path.quoteIfNeeded)
// TODO: See if we can not sort, or sort earlier
.sorted()
.joined(separator: " ")
Expand Down Expand Up @@ -101,7 +101,7 @@ extension Generator.CalculateXcodeConfigurationBuildSettings {
excludedSourceFileNames.append(
contentsOf: allConditionalFiles
.subtracting(conditionalFiles)
.map { $0.path.pbxProjEscaped }
.map(\.path.pbxProjEscaped)
)

// Set configuration-wide conditional files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ extension Generator.CreateBuildPhases {
buildPhases.append(
createCreateLinkDependenciesBuildPhaseObject(
subIdentifier: identifier.subIdentifier,
hasCompileStub: hasCompileStub
hasCompileStub: hasCompileStub,
isStaticLibrary: productType == .staticLibrary
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ extension Generator {
/// target.
func callAsFunction(
subIdentifier: Identifiers.Targets.SubIdentifier,
hasCompileStub: Bool
hasCompileStub: Bool,
isStaticLibrary: Bool = false
) -> Object {
return callable(
/*subIdentifier:*/ subIdentifier,
/*hasCompileStub:*/ hasCompileStub
/* subIdentifier: */ subIdentifier,
/* hasCompileStub: */ hasCompileStub,
/* isStaticLibrary: */ isStaticLibrary
)
}
}
Expand All @@ -31,25 +33,68 @@ extension Generator {
extension Generator.CreateCreateLinkDependenciesBuildPhaseObject {
typealias Callable = (
_ subIdentifier: Identifiers.Targets.SubIdentifier,
_ hasCompileStub: Bool
_ hasCompileStub: Bool,
_ isStaticLibrary: Bool
) -> Object

static func defaultCallable(
subIdentifier: Identifiers.Targets.SubIdentifier,
hasCompileStub: Bool
hasCompileStub: Bool,
isStaticLibrary: Bool = false
) -> Object {
let runtimeAction = isStaticLibrary ? #"""
if [[ "${BAZEL_NATIVE_PREVIEWS:-}" == "YES" && "${ACTION:-}" == build ]]; then
# Script phases have CURRENT_ARCH=undefined_arch. Use the selected target,
# never the host architecture or an unrelated ambient toolchain directory.
# Explicit exit is necessary: macOS sh can report success for a failed
# parameter expansion when an EXIT trap is installed.
for runtime_setting in ARCHS LLVM_TARGET_TRIPLE_VENDOR LLVM_TARGET_TRIPLE_OS_VERSION; do
if [[ -z "${!runtime_setting:-}" ]]; then
echo "error: Missing Preview build setting $runtime_setting" >&2
exit 1
fi
done
read -r -a runtime_archs <<< "$ARCHS"
if [[ "${#runtime_archs[@]}" != 1 ]]; then
echo "error: Preview runtime planning requires exactly one ARCHS value: $ARCHS" >&2
exit 1
fi
runtime_target="${runtime_archs[0]}-${LLVM_TARGET_TRIPLE_VENDOR}-${LLVM_TARGET_TRIPLE_OS_VERSION}"
runtime_target+="${LLVM_TARGET_TRIPLE_SUFFIX:-}"
/usr/bin/python3 "$BAZEL_INTEGRATION_DIR/preview_runtime_link_params.py" \
--driver "${LD:-}" \
--sdk "${SDK_DIR:-}" \
--target "$runtime_target" \
--swift-profile "${BAZEL_PREVIEW_SWIFT_PROFILE:-NO}" \
--driver-policy-file "$SCRIPT_INPUT_FILE_1" >> "$link_params_tmp"
fi

"""# : ""
let action = #"""
readonly link_params_tmp="$(mktemp "$SCRIPT_OUTPUT_FILE_0.tmp.XXXXXX")"
trap 'rm -f "$link_params_tmp"' EXIT
perl -pe 's/\$(\()?([a-zA-Z_]\w*)(?(1)\))/$ENV{$2}/g' \
"$SCRIPT_INPUT_FILE_0" > "$SCRIPT_OUTPUT_FILE_0"
< "$SCRIPT_INPUT_FILE_0" > "$link_params_tmp"
\#(runtimeAction)\#
chmod 0644 "$link_params_tmp"
mv -f "$link_params_tmp" "$SCRIPT_OUTPUT_FILE_0"
trap - EXIT
"""#
let indexGuard = isStaticLibrary
? #"[[ "${ACTION:-}" != indexbuild && "${INDEX_ENABLE_BUILD_ARENA:-}" != YES ]] && "#
: ""
var shellScriptComponents: [String] = [
#"""
set -euo pipefail

if [[ "${ENABLE_PREVIEWS:-}" == "YES" ]]; then
if \#(indexGuard)\#
[[ "${ENABLE_PREVIEWS:-}" == "YES" || \
"${BAZEL_NATIVE_PREVIEWS:-}" == "YES" ]]; then
\#(action)
else
touch "$SCRIPT_OUTPUT_FILE_0"
# A prior Preview build may have populated this response file. Truncate it
# so ordinary linker and Libtool tasks cannot consume stale Preview inputs.
: > "$SCRIPT_OUTPUT_FILE_0"
fi

"""#,
Expand All @@ -58,6 +103,13 @@ fi
var outputPaths = [#"""
"$(DERIVED_FILE_DIR)/link.params",
"""#]
let runtimeInputs = isStaticLibrary ? #"""
"$(LINK_PARAMS_FILE)$(BAZEL_PREVIEW_RUNTIME_POLICY_SUFFIX)",
"$(BAZEL_INTEGRATION_DIR)/preview_runtime_link_params.py",
"$(LD)",
"$(SDK_DIR)/SDKSettings.plist",

"""# : ""
if hasCompileStub {
outputPaths.append(#"""
"$(DERIVED_FILE_DIR)/_CompileStub_.m",
Expand All @@ -77,6 +129,7 @@ touch "$SCRIPT_OUTPUT_FILE_1"
);
inputPaths = (
"$(LINK_PARAMS_FILE)",
\#(runtimeInputs)\#
);
name = "Create Link Dependencies";
outputPaths = (
Expand Down
Loading
Loading