Skip to content

Commit 36c62f8

Browse files
authored
Build and path handling adjustments to handle both old build system and swift-build (#740)
* adjust product name to survive new build system The way we're looking up the swift-java "tool" in plugins uses the target name "SwiftJavaTool" and that is correct in the natrive build system. In swift 6.4, and in Xcode, the swift-build build system is actually naming them using product names: so swift-java. In order to have the build work in BOTH build systems, we have to make the name be the same... It's a workaround, but it seems to work. This should resolve the failure ``` error: Build input file cannot be found: '/Users/ktoso/code/swift-java/Samples/JavaKitSampleApp/.build/out/Products/Debug/SwiftJavaTool'. Did you forget to declare this file as an output of a script phase or custom build rule which produces it? ``` that folks were reporting in #733 and in #281 * forward env to tool uses * include swift-build paths in search paths * more workarounds for nested swift-builds
1 parent 061451d commit 36c62f8

8 files changed

Lines changed: 83 additions & 17 deletions

File tree

.github/workflows/pull_request.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ jobs:
4444
test-java:
4545
name: Test (Java) (${{ matrix.os_version }} swift:${{ matrix.swift_version }} jdk:${{matrix.jdk_vendor}})
4646
runs-on: ubuntu-latest
47+
# Nightly builds are best-effort
48+
continue-on-error: ${{ contains(matrix.swift_version, 'nightly') }}
4749
strategy:
4850
fail-fast: true
4951
matrix:
50-
swift_version: ['6.2', '6.3'] # FIXME: reenable 'nightly' once snapshot toolchains are stable again
52+
swift_version: ['6.2', '6.3', 'nightly']
5153
os_version: ['jammy']
5254
jdk_vendor: ['corretto']
5355
container:
@@ -136,10 +138,12 @@ jobs:
136138
test-swift:
137139
name: Test (Swift) (${{ matrix.os_version }} swift:${{ matrix.swift_version }} jdk:${{matrix.jdk_vendor}})
138140
runs-on: ubuntu-latest
141+
# Nightly builds are best-effort
142+
continue-on-error: ${{ contains(matrix.swift_version, 'nightly') }}
139143
strategy:
140144
fail-fast: false
141145
matrix:
142-
swift_version: ['6.1.3', '6.2', '6.3'] # FIXME: reenable 'nightly' once snapshot toolchains are stable again
146+
swift_version: ['6.1.3', '6.2', '6.3', 'nightly']
143147
os_version: ['jammy']
144148
jdk_vendor: ['corretto']
145149
container:
@@ -186,10 +190,12 @@ jobs:
186190
build-swift-android:
187191
name: Sample SwiftJavaExtractJNISampleApp (Android) (swift:${{ matrix.swift_version }} android:${{matrix.sdk_triple}} NDK:${{matrix.ndk_version}})
188192
runs-on: ubuntu-22.04
193+
# Nightly builds are best-effort
194+
continue-on-error: ${{ contains(matrix.swift_version, 'nightly') }}
189195
strategy:
190196
fail-fast: false
191197
matrix:
192-
swift_version: ['nightly-6.3'] # FIXME: reenable 'nightly-main' once snapshot toolchains are stable again
198+
swift_version: ['6.3']
193199
os_version: ['jammy']
194200
jdk_vendor: ['corretto']
195201
sdk_triple: ['aarch64-unknown-linux-android28', 'x86_64-unknown-linux-android28', 'armv7-unknown-linux-android28']
@@ -210,10 +216,12 @@ jobs:
210216
verify-samples:
211217
name: Sample ${{ matrix.sample_app }} (${{ matrix.os_version }} swift:${{ matrix.swift_version }} jdk:${{matrix.jdk_vendor}})
212218
runs-on: ubuntu-latest
219+
# Nightly builds are best-effort
220+
continue-on-error: ${{ contains(matrix.swift_version, 'nightly') }}
213221
strategy:
214222
fail-fast: false
215223
matrix:
216-
swift_version: ['6.1.3', '6.2', '6.3'] # FIXME: reenable 'nightly' once snapshot toolchains are stable again
224+
swift_version: ['6.1.3', '6.2', '6.3', 'nightly']
217225
os_version: ['jammy']
218226
jdk_vendor: ['corretto']
219227
sample_app: [ # TODO: use a reusable-workflow to generate those names

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,23 @@ fun javaLibraryPaths(rootDir: File): List<String> {
8181

8282
val debugBuildOutputPaths = swiftBuildOutputPaths.map { "$it/debug" }
8383
val releaseBuildOutputPaths = swiftBuildOutputPaths.map { "$it/release" }
84+
85+
// swift-build layout (https://github.com/swiftlang/swift-build/issues/1363):
86+
// .build/out/Products/<Config>[-<os>]/ — no triple, different config casing,
87+
// OS suffix on Linux
88+
val swiftBuildSystemConfigs = if (isLinux) {
89+
listOf("Debug-linux", "Release-linux")
90+
} else {
91+
listOf("Debug", "Release")
92+
}
93+
val swiftBuildSystemRoots = listOf("$base.build/out/Products", "../../$base.build/out/Products")
94+
val swiftBuildSystemPaths = swiftBuildSystemRoots.flatMap { root ->
95+
swiftBuildSystemConfigs.map { config -> "$root/$config" }
96+
}
97+
8498
val swiftRuntimePaths = getSwiftRuntimeLibraryPaths()
8599

86-
return debugBuildOutputPaths + releaseBuildOutputPaths + swiftRuntimePaths
100+
return debugBuildOutputPaths + releaseBuildOutputPaths + swiftBuildSystemPaths + swiftRuntimePaths
87101
}
88102

89103
// Configure paths for native (Swift) libraries

BuildLogic/src/main/kotlin/utilities/javaLibraryPaths.kt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,22 @@ fun Project.javaLibraryPaths(rootDir: File?): List<String> {
4444
"${arch}-apple-macosx"
4545
}
4646

47-
val paths: List<String> = listOf("release", "debug").map { configuration ->
47+
// Native build system: .build/<triple>/<config>/
48+
val nativeBuildPaths: List<String> = listOf("release", "debug").map { configuration ->
4849
"${base}.build/${triple}/$configuration/"
4950
}
51+
52+
// swift-build: .build/out/Products/<Config>[-<os>]/
53+
val swiftBuildConfigs = if (isLinux) {
54+
listOf("Debug-linux", "Release-linux")
55+
} else {
56+
listOf("Debug", "Release")
57+
}
58+
val swiftBuildPaths: List<String> = swiftBuildConfigs.map { config ->
59+
"${base}.build/out/Products/$config/"
60+
}
61+
5062
val swiftRuntimePaths = swiftRuntimeLibraryPaths()
5163

52-
return paths + swiftRuntimePaths
64+
return nativeBuildPaths + swiftBuildPaths + swiftRuntimePaths
5365
}

Package.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ let package = Package(
6161

6262
.executable(
6363
name: "swift-java",
64-
targets: ["SwiftJavaTool"]
64+
targets: ["swift-java"]
6565
),
6666

6767
.library(
@@ -224,7 +224,7 @@ let package = Package(
224224
name: "SwiftJavaPlugin",
225225
capability: .buildTool(),
226226
dependencies: [
227-
"SwiftJavaTool"
227+
"swift-java"
228228
]
229229
),
230230

@@ -289,7 +289,7 @@ let package = Package(
289289
),
290290

291291
.executableTarget(
292-
name: "SwiftJavaTool",
292+
name: "swift-java",
293293
dependencies: [
294294
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
295295
.product(name: "SwiftSyntax", package: "swift-syntax"),
@@ -304,6 +304,10 @@ let package = Package(
304304
"SwiftJavaShared",
305305
"SwiftJavaConfigurationShared",
306306
],
307+
// Keep existing directory name while the target is renamed; see
308+
// https://github.com/swiftlang/swift-java/issues/733 for why the
309+
// target name must match the product name.
310+
path: "Sources/SwiftJavaTool",
307311
swiftSettings: [
308312
.swiftLanguageMode(.v5),
309313
.enableUpcomingFeature("BareSlashRegexLiterals"),
@@ -362,7 +366,7 @@ let package = Package(
362366
name: "JExtractSwiftPlugin",
363367
capability: .buildTool(),
364368
dependencies: [
365-
"SwiftJavaTool"
369+
"swift-java"
366370
]
367371
),
368372

Plugins/JExtractSwiftPlugin/JExtractSwiftPlugin.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
2929
var verbose: Bool = getEnvironmentBool("SWIFT_JAVA_VERBOSE")
3030

3131
func createBuildCommands(context: PluginContext, target: Target) throws -> [Command] {
32-
let toolURL = try context.tool(named: "SwiftJavaTool").url
32+
let toolURL = try context.tool(named: "swift-java").url
3333

3434
var commands: [Command] = []
3535

@@ -171,6 +171,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
171171
displayName: "Generate Java wrappers for Swift types",
172172
executable: toolURL,
173173
arguments: arguments,
174+
environment: ProcessInfo.processInfo.environment,
174175
inputFiles: [configFile] + swiftFiles,
175176
outputFiles: jextractOutputFiles,
176177
)
@@ -203,9 +204,8 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
203204
let GradleUserHome = "GRADLE_USER_HOME"
204205
let gradleUserHomePath = gradleUserHome.path(percentEncoded: false)
205206
log("Prepare command: :SwiftKitCore:build in \(GradleUserHome)=\(gradleUserHomePath)")
206-
var gradlewEnvironment = ProcessInfo.processInfo.environment
207-
gradlewEnvironment[GradleUserHome] = gradleUserHomePath
208-
log("Forward environment: \(gradlewEnvironment)")
207+
var environment = ProcessInfo.processInfo.environment
208+
environment[GradleUserHome] = gradleUserHomePath
209209

210210
let gradlewURL = swiftJavaDirectory.appending(path: "gradlew")
211211
let gradleExecutable: URL
@@ -256,6 +256,7 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
256256
displayName: "Build SwiftKitCore, compile Java callbacks, and generate Swift wrappers",
257257
executable: toolURL,
258258
arguments: javaCallbacksArguments,
259+
environment: environment,
259260
inputFiles: outputSwiftFiles + [swiftJavaDirectory],
260261
outputFiles: [javaCallbacksSwiftOutput],
261262
)

Plugins/SwiftJavaPlugin/SwiftJavaPlugin.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
3131
log("Create build commands for target '\(target.name)'")
3232
guard let sourceModule = target.sourceModule else { return [] }
3333

34-
let executable = try context.tool(named: "SwiftJavaTool").url
34+
let executable = try context.tool(named: "swift-java").url
3535
var commands: [Command] = []
3636

3737
// Note: Target doesn't have a directoryURL counterpart to directory,
@@ -165,7 +165,7 @@ struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
165165
arguments: ["resolve"]
166166
+ argumentsOutputDirectory(context: context, generated: false)
167167
+ argumentsSwiftModule(sourceModule: sourceModule),
168-
environment: [:],
168+
environment: ProcessInfo.processInfo.environment,
169169
inputFiles: [configFile],
170170
outputFiles: fetchDependenciesOutputFiles
171171
)
@@ -192,6 +192,7 @@ struct SwiftJavaBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
192192
executable: executable,
193193
arguments: ["wrap-java"]
194194
+ arguments,
195+
environment: ProcessInfo.processInfo.environment,
195196
inputFiles: compiledClassFiles + fetchDependenciesOutputFiles + [configFile],
196197
outputFiles: outputSwiftFiles
197198
)

SwiftKitCore/build.gradle.kts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ val compileSwift = tasks.register<Exec>("compileSwift") {
8686
commandLine("swift")
8787
// FIXME: disable prebuilts until swift-syntax isn't broken on 6.2 anymore: https://github.com/swiftlang/swift-java/issues/418
8888
args("build", "--disable-experimental-prebuilts", "--target", "SwiftRuntimeFunctions")
89+
90+
// When this task runs inside an outer swift-build-driven invocation (e.g.
91+
// JExtractSwiftPlugin -> java-callbacks-build -> gradle -> here) the outer
92+
// build leaks Xcode-style build settings (SDKROOT=/, TOOLCHAINS, SDK_*,
93+
// SWIFTC_PASS_*) into the subprocess environment, which breaks the nested
94+
// swift build with "unable to resolve run destination SDK: '/'". Strip
95+
// them so the inner invocation resolves its own defaults.
96+
listOf(
97+
"SDKROOT", "SDK_DIR", "SDK_DIR_linux", "SDK_NAME", "SDK_NAMES",
98+
"SDK_VERSION", "SDK_VERSION_ACTUAL", "SDK_VERSION_MAJOR", "SDK_VERSION_MINOR",
99+
"SDK_STAT_CACHE_DIR", "SDK_STAT_CACHE_ENABLE", "SDK_STAT_CACHE_PATH",
100+
"SWIFTC_PASS_SDKROOT", "SWIFTC_PASS_SYSROOT", "TOOLCHAINS",
101+
).forEach { environment.remove(it) }
89102
}
90103
tasks.build {
91104
dependsOn(compileSwift)

SwiftKitFFM/build.gradle.kts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ val compileSwift = tasks.register<Exec>("compileSwift") {
8989
commandLine("swift")
9090
// FIXME: disable prebuilts until swift-syntax isn't broken on 6.2 anymore: https://github.com/swiftlang/swift-java/issues/418
9191
args("build", "--disable-experimental-prebuilts", "--target", "SwiftRuntimeFunctions")
92+
93+
// When this task runs inside an outer swift-build-driven invocation (e.g.
94+
// JExtractSwiftPlugin -> java-callbacks-build -> gradle -> here) the outer
95+
// build leaks Xcode-style build settings (SDKROOT=/, TOOLCHAINS, SDK_*,
96+
// SWIFTC_PASS_*) into the subprocess environment, which breaks the nested
97+
// swift build with "unable to resolve run destination SDK: '/'". Strip
98+
// them so the inner invocation resolves its own defaults.
99+
listOf(
100+
"SDKROOT", "SDK_DIR", "SDK_DIR_linux", "SDK_NAME", "SDK_NAMES",
101+
"SDK_VERSION", "SDK_VERSION_ACTUAL", "SDK_VERSION_MAJOR", "SDK_VERSION_MINOR",
102+
"SDK_STAT_CACHE_DIR", "SDK_STAT_CACHE_ENABLE", "SDK_STAT_CACHE_PATH",
103+
"SWIFTC_PASS_SDKROOT", "SWIFTC_PASS_SYSROOT", "TOOLCHAINS",
104+
).forEach { environment.remove(it) }
92105
}
93106
tasks.build {
94107
dependsOn(compileSwift)

0 commit comments

Comments
 (0)