Skip to content

Commit 3ceb6ef

Browse files
authored
use -print-target-info to get swift library paths reliably (#178)
1 parent 867128b commit 3ceb6ef

File tree

5 files changed

+75
-42
lines changed

5 files changed

+75
-42
lines changed

.licenseignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,4 @@ gradlew.bat
4040
**/gradlew
4141
**/gradlew.bat
4242
**/ci-validate.sh
43+
**/DO_NOT_EDIT.txt

BuildLogic/build.gradle.kts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414

1515
repositories {
1616
gradlePluginPortal()
17+
mavenCentral()
18+
}
19+
20+
dependencies {
21+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.3")
1722
}
1823

1924
plugins {

BuildLogic/src/main/kotlin/build-logic.java-common-conventions.gradle.kts

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import java.util.*
1616
import java.io.*
17+
import kotlin.system.exitProcess
18+
import kotlinx.serialization.json.*
1719

1820
plugins {
1921
java
@@ -44,41 +46,60 @@ tasks.withType(JavaCompile::class).forEach {
4446
}
4547

4648

47-
// FIXME: cannot share definition with 'buildSrc' so we duplicated the impl here
48-
fun javaLibraryPaths(dir: File): List<String> {
49-
val osName = System.getProperty("os.name")
49+
fun getSwiftRuntimeLibraryPaths(): List<String> {
50+
val process = ProcessBuilder("swiftc", "-print-target-info")
51+
.redirectError(ProcessBuilder.Redirect.INHERIT)
52+
.start()
53+
54+
val output = process.inputStream.bufferedReader().use { it.readText() }
55+
val exitCode = process.waitFor()
56+
if (exitCode != 0) {
57+
System.err.println("Error executing swiftc -print-target-info")
58+
exitProcess(exitCode)
59+
}
60+
61+
val json = Json.parseToJsonElement(output)
62+
val runtimeLibraryPaths = json.jsonObject["paths"]?.jsonObject?.get("runtimeLibraryPaths")?.jsonArray
63+
return runtimeLibraryPaths?.map { it.jsonPrimitive.content } ?: emptyList()
64+
}
65+
66+
/**
67+
* Find library paths for 'java.library.path' when running or testing projects inside this build.
68+
*/
69+
// TODO: can't figure out how to share this code between BuildLogic/ and buildSrc/
70+
fun javaLibraryPaths(rootDir: File): List<String> {
71+
val osName = System.getProperty("os.name").lowercase(Locale.getDefault())
5072
val osArch = System.getProperty("os.arch")
51-
val isLinux = osName.lowercase(Locale.getDefault()).contains("linux")
73+
val isLinux = osName.contains("linux")
74+
val base = rootDir.path.let { "$it/" }
5275

53-
return listOf(
54-
if (isLinux) {
55-
if (osArch.equals("x86_64") || osArch.equals("amd64")) {
56-
"$dir/.build/x86_64-unknown-linux-gnu/debug/"
57-
} else {
58-
"$dir/.build/$osArch-unknown-linux-gnu/debug/"
59-
}
60-
} else {
61-
if (osArch.equals("aarch64")) {
62-
"$dir/.build/arm64-apple-macosx/debug/"
63-
} else {
64-
"$dir/.build/$osArch-apple-macosx/debug/"
65-
}
66-
},
76+
val projectBuildOutputPath =
6777
if (isLinux) {
68-
"/usr/lib/swift/linux"
78+
if (osArch == "amd64" || osArch == "x86_64")
79+
"$base.build/x86_64-unknown-linux-gnu"
80+
else
81+
"$base.build/${osArch}-unknown-linux-gnu"
6982
} else {
70-
// assume macOS
71-
"/usr/lib/swift/"
72-
},
73-
if (isLinux) {
74-
System.getProperty("user.home") + "/.local/share/swiftly/toolchains/6.0.2/usr/lib/swift/linux"
75-
} else {
76-
// assume macOS
77-
"/usr/lib/swift/"
83+
if (osArch == "aarch64")
84+
"$base.build/arm64-apple-macosx"
85+
else
86+
"$base.build/${osArch}-apple-macosx"
7887
}
88+
val parentParentBuildOutputPath =
89+
"../../$projectBuildOutputPath"
90+
91+
92+
val swiftBuildOutputPaths = listOf(
93+
projectBuildOutputPath,
94+
parentParentBuildOutputPath
7995
)
80-
}
8196

97+
val debugBuildOutputPaths = swiftBuildOutputPaths.map { "$it/debug" }
98+
val releaseBuildOutputPaths = swiftBuildOutputPaths.map { "$it/release" }
99+
val swiftRuntimePaths = getSwiftRuntimeLibraryPaths()
100+
101+
return debugBuildOutputPaths + releaseBuildOutputPaths + swiftRuntimePaths
102+
}
82103

83104
// Configure paths for native (Swift) libraries
84105
tasks.test {

buildSrc/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ repositories {
1616
mavenCentral()
1717
}
1818

19+
dependencies {
20+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.7.3")
21+
}
22+
1923
def cleanSwift = tasks.register("cleanSwift", Exec) {
2024
workingDir = layout.projectDirectory
2125
commandLine "swift"

buildSrc/src/main/groovy/org/swift/swiftkit/gradle/BuildUtils.groovy

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,21 @@
1414

1515
package org.swift.swiftkit.gradle
1616

17+
import groovy.json.JsonSlurper
18+
1719
final class BuildUtils {
1820

21+
static List<String> getSwiftRuntimeLibraryPaths() {
22+
def process = ['swiftc', '-print-target-info'].execute()
23+
def output = new StringWriter()
24+
process.consumeProcessOutput(output, System.err)
25+
process.waitFor()
26+
27+
def json = new JsonSlurper().parseText(output.toString())
28+
def runtimeLibraryPaths = json.paths.runtimeLibraryPaths
29+
return runtimeLibraryPaths
30+
}
31+
1932
/// Find library paths for 'java.library.path' when running or testing projects inside this build.
2033
static def javaLibraryPaths(File rootDir) {
2134
def osName = System.getProperty("os.name")
@@ -40,19 +53,8 @@ final class BuildUtils {
4053
"${base}../../.build/${osArch}-apple-macosx/debug/"),
4154
]
4255
def releasePaths = debugPaths.collect { it.replaceAll("debug", "release") }
43-
def systemPaths =
44-
// system paths
45-
isLinux ?
46-
[
47-
"/usr/lib/swift/linux",
48-
// TODO: should we be Swiftly aware and then use the currently used path?
49-
System.getProperty("user.home") + "/.local/share/swiftly/toolchains/6.0.2/usr/lib/swift/linux"
50-
] :
51-
[
52-
// assume macOS
53-
"/usr/lib/swift/"
54-
]
55-
56-
return releasePaths + debugPaths + systemPaths
56+
def swiftRuntimePaths = getSwiftRuntimeLibraryPaths()
57+
58+
return releasePaths + debugPaths + swiftRuntimePaths
5759
}
5860
}

0 commit comments

Comments
 (0)