Skip to content

Commit 82b5e60

Browse files
authored
Sample for making jars with dylibs (#180)
1 parent 3ceb6ef commit 82b5e60

File tree

17 files changed

+844
-29
lines changed

17 files changed

+844
-29
lines changed

Plugins/JExtractSwiftPlugin/JExtractSwiftPlugin.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ struct JExtractSwiftBuildToolPlugin: BuildToolPlugin {
2323
// Note: Target doesn't have a directoryURL counterpart to directory,
2424
// so we cannot eliminate this deprecation warning.
2525
let sourceDir = target.directory.string
26+
27+
let t = target.dependencies.first!
28+
switch (t) {
29+
case .target(let t):
30+
t.sourceModule
31+
case .product(let p):
32+
p.sourceModules
33+
@unknown default:
34+
fatalError("Unknown target dependency type: \(t)")
35+
}
2636

2737
let toolURL = try context.tool(named: "JExtractSwiftTool").url
2838
let configuration = try readConfiguration(sourceDir: "\(sourceDir)")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import com.example.swift.MySwiftLibrary;
16+
17+
public class Example {
18+
19+
public static void main(String[] args) {
20+
MySwiftLibrary.helloWorld();
21+
}
22+
23+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// swift-tools-version: 6.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import CompilerPluginSupport
5+
import PackageDescription
6+
7+
import class Foundation.FileManager
8+
import class Foundation.ProcessInfo
9+
10+
// Note: the JAVA_HOME environment variable must be set to point to where
11+
// Java is installed, e.g.,
12+
// Library/Java/JavaVirtualMachines/openjdk-21.jdk/Contents/Home.
13+
func findJavaHome() -> String {
14+
if let home = ProcessInfo.processInfo.environment["JAVA_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+
fatalError("Please set the JAVA_HOME environment variable to point to where Java is installed.")
30+
}
31+
let javaHome = findJavaHome()
32+
33+
let javaIncludePath = "\(javaHome)/include"
34+
#if os(Linux)
35+
let javaPlatformIncludePath = "\(javaIncludePath)/linux"
36+
#elseif os(macOS)
37+
let javaPlatformIncludePath = "\(javaIncludePath)/darwin"
38+
#else
39+
// TODO: Handle windows as well
40+
#error("Currently only macOS and Linux platforms are supported, this may change in the future.")
41+
#endif
42+
43+
let package = Package(
44+
name: "SwiftAndJavaJarSampleLib",
45+
platforms: [
46+
.macOS(.v10_15)
47+
],
48+
products: [
49+
.library(
50+
name: "MySwiftLibrary",
51+
type: .dynamic,
52+
targets: ["MySwiftLibrary"]
53+
),
54+
55+
],
56+
dependencies: [
57+
.package(name: "swift-java", path: "../../"),
58+
],
59+
targets: [
60+
.target(
61+
name: "MySwiftLibrary",
62+
dependencies: [
63+
.product(name: "SwiftKitSwift", package: "swift-java"),
64+
],
65+
exclude: [
66+
"swift-java.config",
67+
],
68+
swiftSettings: [
69+
.swiftLanguageMode(.v5),
70+
.unsafeFlags(["-I\(javaIncludePath)", "-I\(javaPlatformIncludePath)"])
71+
],
72+
plugins: [
73+
.plugin(name: "JExtractSwiftPlugin", package: "swift-java"),
74+
]
75+
),
76+
]
77+
)
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the Swift.org project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift.org project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
// This is a "plain Swift" file containing various types of declarations,
16+
// that is exported to Java by using the `jextract-swift` tool.
17+
//
18+
// No annotations are necessary on the Swift side to perform the export.
19+
20+
#if os(Linux)
21+
import Glibc
22+
#else
23+
import Darwin.C
24+
#endif
25+
26+
public func helloWorld() {
27+
p("\(#function)")
28+
}
29+
30+
public func globalTakeInt(i: Int) {
31+
p("i:\(i)")
32+
}
33+
34+
public func globalTakeIntInt(i: Int, j: Int) {
35+
p("i:\(i), j:\(j)")
36+
}
37+
38+
public func globalCallMeRunnable(run: () -> ()) {
39+
run()
40+
}
41+
42+
public class MySwiftClass {
43+
44+
public var len: Int
45+
public var cap: Int
46+
47+
public init(len: Int, cap: Int) {
48+
self.len = len
49+
self.cap = cap
50+
51+
p("\(MySwiftClass.self).len = \(self.len)")
52+
p("\(MySwiftClass.self).cap = \(self.cap)")
53+
let addr = unsafeBitCast(self, to: UInt64.self)
54+
p("initializer done, self = 0x\(String(addr, radix: 16, uppercase: true))")
55+
}
56+
57+
deinit {
58+
let addr = unsafeBitCast(self, to: UInt64.self)
59+
p("Deinit, self = 0x\(String(addr, radix: 16, uppercase: true))")
60+
}
61+
62+
public var counter: Int32 = 0
63+
64+
public func voidMethod() {
65+
p("")
66+
}
67+
68+
public func takeIntMethod(i: Int) {
69+
p("i:\(i)")
70+
}
71+
72+
public func echoIntMethod(i: Int) -> Int {
73+
p("i:\(i)")
74+
return i
75+
}
76+
77+
public func makeIntMethod() -> Int {
78+
p("make int -> 12")
79+
return 12
80+
}
81+
82+
public func makeRandomIntMethod() -> Int {
83+
return Int.random(in: 1..<256)
84+
}
85+
}
86+
87+
// ==== Internal helpers
88+
89+
private func p(_ msg: String, file: String = #fileID, line: UInt = #line, function: String = #function) {
90+
print("[swift][\(file):\(line)](\(function)) \(msg)")
91+
fflush(stdout)
92+
}
93+
94+
#if os(Linux)
95+
// FIXME: why do we need this workaround?
96+
@_silgen_name("_objc_autoreleaseReturnValue")
97+
public func _objc_autoreleaseReturnValue(a: Any) {}
98+
99+
@_silgen_name("objc_autoreleaseReturnValue")
100+
public func objc_autoreleaseReturnValue(a: Any) {}
101+
#endif
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"javaPackage": "com.example.swift"
3+
}

0 commit comments

Comments
 (0)