22
33use anyhow:: { bail, ensure, Context , Result } ;
44use std:: collections:: HashSet ;
5+ use std:: ffi:: { OsStr , OsString } ;
56use std:: path:: { Path , PathBuf } ;
67use std:: process:: Command ;
78
89/// Returns the set of additional libraries that need to be bundled with
910/// the given library, scanned recursively.
1011///
11- /// Any libraries in `provided_libs_paths ` will be treated as available, without
12- /// being emitted. Any other library not in `search_paths` or `provided_libs_paths `
12+ /// Any libraries in `provided_libs ` will be treated as available, without
13+ /// being emitted. Any other library not in `search_paths` or `provided_libs `
1314/// will result in an error.
1415pub fn list_needed_libs_recursively (
1516 lib : & Path ,
1617 search_paths : & [ & Path ] ,
17- provided_libs_paths : & [ & Path ] ,
18- ) -> Result < HashSet < PathBuf > > {
19- // Create a view of all libraries that are available on Android
20- let mut provided = HashSet :: new ( ) ;
21- for path in provided_libs_paths {
22- for lib in find_libs_in_dir ( path) . with_context ( || {
23- format ! ( "Unable to list available libraries in `{}`" , path. display( ) )
24- } ) ? {
25- // libc++_shared is bundled with the NDK but not available on-device
26- if lib != "libc++_shared.so" {
27- provided. insert ( lib) ;
28- }
29- }
30- }
31-
18+ provided_libs : & HashSet < OsString > ,
19+ ) -> Result < ( HashSet < PathBuf > , bool ) > {
3220 let mut to_copy = HashSet :: new ( ) ;
21+ let mut needs_cpp_shared = false ;
3322
3423 let mut artifacts = vec ! [ lib. to_path_buf( ) ] ;
3524 while let Some ( artifact) = artifacts. pop ( ) {
@@ -39,16 +28,11 @@ pub fn list_needed_libs_recursively(
3928 artifact. display( )
4029 )
4130 } ) ? {
42- // c++_shared is available in the NDK but not on-device.
43- // Must be bundled with the apk if used:
44- // https://developer.android.com/ndk/guides/cpp-support#libc
45- let search_paths = if need == "libc++_shared.so" {
46- provided_libs_paths
47- } else {
48- search_paths
49- } ;
50-
51- if provided. insert ( need. clone ( ) ) {
31+ if need == "libc++_shared.so" {
32+ // c++_shared is available in the NDK but not on-device. Communicate that
33+ // we need to copy it, once
34+ needs_cpp_shared = true ;
35+ } else if !provided_libs. contains ( OsStr :: new ( & need) ) {
5236 if let Some ( path) = find_library_path ( search_paths, & need) . with_context ( || {
5337 format ! (
5438 "Could not iterate one or more search directories in `{:?}` while searching for library `{}`" ,
@@ -64,7 +48,7 @@ pub fn list_needed_libs_recursively(
6448 }
6549 }
6650
67- Ok ( to_copy)
51+ Ok ( ( to_copy, needs_cpp_shared ) )
6852}
6953
7054/// List all required shared libraries as per the dynamic section
@@ -93,17 +77,14 @@ fn list_needed_libs(library_path: &Path) -> Result<HashSet<String>> {
9377}
9478
9579/// List names of shared libraries inside directory
96- fn find_libs_in_dir ( path : & Path ) -> Result < HashSet < String > > {
80+ pub fn find_libs_in_dir ( path : & Path ) -> Result < HashSet < OsString > > {
9781 let mut libs = HashSet :: new ( ) ;
9882 let entries = std:: fs:: read_dir ( path) ?;
9983 for entry in entries {
10084 let entry = entry?;
101- if !entry. path ( ) . is_dir ( ) {
102- if let Some ( file_name) = entry. file_name ( ) . to_str ( ) {
103- if file_name. ends_with ( ".so" ) {
104- libs. insert ( file_name. to_string ( ) ) ;
105- }
106- }
85+ let path = entry. path ( ) ;
86+ if !path. is_dir ( ) && path. extension ( ) == Some ( OsStr :: new ( "so" ) ) {
87+ libs. insert ( entry. file_name ( ) . to_owned ( ) ) ;
10788 }
10889 }
10990 Ok ( libs)
0 commit comments