Skip to content

Commit f10bdea

Browse files
committed
cleanup install jdk script
working on samples validation fixed name deduplication logic
1 parent 371f4e2 commit f10bdea

21 files changed

+158
-97
lines changed

.github/scripts/validate_samples.sh

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/bin/bash
2+
3+
# shellcheck disable=SC2034
4+
declare -r GREEN='\033[0;31m'
5+
declare -r BOLD='\033[1m'
6+
declare -r RESET='\033[0m'
7+
8+
# shellcheck disable=SC2155
9+
declare -r SAMPLE_PACKAGES=$(find Samples -name Package.swift -maxdepth 2)
10+
declare -r CI_VALIDATE_SCRIPT='ci-validate.sh'
11+
12+
for samplePackage in ${SAMPLE_PACKAGES} ; do
13+
sampleDir=$(dirname "$samplePackage")
14+
15+
echo ""
16+
echo ""
17+
echo "========================================================================"
18+
printf "Validate sample: '${BOLD}%s${RESET}' using: " "$sampleDir"
19+
cd "$sampleDir" || exit
20+
if [[ $(find . -name ${CI_VALIDATE_SCRIPT} -maxdepth 1) ]]; then
21+
echo -e "Custom ${BOLD}${CI_VALIDATE_SCRIPT}${RESET} script..."
22+
./${CI_VALIDATE_SCRIPT} || exit
23+
elif [[ $(find . -name 'build.gradle*' -maxdepth 1) ]]; then
24+
echo -e "${BOLD}Gradle${RESET} build..."
25+
./gradlew build --info || exit
26+
else
27+
echo -e "${BOLD}SwiftPM${RESET} build..."
28+
swift build || exit
29+
fi
30+
31+
cd - || exit
32+
done
33+
34+
35+
printf "Done validating samples: "
36+
echo "${GREEN}done${RESET}."

.github/workflows/pull_request.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ jobs:
134134
- name: Test Swift
135135
run: "swift test"
136136
- name: Build (Swift) Sample Apps
137-
run: |
138-
find Samples/ -name Package.swift -maxdepth 2 -exec swift build --package-path $(dirname {}) \;;
137+
run: .github/scripts/validate_samples.sh
139138
# TODO: Benchmark compile crashes in CI, enable when nightly toolchains in better shape.
140139
# - name: Build (Swift) Benchmarks
141140
# run: "swift package --package-path Benchmarks/ benchmark list"

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ let package = Package(
150150

151151
],
152152
dependencies: [
153-
.package(url: "https://github.com/swiftlang/swift-syntax.git", branch: "main"),
153+
.package(url: "https://github.com/swiftlang/swift-syntax", from: "600.0.1"),
154154
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.5.0"),
155155
.package(url: "https://github.com/ordo-one/package-benchmark", .upToNextMajor(from: "1.4.0")),
156156
],

Plugins/JExtractSwiftCommandPlugin/JExtractSwiftCommandPlugin.swift

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,41 +17,45 @@ import PackagePlugin
1717

1818
@main
1919
final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
20-
20+
2121
var verbose: Bool = false
22-
22+
2323
/// Build the target before attempting to extract from it.
2424
/// This avoids trying to extract from broken sources.
2525
///
2626
/// 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.
2727
var buildInputs: Bool = true
28-
28+
2929
/// Build the target once swift-java sources have been generated.
3030
/// This helps verify that the generated output is correct, and won't miscompile on the next build.
3131
var buildOutputs: Bool = true
32-
32+
3333
func createBuildCommands(context: PackagePlugin.PluginContext, target: any PackagePlugin.Target) async throws -> [PackagePlugin.Command] {
3434
// FIXME: This is not a build plugin but SwiftPM forces us to impleme the protocol anyway? rdar://139556637
3535
return []
3636
}
37-
37+
3838
func performCommand(context: PluginContext, arguments: [String]) throws {
39+
// Plugin can't have dependencies, so we have some naive argument parsing instead:
3940
self.verbose = arguments.contains("-v") || arguments.contains("--verbose")
40-
41+
if !self.verbose {
42+
fatalError("Plugin should be verbose")
43+
}
44+
4145
let selectedTargets: [String] =
4246
if let last = arguments.lastIndex(where: { $0.starts(with: "-")}),
4347
last < arguments.endIndex {
4448
Array(arguments[..<last])
4549
} else {
4650
[]
4751
}
48-
52+
4953
for target in context.package.targets {
5054
guard let configPath = getSwiftJavaConfig(target: target) else {
5155
log("Skipping target '\(target.name), has no 'swift-java.config' file")
5256
continue
5357
}
54-
58+
5559
do {
5660
print("[swift-java] Extracting Java wrappers from target: '\(target.name)'...")
5761
try performCommand(context: context, target: target, arguments: arguments)
@@ -60,24 +64,19 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
6064
}
6165
}
6266
}
63-
67+
6468
/// Perform the command on a specific target.
6569
func performCommand(context: PluginContext, target: Target, arguments: [String]) throws {
6670
// Make sure the target can builds properly
6771
try self.packageManager.build(.target(target.name), parameters: .init())
68-
72+
6973
guard let sourceModule = target.sourceModule else { return }
7074

7175
if self.buildInputs {
7276
log("Pre-building target '\(target.name)' before extracting sources...")
7377
try self.packageManager.build(.target(target.name), parameters: .init())
7478
}
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-
79+
8180
// Note: Target doesn't have a directoryURL counterpart to directory,
8281
// so we cannot eliminate this deprecation warning.
8382
let sourceDir = target.directory.string
@@ -91,8 +90,6 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
9190
.appending(path: "generated")
9291
.appending(path: "java")
9392
let outputDirectorySwift = context.pluginWorkDirectoryURL
94-
.appending(path: "src")
95-
.appending(path: "generated")
9693
.appending(path: "Sources")
9794

9895
var arguments: [String] = [
@@ -108,28 +105,42 @@ final class JExtractSwiftCommandPlugin: BuildToolPlugin, CommandPlugin {
108105
arguments.append(sourceDir)
109106

110107
try runExtract(context: context, target: target, arguments: arguments)
108+
109+
if self.buildOutputs {
110+
// Building the *products* since we need to build the dylib that contains our newly generated sources,
111+
// so just building the target again would not be enough. We build all products which we affected using
112+
// our source generation, which usually would be just a product dylib with our library.
113+
//
114+
// In practice, we'll always want to build after generating; either here,
115+
// or via some other task before we run any Java code, calling into Swift.
116+
log("Post-extract building products with target '\(target.name)'...")
117+
for product in context.package.products where product.targets.contains(where: { $0.id == target.id }) {
118+
log("Post-extract building product '\(product.name)'...")
119+
try self.packageManager.build(.product(product.name), parameters: .init())
120+
}
121+
}
111122
}
112-
123+
113124
func runExtract(context: PluginContext, target: Target, arguments: [String]) throws {
114125
let process = Process()
115126
process.executableURL = try context.tool(named: "JExtractSwiftTool").url
116127
process.arguments = arguments
117-
128+
118129
do {
119-
log("Execute: \(process.executableURL) \(arguments)")
120-
130+
log("Execute: \(process.executableURL!.absoluteURL.relativePath) \(arguments.joined(separator: " "))")
131+
121132
try process.run()
122133
process.waitUntilExit()
123-
134+
124135
assert(process.terminationStatus == 0, "Process failed with exit code: \(process.terminationStatus)")
125136
} catch {
126-
print("[swift-java][command] Failed to extract Java sources for target: '\(target.name); Error: \(error)")
137+
print("[swift-java-command] Failed to extract Java sources for target: '\(target.name); Error: \(error)")
127138
}
128139
}
129-
130-
func log(_ message: @autoclosure () -> String) {
140+
141+
func log(_ message: @autoclosure () -> String, terminator: String = "\n") {
131142
if self.verbose {
132-
print("[swift-java] \(message())")
143+
print("[swift-java-command] \(message())", terminator: terminator)
133144
}
134145
}
135146
}
Binary file not shown.

Samples/JExtractPluginSampleApp/Package.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ let javaIncludePath = "\(javaHome)/include"
3535
#elseif os(macOS)
3636
let javaPlatformIncludePath = "\(javaIncludePath)/darwin"
3737
#else
38-
// TODO: Handle windows as well
39-
#error("Currently only macOS and Linux platforms are supported, this may change in the future.")
38+
let javaPlatformIncludePath = "\(javaIncludePath)/win32"
4039
#endif
4140

4241
let package = Package(
@@ -58,6 +57,9 @@ let package = Package(
5857
.target(
5958
name: "JExtractPluginSampleLib",
6059
dependencies: [],
60+
exclude: [
61+
"swift-java.config"
62+
],
6163
swiftSettings: [
6264
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
6365
],

Samples/JExtractPluginSampleApp/build.gradle

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import java.nio.file.*
1818

1919
plugins {
2020
id("build-logic.java-application-conventions")
21-
// id("me.champeau.jmh") version "0.7.2"
2221
}
2322

2423
group = "org.swift.swiftkit"
@@ -61,22 +60,24 @@ def jextract = tasks.register("jextract", Exec) {
6160
inputs.dir(layout.projectDirectory.dir("Sources"))
6261

6362
// TODO: we can use package describe --type json to figure out which targets depend on JExtractSwiftPlugin and will produce outputs
64-
// Avoid adding this directory, but create the expected one specifically for all targets which WILL produce sources because they have the plugin
63+
// Avoid adding this directory, but create the expected one specifically for all targets
64+
// which WILL produce sources because they have the plugin
6565
outputs.dir(layout.buildDirectory.dir("../.build/plugins/outputs/${layout.projectDirectory.asFile.getName().toLowerCase()}"))
6666

6767
File baseSwiftPluginOutputsDir = layout.buildDirectory.dir("../.build/plugins/outputs/").get().asFile
6868
if (!baseSwiftPluginOutputsDir.exists()) {
6969
baseSwiftPluginOutputsDir.mkdirs()
7070
}
7171
Files.walk(layout.buildDirectory.dir("../.build/plugins/outputs/").get().asFile.toPath()).each {
72+
// Add any Java sources generated by the plugin to our sourceSet
7273
if (it.endsWith("JExtractSwiftPlugin/src/generated/java")) {
7374
outputs.dir(it)
7475
}
7576
}
7677

7778
workingDir = layout.projectDirectory
7879
commandLine "swift"
79-
args("package", "jextract")
80+
args("package", "jextract", "-v", "--log-level", "info") // TODO: pass log level from Gradle build
8081
}
8182

8283
// Add the java-swift generated Java sources
@@ -97,8 +98,6 @@ dependencies {
9798

9899
testImplementation(platform("org.junit:junit-bom:5.10.0"))
99100
testImplementation("org.junit.jupiter:junit-jupiter")
100-
101-
// implementation(swiftDynamicLibrary('')
102101
}
103102

104103
tasks.named('test', Test) {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
3+
./gradlew check && ./gradlew run

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +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-
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-
}
25+
var o = new MyCoolSwiftClass(12);
26+
o.exposedToJava();
3527
}
3628
}

0 commit comments

Comments
 (0)