11use self :: conversion:: * ;
22use self :: formatting:: * ;
33use crate :: JavaBindgenConfig ;
4+ use heck:: ShoutySnakeCase ;
45use heck:: { CamelCase , KebabCase } ;
56use oo_bindgen:: formatting:: * ;
67use oo_bindgen:: native_function:: * ;
@@ -20,7 +21,11 @@ mod structure;
2021
2122const NATIVE_FUNCTIONS_CLASSNAME : & str = "NativeFunctions" ;
2223
23- const SUPPORTED_PLATFORMS : & [ Platform ] = & [ Platform :: WinX64Msvc , Platform :: LinuxX64Gnu ] ;
24+ const SUPPORTED_PLATFORMS : & [ Platform ] = & [
25+ Platform :: WinX64Msvc ,
26+ Platform :: LinuxX64Gnu ,
27+ Platform :: LinuxArm8Gnu ,
28+ ] ;
2429
2530pub fn generate_java_bindings ( lib : & Library , config : & JavaBindgenConfig ) -> FormattingResult < ( ) > {
2631 fs:: create_dir_all ( & config. java_output_dir ) ?;
@@ -46,7 +51,7 @@ pub fn generate_java_bindings(lib: &Library, config: &JavaBindgenConfig) -> Form
4651 let mut target_file = target_dir. clone ( ) ;
4752 target_file. push ( platform. bin_filename ( & ffi_name) ) ;
4853
49- fs:: copy ( source_file, target_file) ?;
54+ fs:: copy ( & source_file, & target_file) ?;
5055 }
5156
5257 // Copy the extra files
@@ -170,11 +175,6 @@ fn generate_pom(lib: &Library, config: &JavaBindgenConfig) -> FormattingResult<(
170175 f. writeln ( " <artifactId>joou-java-6</artifactId>" ) ?;
171176 f. writeln ( " <version>0.9.4</version>" ) ?;
172177 f. writeln ( " </dependency>" ) ?;
173- f. writeln ( " <dependency>" ) ?;
174- f. writeln ( " <groupId>org.apache.commons</groupId>" ) ?;
175- f. writeln ( " <artifactId>commons-lang3</artifactId>" ) ?;
176- f. writeln ( " <version>3.11</version>" ) ?;
177- f. writeln ( " </dependency>" ) ?;
178178 f. writeln ( "</dependencies>" ) ?;
179179
180180 f. newline ( ) ?;
@@ -226,35 +226,62 @@ fn generate_native_func_class(lib: &Library, config: &JavaBindgenConfig) -> Form
226226 blocked ( f, |f| {
227227 f. writeln ( "try" ) ?;
228228 blocked ( f, |f| {
229- let libname = format ! ( "{}_java" , config. ffi_name) ;
230- for platform in config. platforms . iter ( ) {
231- match platform. platform {
232- Platform :: WinX64Msvc => {
233- f. writeln ( "if(org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS && org.apache.commons.lang3.ArchUtils.getProcessor().is64Bit())" ) ?;
234- blocked ( f, |f| {
235- f. writeln ( & format ! (
236- "loadLibrary(\" {}\" , \" {}\" , \" dll\" );" ,
237- platform. platform. as_string( ) ,
238- libname
239- ) )
240- } ) ?;
241- }
242- Platform :: LinuxX64Gnu => {
243- f. writeln ( "if(org.apache.commons.lang3.SystemUtils.IS_OS_LINUX && org.apache.commons.lang3.ArchUtils.getProcessor().is64Bit())" ) ?;
244- blocked ( f, |f| {
245- f. writeln ( & format ! (
246- "loadLibrary(\" {}\" , \" lib{}\" , \" so\" );" ,
247- platform. platform. as_string( ) ,
248- libname
249- ) )
250- } ) ?;
229+ let env_variable_name =
230+ format ! ( "{}_NATIVE_LIB_LOCATION" , lib. name. to_shouty_snake_case( ) ) ;
231+ f. writeln ( & format ! (
232+ "String nativeLibLocation = System.getenv(\" {}\" );" ,
233+ env_variable_name
234+ ) ) ?;
235+ f. writeln ( "if(nativeLibLocation != null)" ) ?;
236+ blocked ( f, |f| f. writeln ( "System.load(nativeLibLocation);" ) ) ?;
237+
238+ f. writeln ( "else" ) ?;
239+ blocked ( f, |f| {
240+ f. writeln ( "boolean loaded = false;" ) ?;
241+ let libname = format ! ( "{}_java" , config. ffi_name) ;
242+ for platform in config. platforms . iter ( ) {
243+ match platform. platform {
244+ Platform :: WinX64Msvc => {
245+ f. writeln ( "if(!loaded)" ) ?;
246+ blocked ( f, |f| {
247+ f. writeln ( & format ! (
248+ "loaded = loadLibrary(\" {}\" , \" {}\" , \" dll\" );" ,
249+ platform. platform. as_string( ) ,
250+ libname
251+ ) )
252+ } ) ?;
253+ }
254+ Platform :: LinuxX64Gnu => {
255+ f. writeln ( "if(!loaded)" ) ?;
256+ blocked ( f, |f| {
257+ f. writeln ( & format ! (
258+ "loaded = loadLibrary(\" {}\" , \" lib{}\" , \" so\" );" ,
259+ platform. platform. as_string( ) ,
260+ libname
261+ ) )
262+ } ) ?;
263+ }
264+ Platform :: LinuxArm8Gnu => {
265+ f. writeln ( "if(!loaded)" ) ?;
266+ blocked ( f, |f| {
267+ f. writeln ( & format ! (
268+ "loaded = loadLibrary(\" {}\" , \" lib{}\" , \" so\" );" ,
269+ platform. platform. as_string( ) ,
270+ libname
271+ ) )
272+ } ) ?;
273+ }
274+ _ => ( ) , // Other platforms are not supported
251275 }
252- _ => ( ) , // Other platforms are not supported
253276 }
254- }
255- Ok ( ( ) )
277+
278+ f. writeln ( "if(!loaded)" ) ?;
279+ blocked ( f, |f| {
280+ f. writeln ( "throw new Exception(\" Unable to load any of the included native library\" );" )
281+ } )
282+ } )
256283 } ) ?;
257- f. writeln ( "catch(java.io.IOException e)" ) ?;
284+ f. writeln ( "catch(Exception e)" ) ?;
258285 blocked ( f, |f| {
259286 f. writeln ( "System.err.println(\" Native code library failed to load: \" + e);" ) ?;
260287 f. writeln ( "System.exit(1);" )
@@ -264,13 +291,20 @@ fn generate_native_func_class(lib: &Library, config: &JavaBindgenConfig) -> Form
264291 f. newline ( ) ?;
265292
266293 // Load library helper function
267- f. writeln ( "private static void loadLibrary(String directory, String name, String extension) throws java.io.IOException {" ) ?;
268- f. writeln ( " java.io.InputStream stream = NativeFunctions.class.getResourceAsStream(\" /\" + directory + \" /\" + name + \" .\" + extension);" ) ?;
269- f. writeln ( " java.nio.file.Path tempFilePath = java.nio.file.Files.createTempFile(name, \" .\" + extension);" ) ?;
270- f. writeln ( " tempFilePath.toFile().deleteOnExit();" ) ?;
271- f. writeln ( " java.nio.file.Files.copy(stream, tempFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);" ) ?;
272- f. writeln ( " System.load(tempFilePath.toString());" ) ?;
273- f. writeln ( "}" ) ?;
294+ f. writeln ( "private static boolean loadLibrary(String directory, String name, String extension) throws Exception" ) ?;
295+ blocked ( f, |f| {
296+ f. writeln ( "try" ) ?;
297+ blocked ( f, |f| {
298+ f. writeln ( "java.io.InputStream stream = NativeFunctions.class.getResourceAsStream(\" /\" + directory + \" /\" + name + \" .\" + extension);" ) ?;
299+ f. writeln ( "java.nio.file.Path tempFilePath = java.nio.file.Files.createTempFile(name, \" .\" + extension);" ) ?;
300+ f. writeln ( "tempFilePath.toFile().deleteOnExit();" ) ?;
301+ f. writeln ( "java.nio.file.Files.copy(stream, tempFilePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);" ) ?;
302+ f. writeln ( "System.load(tempFilePath.toString());" ) ?;
303+ f. writeln ( "return true;" )
304+ } ) ?;
305+ f. writeln ( "catch(Exception e)" ) ?;
306+ blocked ( f, |f| f. writeln ( "return false;" ) )
307+ } ) ?;
274308
275309 f. newline ( ) ?;
276310
0 commit comments