Skip to content

Commit 1e03891

Browse files
committed
gradle build now causes proper emission of the swift/java sources
1 parent 95e56ef commit 1e03891

File tree

17 files changed

+123
-63
lines changed

17 files changed

+123
-63
lines changed

Plugins/JExtractSwiftCommandPlugin/JExtractSwiftCommandPlugin.swift

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
2020

2121
var verbose: Bool = false
2222

23+
/// Build the target before attempting to extract from it.
24+
/// This avoids trying to extract from broken sources.
25+
///
26+
/// You may disable this if confident that input targets sources are correct and there's no need to kick off a pre-build for some reason.
27+
var buildInputs: Bool = true
28+
29+
/// Build the target once swift-java sources have been generated.
30+
/// This helps verify that the generated output is correct, and won't miscompile on the next build.
31+
var buildOutputs: Bool = true
32+
2333
func createBuildCommands(context: PackagePlugin.PluginContext, target: any PackagePlugin.Target) async throws -> [PackagePlugin.Command] {
2434
// FIXME: This is not a build plugin but SwiftPM forces us to impleme the protocol anyway? rdar://139556637
2535
return []
@@ -37,7 +47,7 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
3747
}
3848

3949
for target in context.package.targets {
40-
guard hasSwiftJavaConfig(target: target) else {
50+
guard let configPath = getSwiftJavaConfig(target: target) else {
4151
log("Skipping target '\(target.name), has no 'swift-java.config' file")
4252
continue
4353
}
@@ -58,6 +68,16 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
5868

5969
guard let sourceModule = target.sourceModule else { return }
6070

71+
if self.buildInputs {
72+
log("Pre-building target '\(target.name)' before extracting sources...")
73+
try self.packageManager.build(.target(target.name), parameters: .init())
74+
}
75+
76+
if self.buildOutputs {
77+
log("Post-building target '\(target.name)' to verify generated sources...")
78+
try self.packageManager.build(.target(target.name), parameters: .init())
79+
}
80+
6181
// Note: Target doesn't have a directoryURL counterpart to directory,
6282
// so we cannot eliminate this deprecation warning.
6383
let sourceDir = target.directory.string
@@ -87,8 +107,6 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
87107
]
88108
arguments.append(sourceDir)
89109

90-
print("PLUGIN: jextract \(arguments.joined(separator: " "))")
91-
92110
try runExtract(context: context, target: target, arguments: arguments)
93111
}
94112

@@ -98,6 +116,8 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
98116
process.arguments = arguments
99117

100118
do {
119+
log("Execute: \(process.executableURL) \(arguments)")
120+
101121
try process.run()
102122
process.waitUntilExit()
103123

@@ -107,7 +127,7 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
107127
}
108128
}
109129

110-
func log(message: @autoclosure () -> String) {
130+
func log(_ message: @autoclosure () -> String) {
111131
if self.verbose {
112132
print("[swift-java] \(message())")
113133
}

Plugins/JExtractSwiftCommandPlugin/PluginsShared/Configuration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct Configuration: Codable {
2121
}
2222

2323
func readConfiguration(sourceDir: String) throws -> Configuration {
24-
let configFile = URL(filePath: sourceDir).appending(path: "JExtractSwift.config")
24+
let configFile = URL(filePath: sourceDir).appending(path: "swift-java.config")
2525
do {
2626
let configData = try Data(contentsOf: configFile)
2727
return try JSONDecoder().decode(Configuration.self, from: configData)

Plugins/JExtractSwiftCommandPlugin/PluginsShared/PluginUtils.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,27 @@ func findJavaHome() -> String {
2222
if let home = ProcessInfo.processInfo.environment["JAVA_HOME"] {
2323
return home
2424
}
25-
25+
2626
// This is a workaround for envs (some IDEs) which have trouble with
2727
// picking up env variables during the build process
2828
let path = "\(FileManager.default.homeDirectoryForCurrentUser.path()).java_home"
2929
if let home = try? String(contentsOfFile: path, encoding: .utf8) {
3030
if let lastChar = home.last, lastChar.isNewline {
3131
return String(home.dropLast())
3232
}
33-
33+
3434
return home
3535
}
36-
36+
3737
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
3838
}
3939

40-
func hasSwiftJavaConfig(target: Target) -> Bool {
41-
target.directory
40+
func getSwiftJavaConfig(target: Target) -> String? {
41+
let configPath = URL(fileURLWithPath: target.directory.string).appending(component: "swift-java.config").path()
42+
43+
if FileManager.default.fileExists(atPath: configPath) {
44+
return configPath
45+
} else {
46+
return nil
47+
}
4248
}

Plugins/JExtractSwiftPlugin/PluginsShared/Configuration.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct Configuration: Codable {
2121
}
2222

2323
func readConfiguration(sourceDir: String) throws -> Configuration {
24-
let configFile = URL(filePath: sourceDir).appending(path: "JExtractSwift.config")
24+
let configFile = URL(filePath: sourceDir).appending(path: "swift-java.config")
2525
do {
2626
let configData = try Data(contentsOf: configFile)
2727
return try JSONDecoder().decode(Configuration.self, from: configData)

Samples/JExtractPluginSampleApp/build.gradle

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def buildJExtractPlugin = tasks.register("swiftBuildJExtractPlugin", Exec) {
4949
args "build"
5050
}
5151

52-
def buildSwift = tasks.register("swiftBuildProject", Exec) {
52+
def jextract = tasks.register("jextract", Exec) {
5353
description = "Builds swift sources, including swift-java source generation"
5454
dependsOn buildJExtractPlugin
5555

@@ -76,14 +76,14 @@ def buildSwift = tasks.register("swiftBuildProject", Exec) {
7676

7777
workingDir = layout.projectDirectory
7878
commandLine "swift"
79-
args "build"
79+
args("package", "jextract")
8080
}
8181

8282
// Add the java-swift generated Java sources
8383
sourceSets {
8484
main {
8585
java {
86-
srcDir(buildSwift)
86+
srcDir(jextract)
8787
}
8888
}
8989
}

Samples/JExtractPluginSampleApp/src/main/java/com/example/swift/JExtractPluginSampleMain.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ public static void main(String[] args) {
2222
System.out.println("java.library.path = " + SwiftKit.getJavaLibraryPath());
2323
System.out.println("jextract.trace.downcalls = " + SwiftKit.getJextractTraceDowncalls());
2424

25-
var o = new MyCoolSwiftClass(12);
26-
o.exposedToJava();
25+
try {
26+
var o = new MyCoolSwiftClass(12);
27+
o.exposedToJava();
28+
} catch (UnsatisfiedLinkError linkError) {
29+
if (linkError.getMessage().startsWith("unresolved symbol: ")) {
30+
var unresolvedSymbolName = linkError.getMessage().substring("unresolved symbol: ".length());
31+
32+
33+
}
34+
}
2735
}
2836
}

Samples/SwiftKitSampleApp/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def buildSwift = tasks.register("swiftBuildProject", Exec) {
7575

7676
workingDir = layout.projectDirectory
7777
commandLine "swift"
78-
args "build"
78+
args ["package", "jextract"]
7979
}
8080

8181
// Add the java-swift generated Java sources

Sources/JExtractSwift/CodePrinter.swift

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ public struct CodePrinter {
4040
return printer.finalize()
4141
}
4242

43-
var ioMode: PrintMode
43+
var mode: PrintMode
4444
public enum PrintMode {
4545
case accumulateAll
4646
case flushToFileOnWrite
4747
}
48-
public init(io: PrintMode = .flushToFileOnWrite) {
49-
self.ioMode = .accumulateAll
48+
public init(mode: PrintMode = .flushToFileOnWrite) {
49+
self.mode = mode
5050
}
5151

5252
internal mutating func append(_ text: String) {
@@ -208,16 +208,18 @@ public enum PrinterTerminator: String {
208208
}
209209

210210
extension CodePrinter {
211+
212+
/// - Returns: the output path of the generated file, if any (i.e. not in accumulate in memory mode)
211213
package mutating func writeContents(
212214
outputDirectory: String,
213215
javaPackagePath: String?,
214216
filename: String
215-
) throws {
216-
guard self.ioMode != .accumulateAll else {
217+
) throws -> URL? {
218+
guard self.mode != .accumulateAll else {
217219
// if we're accumulating everything, we don't want to finalize/flush any contents
218220
// let's mark that this is where a write would have happened though:
219221
print("// ^^^^ Contents of: \(outputDirectory)/\(filename)")
220-
return
222+
return nil
221223
}
222224

223225
let contents = finalize()
@@ -231,24 +233,22 @@ extension CodePrinter {
231233
print("// \(filename)")
232234
}
233235
print(contents)
234-
return
236+
return nil
235237
}
236238

237-
let targetDirectory = [outputDirectory, javaPackagePath].compactMap { $0 }.joined(
238-
separator: PATH_SEPARATOR)
239+
let targetDirectory = [outputDirectory, javaPackagePath].compactMap { $0 }.joined(separator: PATH_SEPARATOR)
239240
log.trace("Prepare target directory: \(targetDirectory)")
240241
try FileManager.default.createDirectory(
241242
atPath: targetDirectory, withIntermediateDirectories: true)
242243

243-
let targetFilePath = [javaPackagePath, filename].compactMap { $0 }.joined(
244-
separator: PATH_SEPARATOR)
245-
Swift.print("Writing '\(targetFilePath)'...", terminator: "")
244+
let outputPath = Foundation.URL(fileURLWithPath: targetDirectory).appendingPathComponent(filename)
246245
try contents.write(
247-
to: Foundation.URL(fileURLWithPath: targetDirectory).appendingPathComponent(filename),
246+
to: outputPath,
248247
atomically: true,
249248
encoding: .utf8
250249
)
251-
Swift.print(" done.".green)
250+
251+
return outputPath
252252
}
253253

254-
}
254+
}

Sources/JExtractSwift/Logger.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,14 @@ public struct Logger {
9595
}
9696

9797
extension Logger {
98-
public enum Level: Int, Hashable {
99-
case trace = 0
100-
case debug = 1
101-
case info = 2
102-
case notice = 3
103-
case warning = 4
104-
case error = 5
105-
case critical = 6
98+
public enum Level: String, Hashable {
99+
case trace = "trace"
100+
case debug = "debug"
101+
case info = "info"
102+
case notice = "notice"
103+
case warning = "warning"
104+
case error = "error"
105+
case critical = "critical"
106106
}
107107
}
108108

0 commit comments

Comments
 (0)