@@ -25,9 +25,16 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
2525
2626 func createBuildCommands( context: PluginContext , target: Target ) throws -> [ Command ] {
2727 let toolURL = try context. tool ( named: " SwiftJavaTool " ) . url
28-
28+
29+ // The URL of the compiled Java sources
30+ let javaClassFileURL = context. pluginWorkDirectoryURL
31+ . appending ( path: " compiled-java-output " )
32+
33+ var commands : [ Command ] = [ ]
34+
2935 guard let sourceModule = target. sourceModule else { return [ ] }
3036
37+
3138 // Note: Target doesn't have a directoryURL counterpart to directory,
3239 // so we cannot eliminate this deprecation warning.
3340 for dependency in target. dependencies {
@@ -123,15 +130,71 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
123130
124131 print ( " [swift-java-plugin] Output swift files: \n - \( outputSwiftFiles. map ( { $0. absoluteString} ) . joined ( separator: " \n - " ) ) " )
125132
126- return [
133+ // Extract list of all sources
134+ let javaSourcesFile = outputJavaDirectory. appending ( path: " sources.txt " )
135+
136+ commands += [
127137 . buildCommand(
128138 displayName: " Generate Java wrappers for Swift types " ,
129139 executable: toolURL,
130140 arguments: arguments,
131141 inputFiles: [ configFile ] + swiftFiles,
132- outputFiles: outputSwiftFiles
142+ outputFiles: outputSwiftFiles + [ javaSourcesFile ]
133143 )
134144 ]
145+
146+ // Build SwiftKitCore and get the classpath
147+ // as the jextracted sources will depend on that
148+
149+ guard let swiftJavaDirectory = findSwiftJavaDirectory ( for: target) else {
150+ // FIXME: Error
151+ fatalError ( )
152+ }
153+ log ( " Found swift-java at \( swiftJavaDirectory) " )
154+
155+ commands += [
156+ . buildCommand(
157+ displayName: " Build SwiftKitCore " ,
158+ executable: swiftJavaDirectory. appending ( path: " gradlew " ) ,
159+ arguments: [
160+ " :SwiftKitCore:build " ,
161+ " -p " , swiftJavaDirectory. path ( percentEncoded: false ) ,
162+ " --configure-on-demand " ,
163+ " --no-daemon "
164+ ] ,
165+ environment: [ : ] ,
166+ inputFiles: [ swiftJavaDirectory] ,
167+ outputFiles: [ ]
168+ )
169+ ]
170+
171+ let swiftKitCoreClassPath = swiftJavaDirectory. appending ( path: " SwiftKitCore/build/classes/java/main " )
172+
173+ // Compile the jextracted sources
174+ let javaHome = URL ( filePath: findJavaHome ( ) )
175+ #if os(Windows)
176+ let javac = " javac.exe "
177+ #else
178+ let javac = " javac "
179+ #endif
180+ commands += [
181+ . buildCommand(
182+ displayName: " Build extracted Java sources " ,
183+ executable: javaHome
184+ . appending ( path: " bin " )
185+ . appending ( path: javac) ,
186+ arguments: [
187+ " @ \( javaSourcesFile. path ( percentEncoded: false ) ) " ,
188+ " -d " , javaClassFileURL. path,
189+ " -parameters " ,
190+ " -classpath " , swiftKitCoreClassPath. path ( percentEncoded: false )
191+ ] ,
192+ inputFiles: [ javaSourcesFile] ,
193+ outputFiles: [ ]
194+ )
195+ ]
196+
197+ return commands
135198 }
136199
137200 /// Find the manifest files from other swift-java executions in any targets
@@ -181,5 +244,27 @@ struct JExtractSwiftBuildToolPlugin: SwiftJavaPluginProtocol, BuildToolPlugin {
181244
182245 return dependentConfigFiles
183246 }
247+
248+ private func findSwiftJavaDirectory( for target: any Target ) -> URL ? {
249+ for dependency in target. dependencies {
250+ switch dependency {
251+ case . target( let target) :
252+ continue
253+
254+ case . product( let product) :
255+ guard let swiftJava = product. sourceModules. first ( where: { $0. name == " SwiftJava " } ) else {
256+ return nil
257+ }
258+
259+ // We are inside Sources/SwiftJava
260+ return swiftJava. directoryURL. deletingLastPathComponent ( ) . deletingLastPathComponent ( )
261+
262+ @unknown default :
263+ continue
264+ }
265+ }
266+
267+ return nil
268+ }
184269}
185270
0 commit comments