Skip to content

Commit b9cd1ae

Browse files
authored
Add overrideStaticBlockLibraryLoading configuration option (#693)
1 parent dd38340 commit b9cd1ae

5 files changed

Lines changed: 195 additions & 32 deletions

File tree

Sources/JExtractSwiftLib/FFM/FFMSwift2JavaGenerator.swift

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -256,20 +256,37 @@ extension FFMSwift2JavaGenerator {
256256
printNominal(&printer, decl) { printer in
257257
// We use a static field to abuse the initialization order such that by the time we get type metadata,
258258
// we already have loaded the library where it will be obtained from.
259-
printer.printParts(
260-
"""
261-
@SuppressWarnings("unused")
262-
private static final boolean INITIALIZED_LIBS = initializeLibs();
263-
static boolean initializeLibs() {
264-
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_CORE);
265-
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
266-
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_RUNTIME_FUNCTIONS);
267-
SwiftLibraries.loadLibraryWithFallbacks(LIB_NAME);
268-
return true;
259+
if let overrideLoading = self.config.overrideStaticBlockLibraryLoading {
260+
if !overrideLoading.isEmpty {
261+
let body = overrideLoading.map { " \($0)" }.joined(separator: "\n")
262+
printer.printParts(
263+
"""
264+
@SuppressWarnings("unused")
265+
private static final boolean INITIALIZED_LIBS = initializeLibs();
266+
static boolean initializeLibs() {
267+
\(body)
268+
return true;
269+
}
270+
"""
271+
)
272+
printer.print("")
269273
}
270-
"""
271-
)
272-
printer.print("")
274+
} else {
275+
printer.printParts(
276+
"""
277+
@SuppressWarnings("unused")
278+
private static final boolean INITIALIZED_LIBS = initializeLibs();
279+
static boolean initializeLibs() {
280+
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_CORE);
281+
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
282+
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_RUNTIME_FUNCTIONS);
283+
SwiftLibraries.loadLibraryWithFallbacks(LIB_NAME);
284+
return true;
285+
}
286+
"""
287+
)
288+
printer.print("")
289+
}
273290

274291
// Type metadata (common to all nominal types)
275292
printer.printParts(
@@ -479,12 +496,35 @@ extension FFMSwift2JavaGenerator {
479496
"""
480497
static final SymbolLookup SYMBOL_LOOKUP = getSymbolLookup();
481498
private static SymbolLookup getSymbolLookup() {
482-
if (SwiftLibraries.AUTO_LOAD_LIBS) {
483-
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_CORE);
484-
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
485-
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_RUNTIME_FUNCTIONS);
486-
SwiftLibraries.loadLibraryWithFallbacks(LIB_NAME);
487-
}
499+
"""
500+
)
501+
502+
if let overrideLoading = config.overrideStaticBlockLibraryLoading {
503+
if !overrideLoading.isEmpty {
504+
let body = overrideLoading.map { " \($0)" }.joined(separator: "\n")
505+
printer.print(
506+
"""
507+
if (SwiftLibraries.AUTO_LOAD_LIBS) {
508+
\(body)
509+
}
510+
"""
511+
)
512+
}
513+
} else {
514+
printer.print(
515+
"""
516+
if (SwiftLibraries.AUTO_LOAD_LIBS) {
517+
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_CORE);
518+
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
519+
SwiftLibraries.loadLibraryWithFallbacks(SwiftLibraries.LIB_NAME_SWIFT_RUNTIME_FUNCTIONS);
520+
SwiftLibraries.loadLibraryWithFallbacks(LIB_NAME);
521+
}
522+
"""
523+
)
524+
}
525+
526+
printer.print(
527+
"""
488528
489529
if (PlatformUtils.isMacOS()) {
490530
return SymbolLookup.libraryLookup(System.mapLibraryName(LIB_NAME), LIBRARY_ARENA)

Sources/JExtractSwiftLib/JNI/JNISwift2JavaGenerator+JavaBindingsPrinting.swift

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,33 @@ extension JNISwift2JavaGenerator {
112112
printer.print(
113113
"""
114114
static final String LIB_NAME = "\(config.nativeLibraryName ?? swiftModuleName)";
115-
116-
static {
117-
System.loadLibrary(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
118-
System.loadLibrary(LIB_NAME);
119-
}
120115
"""
121116
)
122117

118+
if let overrideLoading = config.overrideStaticBlockLibraryLoading {
119+
if !overrideLoading.isEmpty {
120+
let body = overrideLoading.map { " \($0)" }.joined(separator: "\n")
121+
printer.print(
122+
"""
123+
124+
static {
125+
\(body)
126+
}
127+
"""
128+
)
129+
}
130+
} else {
131+
printer.print(
132+
"""
133+
134+
static {
135+
System.loadLibrary(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
136+
System.loadLibrary(LIB_NAME);
137+
}
138+
"""
139+
)
140+
}
141+
123142
for decl in analysis.importedGlobalFuncs {
124143
self.logger.trace("Print global function: \(decl)")
125144
printFunctionDowncallMethods(&printer, decl)
@@ -201,17 +220,39 @@ extension JNISwift2JavaGenerator {
201220
printer.print(
202221
"""
203222
static final String LIB_NAME = "\(config.nativeLibraryName ?? swiftModuleName)";
204-
205-
@SuppressWarnings("unused")
206-
private static final boolean INITIALIZED_LIBS = initializeLibs();
207-
static boolean initializeLibs() {
208-
System.loadLibrary(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
209-
System.loadLibrary(LIB_NAME);
210-
return true;
211-
}
212223
"""
213224
)
214225

226+
if let overrideLoading = config.overrideStaticBlockLibraryLoading {
227+
if !overrideLoading.isEmpty {
228+
let body = overrideLoading.map { " \($0)" }.joined(separator: "\n")
229+
printer.print(
230+
"""
231+
232+
@SuppressWarnings("unused")
233+
private static final boolean INITIALIZED_LIBS = initializeLibs();
234+
static boolean initializeLibs() {
235+
\(body)
236+
return true;
237+
}
238+
"""
239+
)
240+
}
241+
} else {
242+
printer.print(
243+
"""
244+
245+
@SuppressWarnings("unused")
246+
private static final boolean INITIALIZED_LIBS = initializeLibs();
247+
static boolean initializeLibs() {
248+
System.loadLibrary(SwiftLibraries.LIB_NAME_SWIFT_JAVA);
249+
System.loadLibrary(LIB_NAME);
250+
return true;
251+
}
252+
"""
253+
)
254+
}
255+
215256
let nestedTypes = self.analysis.importedTypes.filter { _, type in
216257
type.parent == decl.swiftNominal
217258
}

Sources/SwiftJavaConfigurationShared/Configuration.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ public struct Configuration: Codable {
3838
/// (e.g. the module is `MyLibrary` but the dylib is `MyLibrarySwiftJava` or something else).
3939
public var nativeLibraryName: String?
4040

41+
/// When non-nil, overrides the library loading statements emitted in the
42+
/// `static {}` / `initializeLibs()` block of generated Java classes.
43+
/// Each string is emitted as a verbatim Java statement.
44+
///
45+
/// When `nil` (the default), the standard loading calls are emitted.
46+
/// When set to an empty array `[]`, no library loading code is emitted at all.
47+
public var overrideStaticBlockLibraryLoading: [String]?
48+
4149
public var inputSwiftDirectory: String?
4250

4351
public var outputSwiftDirectory: String?

Tests/JExtractSwiftTests/JNI/JNIModuleTests.swift

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import JExtractSwiftLib
16+
import SwiftJavaConfigurationShared
1617
import Testing
1718

1819
@Suite
@@ -277,4 +278,53 @@ struct JNIModuleTests {
277278
]
278279
)
279280
}
281+
282+
@Test
283+
func generatesModuleJavaClass_overrideStaticBlockLibraryLoading_empty() throws {
284+
let input = "public func helloWorld()"
285+
var config = Configuration()
286+
config.overrideStaticBlockLibraryLoading = []
287+
288+
try assertOutput(
289+
input: input,
290+
config: config,
291+
.jni,
292+
.java,
293+
expectedChunks: [
294+
"""
295+
static final String LIB_NAME = "SwiftModule";
296+
"""
297+
],
298+
notExpectedChunks: [
299+
"System.loadLibrary",
300+
"initializeLibs",
301+
]
302+
)
303+
}
304+
305+
@Test
306+
func generatesModuleJavaClass_overrideStaticBlockLibraryLoading_custom() throws {
307+
let input = "public func helloWorld()"
308+
var config = Configuration()
309+
config.overrideStaticBlockLibraryLoading = [
310+
"System.loadLibrary(\"SomeSpecialName\");"
311+
]
312+
313+
try assertOutput(
314+
input: input,
315+
config: config,
316+
.jni,
317+
.java,
318+
expectedChunks: [
319+
"""
320+
static {
321+
System.loadLibrary("SomeSpecialName");
322+
}
323+
"""
324+
],
325+
notExpectedChunks: [
326+
"SwiftLibraries.LIB_NAME_SWIFT_JAVA"
327+
]
328+
)
329+
}
280330
}

Tests/JExtractSwiftTests/JNI/JNIStructTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
//===----------------------------------------------------------------------===//
1414

1515
import JExtractSwiftLib
16+
import SwiftJavaConfigurationShared
1617
import Testing
1718

1819
@Suite
@@ -206,4 +207,27 @@ struct JNIStructTests {
206207
]
207208
)
208209
}
210+
211+
@Test
212+
func generatesStructJavaClass_overrideStaticBlockLibraryLoading_empty() throws {
213+
var config = Configuration()
214+
config.overrideStaticBlockLibraryLoading = []
215+
216+
try assertOutput(
217+
input: source,
218+
config: config,
219+
.jni,
220+
.java,
221+
expectedChunks: [
222+
"""
223+
public final class MyStruct implements JNISwiftInstance {
224+
static final String LIB_NAME = "SwiftModule";
225+
"""
226+
],
227+
notExpectedChunks: [
228+
"System.loadLibrary",
229+
"initializeLibs",
230+
]
231+
)
232+
}
209233
}

0 commit comments

Comments
 (0)