Skip to content

Commit 24419b4

Browse files
authored
Merge pull request #581 from artemcm/ArcLiteXcodeFind
Locate "arclite" library relative to the Clang in the active Xcode
2 parents e9f4a0a + 7c991a3 commit 24419b4

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

Sources/SwiftDriver/Jobs/DarwinToolchain+LinkerSupport.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ import TSCUtility
1414
import SwiftOptions
1515

1616
extension DarwinToolchain {
17+
internal func findXcodeClangPath() throws -> AbsolutePath? {
18+
let result = try executor.checkNonZeroExit(
19+
args: "xcrun", "-toolchain", "default", "-f", "clang",
20+
environment: env
21+
).spm_chomp()
22+
23+
return result.isEmpty ? nil : AbsolutePath(result)
24+
}
25+
1726
internal func findXcodeClangLibPath(_ additionalPath: String) throws -> AbsolutePath? {
1827
let path = try getToolPath(.swiftCompiler)
1928
.parentDirectory // 'swift'
@@ -24,7 +33,7 @@ extension DarwinToolchain {
2433

2534
// If we don't have a 'lib/arc/' directory, find the "arclite" library
2635
// relative to the Clang in the active Xcode.
27-
if let clangPath = try? getToolPath(.clang) {
36+
if let clangPath = try? findXcodeClangPath() {
2837
return clangPath
2938
.parentDirectory // 'clang'
3039
.parentDirectory // 'bin'

Sources/SwiftDriver/Toolchains/DarwinToolchain.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,14 @@ import SwiftOptions
165165
targetTriple: Triple,
166166
targetVariantTriple: Triple?,
167167
diagnosticsEngine: DiagnosticsEngine) throws {
168+
// On non-darwin hosts, libArcLite won't be found and a warning will be emitted
169+
// Guard for the sake of tests runnin on all platforms
170+
#if os(macOS)
168171
// Validating arclite library path when link-objc-runtime.
169172
validateLinkObjcRuntimeARCLiteLib(&parsedOptions,
170173
targetTriple: targetTriple,
171174
diagnosticsEngine: diagnosticsEngine)
175+
#endif
172176
// Validating apple platforms deployment targets.
173177
try validateDeploymentTarget(&parsedOptions, targetTriple: targetTriple)
174178
if let targetVariantTriple = targetVariantTriple,

Tests/SwiftDriverTests/SwiftDriverTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,8 @@ final class SwiftDriverTests: XCTestCase {
11321132

11331133
do {
11341134
// static linking
1135+
// Locating relevant libraries is dependent on being a macOS host
1136+
#if os(macOS)
11351137
var driver = try Driver(args: commonArgs + ["-emit-library", "-static", "-L", "/tmp", "-Xlinker", "-w", "-target", "x86_64-apple-macosx10.9", "-lto=llvm-full"], env: env)
11361138
let plannedJobs = try driver.planBuild()
11371139

@@ -1161,6 +1163,7 @@ final class SwiftDriverTests: XCTestCase {
11611163
XCTAssertFalse(cmd.contains("-lto_library"))
11621164
XCTAssertFalse(cmd.contains("-syslibroot"))
11631165
XCTAssertFalse(cmd.contains("-no_objc_category_merging"))
1166+
#endif
11641167
}
11651168

11661169
do {
@@ -1186,12 +1189,15 @@ final class SwiftDriverTests: XCTestCase {
11861189

11871190
do {
11881191
// lto linking
1192+
// Locating relevant libraries is dependent on being a macOS host
1193+
#if os(macOS)
11891194
var driver1 = try Driver(args: commonArgs + ["-emit-executable", "-target", "x86_64-apple-macosx10.15", "-lto=llvm-thin"], env: env)
11901195
let plannedJobs1 = try driver1.planBuild()
11911196
XCTAssertFalse(plannedJobs1.contains(where: { $0.kind == .autolinkExtract }))
11921197
let linkJob1 = plannedJobs1.first(where: { $0.kind == .link })
11931198
XCTAssertTrue(linkJob1?.tool.name.contains("ld"))
11941199
XCTAssertTrue(linkJob1?.commandLine.contains(.flag("-lto_library")))
1200+
#endif
11951201

11961202
var driver2 = try Driver(args: commonArgs + ["-emit-executable", "-target", "x86_64-unknown-linux", "-lto=llvm-thin"], env: env)
11971203
let plannedJobs2 = try driver2.planBuild()
@@ -1436,6 +1442,18 @@ final class SwiftDriverTests: XCTestCase {
14361442
}
14371443
}
14381444

1445+
private func clangPathInActiveXcode() throws -> AbsolutePath? {
1446+
#if !os(macOS)
1447+
return nil
1448+
#endif
1449+
let process = Process(arguments: ["xcrun", "-toolchain", "default", "-f", "clang"])
1450+
try process.launch()
1451+
let result = try process.waitUntilExit()
1452+
guard result.exitStatus == .terminated(code: EXIT_SUCCESS) else { return nil }
1453+
guard let path = String(bytes: try result.output.get(), encoding: .utf8) else { return nil }
1454+
return path.isEmpty ? nil : AbsolutePath(path.spm_chomp())
1455+
}
1456+
14391457
func testCompatibilityLibs() throws {
14401458
var env = ProcessEnv.vars
14411459
env["SWIFT_DRIVER_TESTS_ENABLE_EXEC_PATH_FALLBACK"] = "1"
@@ -1537,6 +1555,30 @@ final class SwiftDriverTests: XCTestCase {
15371555
XCTAssertTrue(cmd.contains(subsequence: [.flag("-force_load"), .path(.absolute(path5_1iOS))]))
15381556
XCTAssertTrue(cmd.contains(subsequence: [.flag("-force_load"), .path(.absolute(pathDynamicReplacementsiOS))]))
15391557
}
1558+
1559+
// libarclite is only relevant on darwin
1560+
#if os(macOS)
1561+
do {
1562+
// Override executive paths and make sure this does not affect the location of the found
1563+
// libarclite
1564+
env["SWIFT_DRIVER_SWIFTC_EXEC"] = "/some/path/swiftc"
1565+
env["SWIFT_DRIVER_CLANG_EXEC"] = "/some/path/clang"
1566+
guard let clangPathInXcode = try? clangPathInActiveXcode() else {
1567+
throw XCTSkip()
1568+
}
1569+
let clangRelativeArcLite = clangPathInXcode.parentDirectory.parentDirectory
1570+
.appending(components: "lib", "arc", "libarclite_macosx.a")
1571+
1572+
var driver = try Driver(args: commonArgs + ["-target", "x86_64-apple-macosx10.9"], env: env)
1573+
let plannedJobs = try driver.planBuild()
1574+
1575+
XCTAssertEqual(3, plannedJobs.count)
1576+
let linkJob = plannedJobs[2]
1577+
XCTAssertEqual(linkJob.kind, .link)
1578+
let cmd = linkJob.commandLine
1579+
XCTAssertTrue(cmd.contains(subsequence: [.flag("-force_load"), .path(.absolute(clangRelativeArcLite))]))
1580+
}
1581+
#endif
15401582
}
15411583
}
15421584

@@ -2341,7 +2383,10 @@ final class SwiftDriverTests: XCTestCase {
23412383
return
23422384
}
23432385
}
2386+
// On non-darwin hosts, libArcLite won't be found and a warning will be emitted
2387+
#if os(macOS)
23442388
try assertNoDriverDiagnostics(args: "swiftc", "-c", "-target", "x86_64-apple-macosx10.14", "-link-objc-runtime", "foo.swift")
2389+
#endif
23452390
}
23462391

23472392
func testProfileArgValidation() throws {
@@ -3445,6 +3490,7 @@ final class SwiftDriverTests: XCTestCase {
34453490
}
34463491

34473492
func testLTOLibraryArg() throws {
3493+
#if os(macOS)
34483494
do {
34493495
var driver = try Driver(args: ["swiftc", "foo.swift", "-lto=llvm-thin", "-target", "x86_64-apple-macos11.0"])
34503496
let plannedJobs = try driver.planBuild()
@@ -3463,6 +3509,7 @@ final class SwiftDriverTests: XCTestCase {
34633509
XCTAssertEqual(plannedJobs.map(\.kind), [.compile, .link])
34643510
XCTAssertFalse(plannedJobs[1].commandLine.contains("-lto_library"))
34653511
}
3512+
#endif
34663513
}
34673514

34683515
func testBCasTopLevelOutput() throws {

0 commit comments

Comments
 (0)