From e2f32bdeb134934944163a0182e533e69bb98287 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Marc=CC=A7al?= Date: Sat, 8 Mar 2025 13:33:20 -0300 Subject: [PATCH 1/3] Add support to custom toolchains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lucas Marçal --- .../src/Extensions/XCScheme+Extensions.swift | 13 ++- .../CreateAutogeneratedXCSchemesTests.swift | 2 +- tools/generators/xcschemes/README.md | 2 +- .../src/Generator/CreateScheme.swift | 7 +- tools/swiftc_stub/main.swift | 93 ++++++++++--------- .../internal/bazel_integration_files/clang.sh | 12 ++- xcodeproj/internal/bazel_integration_files/ld | 10 +- 7 files changed, 83 insertions(+), 56 deletions(-) diff --git a/tools/generators/legacy/src/Extensions/XCScheme+Extensions.swift b/tools/generators/legacy/src/Extensions/XCScheme+Extensions.swift index 9c388c8a26..5cca1277ca 100644 --- a/tools/generators/legacy/src/Extensions/XCScheme+Extensions.swift +++ b/tools/generators/legacy/src/Extensions/XCScheme+Extensions.swift @@ -35,7 +35,7 @@ extension XCScheme { .first { otherPreActions.append( - .symlinkDefaultToolchainUsrLibDirectory( + .symlinkToolchainUsrLibDirectory( buildableReference: launchableTarget.targetInfo .buildableReference ) @@ -201,10 +201,10 @@ touch "$BUILD_MARKER_FILE" ) } - /// Symlinks `$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib` to + /// Symlinks `$TOOLCHAIN_DIR/usr/lib` to /// `$(BAZEL_INTEGRATION_DIR)/../lib` so that Xcode can copy sanitizers' /// dylibs. - static func symlinkDefaultToolchainUsrLibDirectory( + static func symlinkToolchainUsrLibDirectory( buildableReference: XCScheme.BuildableReference ) -> XCScheme.ExecutionAction { return .init( @@ -215,9 +215,12 @@ if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then - # TODO: Support custom toolchains once clang.sh supports them cd "$INTERNAL_DIR" || exit 1 - ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib + if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then + ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib + else + ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib + fi fi """#, title: "Prepare BazelDependencies", diff --git a/tools/generators/legacy/test/CreateAutogeneratedXCSchemesTests.swift b/tools/generators/legacy/test/CreateAutogeneratedXCSchemesTests.swift index 25b491d347..5558fc2598 100644 --- a/tools/generators/legacy/test/CreateAutogeneratedXCSchemesTests.swift +++ b/tools/generators/legacy/test/CreateAutogeneratedXCSchemesTests.swift @@ -178,7 +178,7 @@ class CreateAutogeneratedXCSchemesTests: XCTestCase { expectedTargetInfo.productType.isLaunchable { expectedBuildPreActions.append( - .symlinkDefaultToolchainUsrLibDirectory( + .symlinkToolchainUsrLibDirectory( buildableReference: expectedTargetInfo.buildableReference ) ) diff --git a/tools/generators/xcschemes/README.md b/tools/generators/xcschemes/README.md index 75ec1871d9..211afc3b68 100644 --- a/tools/generators/xcschemes/README.md +++ b/tools/generators/xcschemes/README.md @@ -78,7 +78,7 @@ Here is an example output: ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then $INTERNAL_DIR" || exit 1 ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi "> Int32 { } func handleXcodePreviewThunk(args: [String], paths: [PathKey: URL]) throws -> Never { - guard let sdkPath = paths[PathKey.sdk]?.path else { - fputs( - "error: No such argument '-sdk'. Using /usr/bin/swiftc.", - stderr - ) - exit(1) + var swiftcPath: String? + + if let toolchainDir = ProcessInfo.processInfo.environment["TOOLCHAIN_DIR"] { + swiftcPath = "\(toolchainDir)/usr/bin/swiftc" + } else { + guard let sdkPath = paths[PathKey.sdk]?.path else { + fputs("error: No such argument '-sdk'. Using /usr/bin/swiftc.", stderr) + exit(1) + } + + // We could produce this file at the start of the build? + let fullRange = NSRange(sdkPath.startIndex..., in: sdkPath) + let matches = try NSRegularExpression( + pattern: #"(.*?/Contents/Developer)/.*"# + ).matches(in: sdkPath, range: fullRange) + guard let match = matches.first, + let range = Range(match.range(at: 1), in: sdkPath) + else { + fputs("error: Failed to parse DEVELOPER_DIR from '-sdk'. Using /usr/bin/swiftc.", stderr) + exit(1) + } + let developerDir = sdkPath[range] + + swiftcPath = "\(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc" } - // TODO: Make this work with custom toolchains - // We could produce this file at the start of the build? - let fullRange = NSRange(sdkPath.startIndex..., in: sdkPath) - let matches = try NSRegularExpression( - pattern: #"(.*?/Contents/Developer)/.*"# - ).matches(in: sdkPath, range: fullRange) - guard let match = matches.first, - let range = Range(match.range(at: 1), in: sdkPath) - else { - fputs( - """ -error: Failed to parse DEVELOPER_DIR from '-sdk'. Using /usr/bin/swiftc. -""", - stderr - ) + guard let swiftcPath else { + fputs("error: Failed to determine swiftc path", stderr) exit(1) } - let developerDir = sdkPath[range] - - try exit(runSubProcess( - executable: """ -\(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -""", - args: Array(args.dropFirst()) - )) + + try exit(runSubProcess(executable: swiftcPath, args: Array(args.dropFirst()))) } // MARK: - Main @@ -183,21 +182,31 @@ if args.count == 2, args.last == "--version" || args.last == "-v" { exit(1) } - // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin - let pathComponents = path.split(separator: ":", maxSplits: 1) - let xcodeBinPath = pathComponents[0] - guard xcodeBinPath.hasSuffix("/Contents/Developer/usr/bin") else { - fputs("error: Xcode based bin PATH not set", stderr) - exit(1) + var swiftcPath: String? + + if let toolchainDir = ProcessInfo.processInfo.environment["TOOLCHAIN_DIR"] { + swiftcPath = """ + \(toolchainDir)/usr/bin/swiftc + """ + } else { + // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin + let pathComponents = path.split(separator: ":", maxSplits: 1) + let xcodeBinPath = pathComponents[0] + guard xcodeBinPath.hasSuffix("/Contents/Developer/usr/bin") else { + fputs("error: Xcode based bin PATH not set", stderr) + exit(1) + } + // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer + let developerDir = xcodeBinPath.dropLast(8) + swiftcPath = """ + \(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc + """ } - // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer - let developerDir = xcodeBinPath.dropLast(8) - - // TODO: Make this work with custom toolchains - let swiftcPath = """ -\(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc -""" + guard let swiftcPath else { + fputs("error: Failed to determine swiftc path", stderr) + exit(1) + } // args.last allows passing in -v (Xcode < 16b3) and --version (>= 16b3) try exit(runSubProcess(executable: swiftcPath, args: [args.last!])) diff --git a/xcodeproj/internal/bazel_integration_files/clang.sh b/xcodeproj/internal/bazel_integration_files/clang.sh index a327a2a3a9..6082bd2f43 100755 --- a/xcodeproj/internal/bazel_integration_files/clang.sh +++ b/xcodeproj/internal/bazel_integration_files/clang.sh @@ -17,9 +17,15 @@ do break ;; -v) - # TODO: Make this work with custom toolchains - DEV_DIR_PREFIX=$(awk '{ sub(/.*-isysroot /, ""); sub(/.Contents\/Developer.*/, ""); print}' <<< "${@:1}") - clang="$DEV_DIR_PREFIX/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" + if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then + # Use the toolchain's clang + clang="$TOOLCHAIN_DIR/usr/bin/clang" + else + # Use default Xcode default toolchain if no toolchain is provided + DEV_DIR_PREFIX=$(awk '{ sub(/.*-isysroot /, ""); sub(/.Contents\/Developer.*/, ""); print}' <<< "${@:1}") + clang="$DEV_DIR_PREFIX/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" + fi + "$clang" "${@:1}" break ;; diff --git a/xcodeproj/internal/bazel_integration_files/ld b/xcodeproj/internal/bazel_integration_files/ld index 2156250535..4818a4bf8f 100755 --- a/xcodeproj/internal/bazel_integration_files/ld +++ b/xcodeproj/internal/bazel_integration_files/ld @@ -22,8 +22,14 @@ do *.preview-thunk.dylib) # Pass through for SwiftUI Preview thunk compilation - # TODO: Make this work with custom toolchains - exec "$developer_dir/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" "${passthrough_args[@]}" + if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then + # Use the toolchain's ld + ld="$TOOLCHAIN_DIR/usr/bin/ld" + else + # Use default Xcode default toolchain if no toolchain is provided + ld="$developer_dir/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" + fi + exec "$ld" "${passthrough_args[@]}" ;; esac shift From ddddb028ee2b154b56684d56501bea2fcf32f884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Marc=CC=A7al?= Date: Tue, 11 Mar 2025 19:08:19 -0300 Subject: [PATCH 2/3] Update test fixtures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lucas Marçal --- .../xcshareddata/xcschemes/AppClip.xcscheme | 2 +- .../xcshareddata/xcschemes/BasicTests.xcscheme | 2 +- .../xcschemes/CommandLineTool.xcscheme | 2 +- .../xcschemes/CommandLineToolTests.xcscheme | 2 +- .../xcschemes/ExtensionKitExtension.xcscheme | 2 +- .../UniversalCommandLineTool (arm64).xcscheme | 2 +- .../UniversalCommandLineTool (x86_64).xcscheme | 2 +- .../xcschemes/WidgetExtension.xcscheme | 2 +- .../xcshareddata/xcschemes/echo_client.xcscheme | 2 +- .../xcshareddata/xcschemes/echo_server.xcscheme | 2 +- .../xcschemes/iMessageAppExtension.xcscheme | 2 +- .../xcshareddata/xcschemes/iOSApp.xcscheme | 2 +- .../xcschemes/iOSAppObjCUnitTestSuite.xcscheme | 2 +- .../xcschemes/iOSAppObjCUnitTests.xcscheme | 2 +- .../xcschemes/iOSAppSwiftUnitTestSuite.xcscheme | 2 +- .../xcschemes/iOSAppSwiftUnitTests.xcscheme | 2 +- .../xcschemes/iOSAppSwiftUnitTests_Scheme.xcscheme | 2 +- .../xcschemes/iOSAppUITestSuite.xcscheme | 2 +- .../xcshareddata/xcschemes/iOSAppUITests.xcscheme | 2 +- ...ppUnitTestSuite_CommandLineArgs_Scheme.xcscheme | 2 +- .../xcschemes/iOSAppUnitTests_Scheme.xcscheme | 2 +- .../xcshareddata/xcschemes/macOSApp.xcscheme | 2 +- .../xcschemes/macOSAppUITests.xcscheme | 2 +- .../xcshareddata/xcschemes/proto.xcscheme | 2 +- .../xcshareddata/xcschemes/tool.xcscheme | 2 +- .../xcshareddata/xcschemes/tvOSApp.xcscheme | 2 +- .../xcshareddata/xcschemes/tvOSAppUITests.xcscheme | 2 +- .../xcschemes/tvOSAppUnitTests.xcscheme | 2 +- .../xcshareddata/xcschemes/watchOSApp.xcscheme | 2 +- .../watchOSAppExtensionUnitTests.xcscheme | 2 +- .../xcschemes/watchOSAppUITests.xcscheme | 2 +- .../WidgetExtension (App Extension).xcscheme | 2 +- .../xcshareddata/xcschemes/iOSApp (App).xcscheme | 2 +- .../iOSAppMixedUnitTests (Unit Tests).xcscheme | 2 +- .../xcschemes/iOSAppObjCUnitTestSuite.xcscheme | 2 +- .../iOSAppObjCUnitTestSuite_macro.xcscheme | 2 +- .../xcschemes/iOSAppObjCUnitTests_macro.xcscheme | 2 +- .../xcschemes/iOSAppSwiftUnitTestSuite.xcscheme | 2 +- .../xcschemes/iOSAppSwiftUnitTests.xcscheme | 2 +- .../xcschemes/iOSAppUITestSuite.xcscheme | 2 +- .../xcschemes/iOSAppUITestSuite_macro.xcscheme | 2 +- .../xcschemes/iOSAppUITests_macro.xcscheme | 2 +- .../xcschemes/iOS_App_ObjC_UnitTests.xcscheme | 2 +- ..._ObjC_UnitTests_macro_with_bundle_name.xcscheme | 2 +- .../rules_ios/test/fixtures/bwb_targets_spec.json | 14 +++++++------- .../xcschemes/src/Generator/CreateScheme.swift | 2 +- 46 files changed, 52 insertions(+), 52 deletions(-) diff --git a/examples/integration/test/fixtures/bwb.xcodeproj/xcshareddata/xcschemes/AppClip.xcscheme b/examples/integration/test/fixtures/bwb.xcodeproj/xcshareddata/xcschemes/AppClip.xcscheme index 53ac61bebf..e449485c1e 100644 --- a/examples/integration/test/fixtures/bwb.xcodeproj/xcshareddata/xcschemes/AppClip.xcscheme +++ b/examples/integration/test/fixtures/bwb.xcodeproj/xcshareddata/xcschemes/AppClip.xcscheme @@ -26,7 +26,7 @@ ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> + scriptText = "mkdir -p "$PROJECT_DIR" if [[ "${ENABLE_ADDRESS_SANITIZER:-}" == "YES" || \ "${ENABLE_THREAD_SANITIZER:-}" == "YES" || \ "${ENABLE_UNDEFINED_BEHAVIOR_SANITIZER:-}" == "YES" ]] then cd "$INTERNAL_DIR" || exit 1 if [[ -n "${TOOLCHAIN_DIR:-}" ]]; then ln -shfF "$TOOLCHAIN_DIR/usr/lib" lib else ln -shfF "$DEVELOPER_DIR/Toolchains/XcodeDefault.xctoolchain/usr/lib" lib fi fi"> Date: Tue, 11 Mar 2025 19:16:36 -0300 Subject: [PATCH 3/3] Add swiftcPath variable in the swiftc stub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Lucas Marçal --- tools/swiftc_stub/main.swift | 94 ++++++++++++------------------------ 1 file changed, 32 insertions(+), 62 deletions(-) diff --git a/tools/swiftc_stub/main.swift b/tools/swiftc_stub/main.swift index 680515cc6b..6a81931c1b 100644 --- a/tools/swiftc_stub/main.swift +++ b/tools/swiftc_stub/main.swift @@ -62,6 +62,38 @@ func processArgs( ) } +let swiftcPath: String = { + guard let path = ProcessInfo.processInfo.environment["PATH"] else { + fputs("error: PATH not set", stderr) + exit(1) + } + + var result: String? + + if let toolchainDir = ProcessInfo.processInfo.environment["TOOLCHAIN_DIR"] { + result = "\(toolchainDir)/usr/bin/swiftc" + } else { + // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin + let pathComponents = path.split(separator: ":", maxSplits: 1) + let xcodeBinPath = pathComponents[0] + guard xcodeBinPath.hasSuffix("/Contents/Developer/usr/bin") else { + fputs("Xcode based bin PATH not set \(path)", stderr) + fputs("error: Xcode based bin PATH not set", stderr) + exit(1) + } + // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer + let developerDir = xcodeBinPath.dropLast(8) + result = "\(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc" + } + + guard let result else { + fputs("error: Failed to determine swiftc path", stderr) + exit(1) + } + + return result +}() + extension URL { mutating func touch() throws { let fileManager = FileManager.default @@ -138,37 +170,6 @@ func runSubProcess(executable: String, args: [String]) throws -> Int32 { } func handleXcodePreviewThunk(args: [String], paths: [PathKey: URL]) throws -> Never { - var swiftcPath: String? - - if let toolchainDir = ProcessInfo.processInfo.environment["TOOLCHAIN_DIR"] { - swiftcPath = "\(toolchainDir)/usr/bin/swiftc" - } else { - guard let sdkPath = paths[PathKey.sdk]?.path else { - fputs("error: No such argument '-sdk'. Using /usr/bin/swiftc.", stderr) - exit(1) - } - - // We could produce this file at the start of the build? - let fullRange = NSRange(sdkPath.startIndex..., in: sdkPath) - let matches = try NSRegularExpression( - pattern: #"(.*?/Contents/Developer)/.*"# - ).matches(in: sdkPath, range: fullRange) - guard let match = matches.first, - let range = Range(match.range(at: 1), in: sdkPath) - else { - fputs("error: Failed to parse DEVELOPER_DIR from '-sdk'. Using /usr/bin/swiftc.", stderr) - exit(1) - } - let developerDir = sdkPath[range] - - swiftcPath = "\(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc" - } - - guard let swiftcPath else { - fputs("error: Failed to determine swiftc path", stderr) - exit(1) - } - try exit(runSubProcess(executable: swiftcPath, args: Array(args.dropFirst()))) } @@ -177,37 +178,6 @@ func handleXcodePreviewThunk(args: [String], paths: [PathKey: URL]) throws -> Ne let args = CommandLine.arguments // Xcode 16.0 Beta 3 began using "--version" over "-v". Support both. if args.count == 2, args.last == "--version" || args.last == "-v" { - guard let path = ProcessInfo.processInfo.environment["PATH"] else { - fputs("error: PATH not set", stderr) - exit(1) - } - - var swiftcPath: String? - - if let toolchainDir = ProcessInfo.processInfo.environment["TOOLCHAIN_DIR"] { - swiftcPath = """ - \(toolchainDir)/usr/bin/swiftc - """ - } else { - // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin - let pathComponents = path.split(separator: ":", maxSplits: 1) - let xcodeBinPath = pathComponents[0] - guard xcodeBinPath.hasSuffix("/Contents/Developer/usr/bin") else { - fputs("error: Xcode based bin PATH not set", stderr) - exit(1) - } - // /Applications/Xcode-15.0.0-Beta.app/Contents/Developer/usr/bin -> /Applications/Xcode-15.0.0-Beta.app/Contents/Developer - let developerDir = xcodeBinPath.dropLast(8) - swiftcPath = """ - \(developerDir)/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc - """ - } - - guard let swiftcPath else { - fputs("error: Failed to determine swiftc path", stderr) - exit(1) - } - // args.last allows passing in -v (Xcode < 16b3) and --version (>= 16b3) try exit(runSubProcess(executable: swiftcPath, args: [args.last!])) }