@@ -52,11 +52,8 @@ mod header_binding {
5252
5353 assert_eq ! ( "android" , & target_os) ;
5454
55- let java_home =
56- std:: env:: var ( "JAVA_HOME" ) . expect ( "JAVA_HOME and ANDROID_SDK_ROOT must be set" ) ;
57- let java_home = Path :: new ( & java_home) . to_path_buf ( ) ;
5855 let android_sdk_root =
59- std:: env:: var ( "ANDROID_SDK_ROOT" ) . expect ( "JAVA_HOME and ANDROID_SDK_ROOT must be set" ) ;
56+ std:: env:: var ( "ANDROID_SDK_ROOT" ) . expect ( "ANDROID_SDK_ROOT must be set" ) ;
6057 let android_sdk_root = Path :: new ( & android_sdk_root) . to_path_buf ( ) ;
6158
6259 // Note: cfg!(target_os) and cfg!(target_arch) refer to the target of the build script:
@@ -69,51 +66,83 @@ mod header_binding {
6966 "unsupported host architecture: build from x86_64 instead"
7067 ) ;
7168
72- builder = builder
73- . clang_arg ( "-I" )
74- . clang_arg ( Path :: join ( & java_home, "include/" ) . to_string_lossy ( ) ) ;
75-
76- builder = builder. clang_arg ( "-I" ) . clang_arg (
77- Path :: join (
78- & java_home,
79- format ! ( "include/{}/" , {
80- if cfg!( target_os = "windows" ) {
81- "win32"
82- } else if cfg!( target_os = "macos" ) {
83- "darwin"
84- } else if cfg!( target_os = "linux" ) {
85- "linux"
69+ let mut android_ndk_root: Option < PathBuf > = None ;
70+
71+ let android_ndk_folder = Path :: join ( & android_sdk_root, "ndk" ) ;
72+ if android_ndk_folder. exists ( ) {
73+ // New NDK
74+ let available_ndk_versions: Vec < _ > = std:: fs:: read_dir ( android_ndk_folder. clone ( ) )
75+ . unwrap ( )
76+ . into_iter ( )
77+ . map ( |dir| dir. unwrap ( ) . path ( ) )
78+ . collect ( ) ;
79+
80+ if !available_ndk_versions. is_empty ( ) {
81+ let ndk_version = std:: env:: var ( "ANDROID_NDK_VERSION" ) ;
82+
83+ if let Ok ( ndk_version) = ndk_version {
84+ if available_ndk_versions
85+ . iter ( )
86+ . map ( |p| p. file_name ( ) )
87+ . any ( |p| {
88+ p. is_some ( ) && p. unwrap ( ) . to_string_lossy ( ) . eq ( ndk_version. as_str ( ) )
89+ } )
90+ {
91+ // Asked version is available
92+ android_ndk_root = Some ( Path :: join ( & android_ndk_folder, ndk_version) )
8693 } else {
87- panic!( "unsupported host OS: build from Windows, MacOS, or Linux instead" ) ;
94+ panic ! (
95+ "no available android ndk versions matches {}. Available versions: {:?}" ,
96+ ndk_version, available_ndk_versions
97+ )
8898 }
89- } ) ,
90- )
91- . to_string_lossy ( ) ,
92- ) ;
99+ } else {
100+ // No NDK version chosen, chose the most recent one and issue a warning
101+ println ! ( "cargo:warning=Multiple android ndk versions have been detected." ) ;
102+ println ! ( "cargo:warning=You should chose one using ANDROID_NDK_VERSION environment variable to have reproducible builds." ) ;
103+ println ! (
104+ "cargo:warning=Available versions: {:?}" ,
105+ available_ndk_versions
106+ ) ;
107+
108+ let ndk_version = available_ndk_versions
109+ . iter ( )
110+ . filter_map ( |p| p. file_name ( ) )
111+ . filter_map ( |v| semver:: Version :: parse ( v. to_string_lossy ( ) . as_ref ( ) ) . ok ( ) )
112+ . max ( )
113+ . unwrap ( ) ;
114+
115+ println ! (
116+ "cargo:warning=Automatically chosen version: {} (latest)" ,
117+ ndk_version
118+ ) ;
119+
120+ android_ndk_root =
121+ Some ( Path :: join ( & android_ndk_folder, ndk_version. to_string ( ) ) ) ;
122+ }
123+ }
124+ }
93125
126+ let android_ndk_bundle_folder = Path :: join ( & android_sdk_root, "ndk-bundle" ) ;
127+ if android_ndk_root. is_none ( ) && android_ndk_bundle_folder. exists ( ) {
128+ // Old NDK
129+ android_ndk_root = Some ( android_ndk_bundle_folder) ;
130+ }
131+
132+ let android_ndk_root = android_ndk_root. expect ( "Android ndk needs to be installed" ) ;
133+
134+ builder = builder
135+ . clang_arg ( "-I" )
136+ . clang_arg ( Path :: join ( & android_ndk_root, "sysroot/usr/include" ) . to_string_lossy ( ) ) ;
94137 builder = builder. clang_arg ( "-I" ) . clang_arg (
95- Path :: join ( & android_sdk_root, "ndk-bundle/sysroot/usr/include" ) . to_string_lossy ( ) ,
96- ) ;
97- builder = builder. clang_arg ( "-I" ) . clang_arg (
98- Path :: join (
99- & android_sdk_root,
100- "ndk-bundle/sources/cxx-stl/llvm-libc++/include" ,
101- )
102- . to_string_lossy ( ) ,
138+ Path :: join ( & android_ndk_root, "sources/cxx-stl/llvm-libc++/include" ) . to_string_lossy ( ) ,
103139 ) ;
104140 builder = builder. clang_arg ( "-I" ) . clang_arg (
105- Path :: join (
106- & android_sdk_root,
107- "ndk-bundle/sources/cxx-stl/llvm-libc++abi/include" ,
108- )
109- . to_string_lossy ( ) ,
141+ Path :: join ( & android_ndk_root, "sources/cxx-stl/llvm-libc++abi/include" )
142+ . to_string_lossy ( ) ,
110143 ) ;
111144 builder = builder. clang_arg ( "-I" ) . clang_arg (
112- Path :: join (
113- & android_sdk_root,
114- "ndk-bundle/sources/android/support/include" ,
115- )
116- . to_string_lossy ( ) ,
145+ Path :: join ( & android_ndk_root, "sources/android/support/include" ) . to_string_lossy ( ) ,
117146 ) ;
118147
119148 let host_tag = {
@@ -130,23 +159,20 @@ mod header_binding {
130159
131160 builder = builder. clang_arg ( "-I" ) . clang_arg (
132161 Path :: join (
133- & android_sdk_root,
134- format ! (
135- "ndk-bundle/toolchains/llvm/prebuilt/{}/sysroot/usr/include" ,
136- & host_tag
137- ) ,
162+ & android_ndk_root,
163+ format ! ( "toolchains/llvm/prebuilt/{}/sysroot/usr/include" , & host_tag) ,
138164 )
139165 . to_string_lossy ( ) ,
140166 ) ;
141167
142168 builder = builder. clang_arg ( "-I" ) . clang_arg (
143169 Path :: join (
144- & android_sdk_root ,
170+ & android_ndk_root ,
145171 format ! (
146- "ndk-bundle/ toolchains/llvm/prebuilt/{host}/sysroot/usr/include/{target_triple}",
147- host = & host_tag,
148- target_triple = & target_triple,
149- ) ,
172+ " toolchains/llvm/prebuilt/{host}/sysroot/usr/include/{target_triple}",
173+ host = & host_tag,
174+ target_triple = & target_triple,
175+ ) ,
150176 )
151177 . to_string_lossy ( ) ,
152178 ) ;
0 commit comments