1
2
3
4
5
6
7
8
9
10
11
12
13
14 package com.simpligility.maven.plugins.android;
15
16 import org.apache.commons.lang3.SystemUtils;
17 import org.apache.maven.plugin.MojoExecutionException;
18
19 import java.io.File;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.List;
23
24
25
26
27
28
29
30 public class AndroidNdk
31 {
32
33 public static final String PROPER_NDK_HOME_DIRECTORY_MESSAGE = "Please provide a proper Android NDK directory path"
34 + " as configuration parameter <ndk><path>...</path></ndk> in the plugin <configuration/>. As an "
35 + "alternative, you may add the parameter to commandline: -Dandroid.ndk.path=... or set environment "
36 + "variable ANDROID_ND_HOME.";
37
38 public static final String[] NDK_ARCHITECTURES = { "armeabi", "armeabi-v7a", "arm64-v8a", "mips", "mips64",
39 "x86", "x86_64" };
40
41
42
43
44 public static final String[] ARM_TOOLCHAIN = { "arm-linux-androideabi-4.9", "arm-linux-androideabi-4.8",
45 "arm-linux-androideabi-4.7", "arm-linux-androideabi-4.6", "arm-linux-androideabi-4.4.3" };
46
47
48
49
50 public static final String[] ARM64_TOOLCHAIN = { "aarch64-linux-android-4.9" };
51
52
53
54
55 public static final String[] X86_TOOLCHAIN = { "x86-4.9", "x86-4.8", "x86-4.7", "x86-4.6", "x86-4.4.3" };
56
57
58
59
60 public static final String[] X86_64_TOOLCHAIN = { "x86_64-4.9" };
61
62
63
64
65 public static final String[] MIPS_TOOLCHAIN = { "mipsel-linux-android-4.9", "mipsel-linux-android-4.8",
66 "mipsel-linux-android-4.7", "mipsel-linux-android-4.6", "mipsel-linux-android-4.4.3" };
67
68
69
70
71 public static final String[] MIPS64_TOOLCHAIN = { "mips64el-linux-android-4.9" };
72
73
74
75
76 private static final String[] GDB_SERVER_LOCATIONS = { "toolchains/%s/prebuilt/gdbserver",
77 "prebuilt/%s/gdbserver/gdbserver" };
78
79 private final File ndkPath;
80
81 public AndroidNdk( File ndkPath )
82 {
83 assertPathIsDirectory( ndkPath );
84 this.ndkPath = ndkPath;
85 }
86
87 private void assertPathIsDirectory( final File path )
88 {
89 if ( path == null )
90 {
91 throw new InvalidNdkException( PROPER_NDK_HOME_DIRECTORY_MESSAGE );
92 }
93 if ( ! path.isDirectory() )
94 {
95 throw new InvalidNdkException(
96 "Path \"" + path + "\" is not a directory. " + PROPER_NDK_HOME_DIRECTORY_MESSAGE );
97 }
98 }
99
100 private File findStripper( String toolchain )
101 {
102 List<String> osDirectories = new ArrayList<String>();
103 String extension = "";
104
105 if ( SystemUtils.IS_OS_LINUX )
106 {
107 osDirectories.add( "linux-x86" );
108 osDirectories.add( "linux-x86_64" );
109 }
110 else if ( SystemUtils.IS_OS_WINDOWS )
111 {
112 osDirectories.add( "windows" );
113 osDirectories.add( "windows-x86_64" );
114 extension = ".exe";
115 }
116 else if ( SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_MAC_OSX )
117 {
118 osDirectories.add( "darwin-x86" );
119 osDirectories.add( "darwin-x86_64" );
120 }
121
122 String fileName = "";
123 if ( toolchain.startsWith( "arm" ) )
124 {
125 fileName = "arm-linux-androideabi-strip" + extension;
126 }
127 else if ( toolchain.startsWith( "aarch64" ) )
128 {
129 fileName = "aarch64-linux-android-strip" + extension;
130 }
131 else if ( toolchain.startsWith( "x86_64" ) )
132 {
133 fileName = "x86_64-linux-android-strip" + extension;
134 }
135 else if ( toolchain.startsWith( "x86" ) )
136 {
137 fileName = "i686-linux-android-strip" + extension;
138 }
139 else if ( toolchain.startsWith( "mips64" ) )
140 {
141 fileName = "mips64el-linux-android-strip" + extension;
142 }
143 else if ( toolchain.startsWith( "mips" ) )
144 {
145 fileName = "mipsel-linux-android-strip" + extension;
146 }
147
148 for ( String osDirectory : osDirectories )
149 {
150 String stripperLocation =
151 String.format( "toolchains/%s/prebuilt/%s/bin/%s", toolchain, osDirectory, fileName );
152 final File stripper = new File( ndkPath, stripperLocation );
153 if ( stripper.exists() )
154 {
155 return stripper;
156 }
157 }
158 return null;
159 }
160
161 public File getStripper( String toolchain ) throws MojoExecutionException
162 {
163 final File stripper = findStripper( toolchain );
164 if ( stripper == null )
165 {
166 throw new MojoExecutionException( "Could not resolve stripper for current OS: " + SystemUtils.OS_NAME );
167 }
168
169
170 if ( ! stripper.exists() )
171 {
172 throw new MojoExecutionException( "Strip binary " + stripper.getAbsolutePath()
173 + " does not exist, please double check the toolchain and OS used" );
174 }
175
176
177 return stripper;
178 }
179
180 private String resolveNdkToolchain( String[] toolchains )
181 {
182 for ( String toolchain : toolchains )
183 {
184 File f = findStripper( toolchain );
185 if ( f != null && f.exists() )
186 {
187 return toolchain;
188 }
189 }
190 return null;
191 }
192
193
194
195
196
197
198
199
200 public String getToolchain( File file ) throws MojoExecutionException
201 {
202 String resolvedNdkToolchain = null;
203
204
205 String ndkArchitecture = file.getParentFile().getName();
206 if ( ndkArchitecture.startsWith( "armeabi" ) )
207 {
208 resolvedNdkToolchain = resolveNdkToolchain( ARM_TOOLCHAIN );
209 }
210 else if ( ndkArchitecture.startsWith( "arm64" ) )
211 {
212 resolvedNdkToolchain = resolveNdkToolchain( ARM64_TOOLCHAIN );
213 }
214 else if ( ndkArchitecture.startsWith( "x86_64" ) )
215 {
216 resolvedNdkToolchain = resolveNdkToolchain( X86_64_TOOLCHAIN );
217 }
218 else if ( ndkArchitecture.startsWith( "x86" ) )
219 {
220 resolvedNdkToolchain = resolveNdkToolchain( X86_TOOLCHAIN );
221 }
222 else if ( ndkArchitecture.startsWith( "mips64" ) )
223 {
224 resolvedNdkToolchain = resolveNdkToolchain( MIPS64_TOOLCHAIN );
225 }
226 else if ( ndkArchitecture.startsWith( "mips" ) )
227 {
228 resolvedNdkToolchain = resolveNdkToolchain( MIPS_TOOLCHAIN );
229 }
230
231
232 if ( resolvedNdkToolchain == null )
233 {
234 throw new MojoExecutionException(
235 "Can not resolve automatically a toolchain to use. Please specify one." );
236 }
237 return resolvedNdkToolchain;
238 }
239
240
241
242
243
244
245 public String getNdkBuildPath()
246 {
247 if ( SystemUtils.IS_OS_WINDOWS )
248 {
249 return new File( ndkPath, "/ndk-build.cmd" ).getAbsolutePath();
250 }
251 else
252 {
253 return new File( ndkPath, "/ndk-build" ).getAbsolutePath();
254 }
255 }
256
257 public File getGdbServer( String ndkArchitecture ) throws MojoExecutionException
258 {
259
260 List<String> gdbServerLocations = new ArrayList<String>();
261 if ( ndkArchitecture.startsWith( "armeabi" ) )
262 {
263 gdbServerLocations.add( "android-arm" );
264 gdbServerLocations.add( "android-armeabi" );
265 gdbServerLocations.addAll( Arrays.asList( ARM_TOOLCHAIN ) );
266 }
267 else if ( ndkArchitecture.startsWith( "arm64" ) )
268 {
269 gdbServerLocations.add( "android-arm64" );
270 gdbServerLocations.addAll( Arrays.asList( ARM64_TOOLCHAIN ) );
271 }
272 else if ( ndkArchitecture.startsWith( "x86_64" ) )
273 {
274 gdbServerLocations.add( "android-x86_64" );
275 gdbServerLocations.addAll( Arrays.asList( X86_64_TOOLCHAIN ) );
276 }
277 else if ( ndkArchitecture.startsWith( "x86" ) )
278 {
279 gdbServerLocations.add( "android-x86" );
280 gdbServerLocations.addAll( Arrays.asList( X86_TOOLCHAIN ) );
281 }
282 else if ( ndkArchitecture.startsWith( "mips64" ) )
283 {
284 gdbServerLocations.add( "android-mips64" );
285 gdbServerLocations.addAll( Arrays.asList( MIPS64_TOOLCHAIN ) );
286 }
287 else if ( ndkArchitecture.startsWith( "mips" ) )
288 {
289 gdbServerLocations.add( "android-mips" );
290 gdbServerLocations.addAll( Arrays.asList( MIPS_TOOLCHAIN ) );
291 }
292
293
294 for ( String location : GDB_SERVER_LOCATIONS )
295 {
296 for ( String gdbServerLocation : gdbServerLocations )
297 {
298 File gdbServerFile = new File( ndkPath, String.format( location, gdbServerLocation ) );
299 if ( gdbServerFile.exists() )
300 {
301 return gdbServerFile;
302 }
303 }
304 }
305
306
307 throw new MojoExecutionException( "gdbserver binary for architecture " + ndkArchitecture
308 + " does not exist, please double check the toolchain and OS used" );
309 }
310
311 }
312