Skip to content

Commit 5d7677e

Browse files
committed
linux JExtractPluginSampleApp worked
1 parent 7f98e7a commit 5d7677e

File tree

17 files changed

+113
-69
lines changed

17 files changed

+113
-69
lines changed

.github/workflows/pull_request.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ jobs:
3232
- uses: actions/checkout@v4
3333
- name: Prepare CI Environment
3434
uses: ./.github/actions/prepare_env
35-
- name: Gradle build
35+
- name: Gradle :SwiftKit:build
3636
run: ./gradlew build -x test # just build
37-
- name: Gradle check
38-
run: ./gradlew check --info
39-
- name: Gradle compile benchmarks
37+
- name: Gradle :SwiftKit:check
38+
run: ./gradlew :SwiftKit:check --info
39+
- name: Gradle compile JMH benchmarks
4040
run: ./gradlew compileJmh --info
4141

4242
test-swift:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ Package.resolved
3737
*/**/*.d
3838
*/**/*.o
3939
*/**/*.swiftdeps
40+
*/**/*.swiftdeps~

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

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,3 @@ tasks.withType<Test> {
9191
this.showStandardStreams = true
9292
}
9393
}
94-
95-
96-
// TODO: This is a crude workaround, we'll remove 'make' soon and properly track build dependencies
97-
// val buildSwiftJExtract = tasks.register<Exec>("buildMake") {
98-
// description = "Triggers 'make' build"
99-
//
100-
// workingDir(rootDir)
101-
// commandLine("make")
102-
// }
103-
//
104-
// tasks.build {
105-
// dependsOn(buildSwiftJExtract)
106-
// }
107-

Plugins/JExtractSwiftCommandPlugin/JExtractSwiftCommandPlugin.swift

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,14 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
3030
/// This helps verify that the generated output is correct, and won't miscompile on the next build.
3131
var buildOutputs: Bool = true
3232

33-
func createBuildCommands(context: PackagePlugin.PluginContext, target: any PackagePlugin.Target) async throws -> [PackagePlugin.Command] {
33+
func createBuildCommands(context: PluginContext, target: any Target) async throws -> [Command] {
3434
// FIXME: This is not a build plugin but SwiftPM forces us to impleme the protocol anyway? rdar://139556637
3535
return []
3636
}
3737

3838
func performCommand(context: PluginContext, arguments: [String]) throws {
3939
// Plugin can't have dependencies, so we have some naive argument parsing instead:
4040
self.verbose = arguments.contains("-v") || arguments.contains("--verbose")
41-
if !self.verbose {
42-
fatalError("Plugin should be verbose")
43-
}
4441

4542
let selectedTargets: [String] =
4643
if let last = arguments.lastIndex(where: { $0.starts(with: "-")}),
@@ -52,32 +49,23 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
5249

5350
for target in context.package.targets {
5451
guard let configPath = getSwiftJavaConfig(target: target) else {
55-
log("Skipping target '\(target.name), has no 'swift-java.config' file")
52+
log("Skipping target '\(target.name)', has no 'swift-java.config' file")
5653
continue
5754
}
5855

5956
do {
6057
print("[swift-java-command] Extracting Java wrappers from target: '\(target.name)'...")
61-
try performCommand(context: context, target: target, arguments: arguments)
58+
try performCommand(context: context, target: target, extraArguments: arguments)
6259
} catch {
6360
print("[swift-java-command] error: Failed to extract from target '\(target.name)': \(error)")
6461
}
6562

66-
print("[swift-java-command] Done.")
6763
}
64+
print("[swift-java-command] Generating sources: " + "done".green + ".")
6865
}
6966

70-
/// Perform the command on a specific target.
71-
func performCommand(context: PluginContext, target: Target, arguments: [String]) throws {
72-
// Make sure the target can builds properly
73-
try self.packageManager.build(.target(target.name), parameters: .init())
74-
75-
guard let sourceModule = target.sourceModule else { return }
76-
77-
if self.buildInputs {
78-
log("Pre-building target '\(target.name)' before extracting sources...")
79-
try self.packageManager.build(.target(target.name), parameters: .init())
80-
}
67+
func prepareJExtractArguments(context: PluginContext, target: Target) throws -> [String] {
68+
guard let sourceModule = target.sourceModule else { return [] }
8169

8270
// Note: Target doesn't have a directoryURL counterpart to directory,
8371
// so we cannot eliminate this deprecation warning.
@@ -106,6 +94,23 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
10694
]
10795
arguments.append(sourceDir)
10896

97+
return arguments
98+
}
99+
100+
/// Perform the command on a specific target.
101+
func performCommand(context: PluginContext, target: Target, extraArguments _: [String]) throws {
102+
// Make sure the target can builds properly
103+
try self.packageManager.build(.target(target.name), parameters: .init())
104+
105+
guard let sourceModule = target.sourceModule else { return }
106+
107+
if self.buildInputs {
108+
log("Pre-building target '\(target.name)' before extracting sources...")
109+
try self.packageManager.build(.target(target.name), parameters: .init())
110+
}
111+
112+
let arguments = try prepareJExtractArguments(context: context, target: target)
113+
109114
try runExtract(context: context, target: target, arguments: arguments)
110115

111116
if self.buildOutputs {
@@ -146,3 +151,10 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
146151
}
147152
}
148153
}
154+
155+
// Mini coloring helper, since we cannot have dependencies we keep it minimal here
156+
extension String {
157+
var green: String {
158+
"\u{001B}[0;32m" + "\(self)" + "\u{001B}[0;0m"
159+
}
160+
}

Samples/JExtractPluginSampleApp/Sources/JExtractPluginSampleLib/MyCoolSwiftClass.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,9 @@ public class MyCoolSwiftClass {
2424
print("[swift] number = \(number)")
2525
}
2626
}
27+
28+
@_silgen_name("_objc_autoreleaseReturnValue")
29+
public func _objc_autoreleaseReturnValue(a: Any) {}
30+
31+
@_silgen_name("objc_autoreleaseReturnValue")
32+
public func objc_autoreleaseReturnValue(a: Any) {}

Samples/JExtractPluginSampleApp/build.gradle

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ def buildJExtractPlugin = tasks.register("swiftBuildJExtractPlugin", Exec) {
4848
args "build"
4949
}
5050

51+
def swiftClean = tasks.register("swiftClean", Exec) {
52+
workingDir = layout.projectDirectory
53+
commandLine "swift"
54+
args("package", "clean")
55+
}
56+
5157
def jextract = tasks.register("jextract", Exec) {
5258
description = "Builds swift sources, including swift-java source generation"
5359
dependsOn buildJExtractPlugin
@@ -93,6 +99,10 @@ tasks.build {
9399
dependsOn("jextract")
94100
}
95101

102+
tasks.clean {
103+
dependsOn("swiftClean")
104+
}
105+
96106
dependencies {
97107
implementation(project(':SwiftKit'))
98108

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ 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+
SwiftKit.loadLibraries(true);
2526
var o = new MyCoolSwiftClass(12);
2627
o.exposedToJava();
2728
}

Samples/SwiftKitSampleApp/build.gradle

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

52+
def swiftClean = tasks.register("swiftClean", Exec) {
53+
workingDir = layout.projectDirectory
54+
commandLine "swift"
55+
args("package", "clean")
56+
}
57+
5258
def jextract = tasks.register("jextract", Exec) {
5359
description = "Builds swift sources, including swift-java source generation"
5460
dependsOn buildJExtractPlugin
@@ -104,6 +110,10 @@ tasks.build {
104110
dependsOn("jextract")
105111
}
106112

113+
tasks.clean {
114+
dependsOn("swiftClean")
115+
}
116+
107117
dependencies {
108118
implementation(project(':SwiftKit'))
109119

Sources/JExtractSwift/Swift2JavaTranslator+Printing.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,9 +446,9 @@ extension Swift2JavaTranslator {
446446
.map(Object::toString)
447447
.collect(Collectors.joining(", "));
448448
System.out.printf("[java][%s:%d] Downcall: %s(%s)\\n",
449-
ex.getStackTrace()[1].getFileName(),
450-
ex.getStackTrace()[1].getLineNumber(),
451-
ex.getStackTrace()[1].getMethodName(),
449+
ex.getStackTrace()[2].getFileName(),
450+
ex.getStackTrace()[2].getLineNumber(),
451+
ex.getStackTrace()[2].getMethodName(),
452452
traceArgs);
453453
}
454454
@@ -459,9 +459,9 @@ extension Swift2JavaTranslator {
459459
.map(Object::toString)
460460
.collect(Collectors.joining(", "));
461461
System.out.printf("[java][%s:%d] %s: %s\\n",
462-
ex.getStackTrace()[1].getFileName(),
463-
ex.getStackTrace()[1].getLineNumber(),
464-
ex.getStackTrace()[1].getMethodName(),
462+
ex.getStackTrace()[2].getFileName(),
463+
ex.getStackTrace()[2].getLineNumber(),
464+
ex.getStackTrace()[2].getMethodName(),
465465
traceArgs);
466466
}
467467
"""
@@ -884,18 +884,26 @@ extension Swift2JavaTranslator {
884884
let firstName = p.firstName ?? "_"
885885
let secondName = p.secondName ?? p.firstName ?? nextUniqueParamName()
886886

887+
let paramTy: String =
888+
if paramPassingStyle == .swiftThunkSelf {
889+
"\(p.type.cCompatibleSwiftType)"
890+
} else {
891+
p.type.swiftTypeName.description
892+
}
893+
887894
let param =
888895
if firstName == secondName {
889896
// We have to do this to avoid a 'extraneous duplicate parameter name; 'number' already has an argument label' warning
890-
"\(firstName): \(p.type.swiftTypeName.description)"
897+
"\(firstName): \(paramTy)"
891898
} else {
892-
"\(firstName) \(secondName): \(p.type.swiftTypeName.description)"
899+
"\(firstName) \(secondName): \(paramTy)"
893900
}
894901
ps.append(param)
895902
}
896903

897904
if paramPassingStyle == .swiftThunkSelf {
898-
ps.append("_self: Any")
905+
ps.append("_self: UnsafeMutableRawPointer")
906+
// ps.append("_self: Any")
899907
}
900908

901909
let res = ps.joined(separator: ", ")

Sources/JExtractSwift/Swift2JavaVisitor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
136136

137137
// TODO: filter out kinds of variables we cannot import
138138

139-
self.log.info("Import variable: \(node.kind) \(fullName)")
139+
self.log.debug("Import variable: \(node.kind) \(fullName)")
140140

141141
let returnTy: TypeSyntax
142142
if let typeAnnotation = binding.typeAnnotation {
@@ -167,7 +167,7 @@ final class Swift2JavaVisitor: SyntaxVisitor {
167167
}
168168

169169
if let currentTypeName {
170-
log.info("Record variable in \(currentTypeName)")
170+
log.debug("Record variable in \(currentTypeName)")
171171
translator.importedTypes[currentTypeName]!.variables.append(varDecl)
172172
} else {
173173
fatalError("Global variables are not supported yet: \(node.debugDescription)")

0 commit comments

Comments
 (0)