Skip to content

Commit b4b1966

Browse files
committed
Move JAVA_HOME logic from swift-java's Package.swift to swift-jni
1 parent 983430b commit b4b1966

File tree

2 files changed

+97
-95
lines changed

2 files changed

+97
-95
lines changed

Package.swift

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -4,81 +4,6 @@
44
import CompilerPluginSupport
55
import PackageDescription
66

7-
import Foundation
8-
9-
// Note: the JAVA_HOME environment variable must be set to point to where
10-
// Java is installed, e.g.,
11-
// Library/Java/JavaVirtualMachines/openjdk-21.jdk/Contents/Home.
12-
func findJavaHome() -> String {
13-
if let home = ProcessInfo.processInfo.environment["JAVA_HOME"] {
14-
print("JAVA_HOME = \(home)")
15-
return home
16-
}
17-
18-
// This is a workaround for envs (some IDEs) which have trouble with
19-
// picking up env variables during the build process
20-
let path = "\(FileManager.default.homeDirectoryForCurrentUser.path()).java_home"
21-
if let home = try? String(contentsOfFile: path, encoding: .utf8) {
22-
if let lastChar = home.last, lastChar.isNewline {
23-
return String(home.dropLast())
24-
}
25-
26-
return home
27-
}
28-
29-
if let home = getJavaHomeFromLibexecJavaHome(),
30-
!home.isEmpty {
31-
return home
32-
}
33-
34-
35-
if ProcessInfo.processInfo.environment["SPI_PROCESSING"] == "1" && ProcessInfo.processInfo.environment["SPI_BUILD"] == nil {
36-
// Just ignore that we're missing a JAVA_HOME when building in Swift Package Index during general processing where no Java is needed. However, do _not_ suppress the error during SPI's compatibility build stage where Java is required.
37-
return ""
38-
}
39-
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
40-
}
41-
42-
/// On MacOS we can use the java_home tool as a fallback if we can't find JAVA_HOME environment variable.
43-
func getJavaHomeFromLibexecJavaHome() -> String? {
44-
let task = Process()
45-
task.executableURL = URL(fileURLWithPath: "/usr/libexec/java_home")
46-
47-
// Check if the executable exists before trying to run it
48-
guard FileManager.default.fileExists(atPath: task.executableURL!.path) else {
49-
print("/usr/libexec/java_home does not exist")
50-
return nil
51-
}
52-
53-
let pipe = Pipe()
54-
task.standardOutput = pipe
55-
task.standardError = pipe // Redirect standard error to the same pipe for simplicity
56-
57-
do {
58-
try task.run()
59-
task.waitUntilExit()
60-
61-
let data = pipe.fileHandleForReading.readDataToEndOfFile()
62-
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
63-
64-
if task.terminationStatus == 0 {
65-
return output
66-
} else {
67-
print("java_home terminated with status: \(task.terminationStatus)")
68-
// Optionally, log the error output for debugging
69-
if let errorOutput = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) {
70-
print("Error output: \(errorOutput)")
71-
}
72-
return nil
73-
}
74-
} catch {
75-
print("Error running java_home: \(error)")
76-
return nil
77-
}
78-
}
79-
80-
let javaHome = findJavaHome()
81-
827
let package = Package(
838
name: "swift-java",
849
platforms: [
@@ -220,25 +145,6 @@ let package = Package(
220145
exclude: ["swift-java.config"],
221146
swiftSettings: [
222147
.swiftLanguageMode(.v5),
223-
],
224-
linkerSettings: [
225-
.unsafeFlags(
226-
[
227-
"-L\(javaHome)/lib/server",
228-
"-Xlinker", "-rpath",
229-
"-Xlinker", "\(javaHome)/lib/server",
230-
],
231-
.when(platforms: [.linux, .macOS])
232-
),
233-
.unsafeFlags(
234-
[
235-
"-L\(javaHome)/lib"
236-
],
237-
.when(platforms: [.windows])),
238-
.linkedLibrary(
239-
"jvm",
240-
.when(platforms: [.linux, .macOS, .windows])
241-
),
242148
]
243149
),
244150
.target(

swift-jni/Package.swift

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,109 @@
11
// swift-tools-version: 6.0
22
import PackageDescription
33

4+
import Foundation
5+
6+
// Note: the JAVA_HOME environment variable must be set to point to where
7+
// Java is installed, e.g.,
8+
// Library/Java/JavaVirtualMachines/openjdk-21.jdk/Contents/Home.
9+
func findJavaHome() -> String {
10+
if let home = ProcessInfo.processInfo.environment["JAVA_HOME"] {
11+
print("JAVA_HOME = \(home)")
12+
return home
13+
}
14+
15+
// This is a workaround for envs (some IDEs) which have trouble with
16+
// picking up env variables during the build process
17+
let path = "\(FileManager.default.homeDirectoryForCurrentUser.path()).java_home"
18+
if let home = try? String(contentsOfFile: path, encoding: .utf8) {
19+
if let lastChar = home.last, lastChar.isNewline {
20+
return String(home.dropLast())
21+
}
22+
23+
return home
24+
}
25+
26+
if let home = getJavaHomeFromLibexecJavaHome(),
27+
!home.isEmpty {
28+
return home
29+
}
30+
31+
32+
if ProcessInfo.processInfo.environment["SPI_PROCESSING"] == "1" && ProcessInfo.processInfo.environment["SPI_BUILD"] == nil {
33+
// Just ignore that we're missing a JAVA_HOME when building in Swift Package Index during general processing where no Java is needed. However, do _not_ suppress the error during SPI's compatibility build stage where Java is required.
34+
return ""
35+
}
36+
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
37+
}
38+
39+
/// On MacOS we can use the java_home tool as a fallback if we can't find JAVA_HOME environment variable.
40+
func getJavaHomeFromLibexecJavaHome() -> String? {
41+
let task = Process()
42+
task.executableURL = URL(fileURLWithPath: "/usr/libexec/java_home")
43+
44+
// Check if the executable exists before trying to run it
45+
guard FileManager.default.fileExists(atPath: task.executableURL!.path) else {
46+
print("/usr/libexec/java_home does not exist")
47+
return nil
48+
}
49+
50+
let pipe = Pipe()
51+
task.standardOutput = pipe
52+
task.standardError = pipe // Redirect standard error to the same pipe for simplicity
53+
54+
do {
55+
try task.run()
56+
task.waitUntilExit()
57+
58+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
59+
let output = String(data: data, encoding: .utf8)?.trimmingCharacters(in: .whitespacesAndNewlines)
60+
61+
if task.terminationStatus == 0 {
62+
return output
63+
} else {
64+
print("java_home terminated with status: \(task.terminationStatus)")
65+
// Optionally, log the error output for debugging
66+
if let errorOutput = String(data: pipe.fileHandleForReading.readDataToEndOfFile(), encoding: .utf8) {
67+
print("Error output: \(errorOutput)")
68+
}
69+
return nil
70+
}
71+
} catch {
72+
print("Error running java_home: \(error)")
73+
return nil
74+
}
75+
}
76+
77+
let javaHome = findJavaHome()
78+
479
let package = Package(
580
name: "swift-jni",
681
products: [
782
.library(name: "SwiftJNI", targets: ["SwiftJNI"]),
883
],
984
targets: [
10-
.target(name: "SwiftJNI", dependencies: ["CSwiftJavaJNI"]),
85+
.target(name: "SwiftJNI",
86+
dependencies: ["CSwiftJavaJNI"],
87+
linkerSettings: [
88+
.unsafeFlags(
89+
[
90+
"-L\(javaHome)/lib/server",
91+
"-Xlinker", "-rpath",
92+
"-Xlinker", "\(javaHome)/lib/server",
93+
],
94+
.when(platforms: [.linux, .macOS])
95+
),
96+
.unsafeFlags(
97+
[
98+
"-L\(javaHome)/lib"
99+
],
100+
.when(platforms: [.windows])),
101+
.linkedLibrary(
102+
"jvm",
103+
.when(platforms: [.linux, .macOS, .windows])
104+
),
105+
]
106+
),
11107
.target(name: "CSwiftJavaJNI")
12108
]
13109
)

0 commit comments

Comments
 (0)