1
2
3
4
5
6
7
8
9
10
11
12
13
14 package com.jayway.maven.plugins.android;
15
16 import com.jayway.maven.plugins.android.phase05compile.NdkBuildMojo;
17 import org.apache.commons.lang.SystemUtils;
18 import org.apache.maven.plugin.MojoExecutionException;
19
20 import java.io.File;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.List;
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 " + NdkBuildMojo.ENV_ANDROID_NDK_HOME + ".";
37
38 public static final String[] NDK_ARCHITECTURES = { "armeabi", "armeabi-v7a", "mips", "x86" };
39
40
41
42
43 private static final String[] ARM_TOOLCHAIN = { "arm-linux-androideabi-4.7", "arm-linux-androideabi-4.6",
44 "arm-linux-androideabi-4.4.3" };
45
46
47
48
49 private static final String[] X86_TOOLCHAIN = { "x86-4.7", "x86-4.6", "x86-4.4.3" };
50
51
52
53
54 private static final String[] MIPS_TOOLCHAIN = { "mipsel-linux-android-4.7", "mipsel-linux-android-4.6",
55 "mipsel-linux-android-4.4.3" };
56
57
58
59
60 private static final String[] GDB_SERVER_LOCATIONS = { "toolchains/%s/prebuilt/gdbserver",
61 "prebuilt/%s/gdbserver/gdbserver" };
62
63 private final File ndkPath;
64
65 public AndroidNdk( File ndkPath )
66 {
67 assertPathIsDirectory( ndkPath );
68 this.ndkPath = ndkPath;
69 }
70
71 private void assertPathIsDirectory( final File path )
72 {
73 if ( path == null )
74 {
75 throw new InvalidNdkException( PROPER_NDK_HOME_DIRECTORY_MESSAGE );
76 }
77 if ( ! path.isDirectory() )
78 {
79 throw new InvalidNdkException(
80 "Path \"" + path + "\" is not a directory. " + PROPER_NDK_HOME_DIRECTORY_MESSAGE );
81 }
82 }
83
84 private File findStripper( String toolchain )
85 {
86 List<String> osDirectories = new ArrayList<String>();
87 String extension = "";
88
89 if ( SystemUtils.IS_OS_LINUX )
90 {
91 osDirectories.add( "linux-x86" );
92 osDirectories.add( "linux-x86_64" );
93 }
94 else if ( SystemUtils.IS_OS_WINDOWS )
95 {
96 osDirectories.add( "windows" );
97 osDirectories.add( "windows-x86_64" );
98 extension = ".exe";
99 }
100 else if ( SystemUtils.IS_OS_MAC || SystemUtils.IS_OS_MAC_OSX )
101 {
102 osDirectories.add( "darwin-x86" );
103 osDirectories.add( "darwin-x86_64" );
104 }
105
106 String fileName = "";
107 if ( toolchain.startsWith( "arm" ) )
108 {
109 fileName = "arm-linux-androideabi-strip" + extension;
110 }
111 else if ( toolchain.startsWith( "x86" ) )
112 {
113 fileName = "i686-linux-android-strip" + extension;
114 }
115 else if ( toolchain.startsWith( "mips" ) )
116 {
117 fileName = "mipsel-linux-android-strip" + extension;
118 }
119
120 for ( String osDirectory : osDirectories )
121 {
122 String stripperLocation =
123 String.format( "toolchains/%s/prebuilt/%s/bin/%s", toolchain, osDirectory, fileName );
124 final File stripper = new File( ndkPath, stripperLocation );
125 if ( stripper.exists() )
126 {
127 return stripper;
128 }
129 }
130 return null;
131 }
132
133 public File getStripper( String toolchain ) throws MojoExecutionException
134 {
135 final File stripper = findStripper( toolchain );
136 if ( stripper == null )
137 {
138 throw new MojoExecutionException( "Could not resolve stripper for current OS: " + SystemUtils.OS_NAME );
139 }
140
141
142 if ( ! stripper.exists() )
143 {
144 throw new MojoExecutionException( "Strip binary " + stripper.getAbsolutePath()
145 + " does not exist, please double check the toolchain and OS used" );
146 }
147
148
149 return stripper;
150 }
151
152 private String resolveNdkToolchain( String[] toolchains )
153 {
154 for ( String toolchain : toolchains )
155 {
156 File f = findStripper( toolchain );
157 if ( f != null && f.exists() )
158 {
159 return toolchain;
160 }
161 }
162 return null;
163 }
164
165
166
167
168
169
170
171
172 public String getToolchain( File file ) throws MojoExecutionException
173 {
174 String resolvedNdkToolchain = null;
175
176
177 String ndkArchitecture = file.getParentFile().getName();
178 if ( ndkArchitecture.startsWith( "arm" ) )
179 {
180 resolvedNdkToolchain = resolveNdkToolchain( ARM_TOOLCHAIN );
181 }
182 else if ( ndkArchitecture.startsWith( "x86" ) )
183 {
184 resolvedNdkToolchain = resolveNdkToolchain( X86_TOOLCHAIN );
185 }
186 else if ( ndkArchitecture.startsWith( "mips" ) )
187 {
188 resolvedNdkToolchain = resolveNdkToolchain( MIPS_TOOLCHAIN );
189 }
190
191
192 if ( resolvedNdkToolchain == null )
193 {
194 throw new MojoExecutionException(
195 "Can not resolve automatically a toolchain to use. Please specify one." );
196 }
197 return resolvedNdkToolchain;
198 }
199
200
201
202
203
204
205 public String getNdkBuildPath()
206 {
207 if ( SystemUtils.IS_OS_WINDOWS )
208 {
209 return new File( ndkPath, "/ndk-build.cmd" ).getAbsolutePath();
210 }
211 else
212 {
213 return new File( ndkPath, "/ndk-build" ).getAbsolutePath();
214 }
215 }
216
217 public File getGdbServer( String ndkArchitecture ) throws MojoExecutionException
218 {
219
220 List<String> gdbServerLocations = new ArrayList<String>();
221 if ( ndkArchitecture.startsWith( "arm" ) )
222 {
223 gdbServerLocations.add( "android-arm" );
224 gdbServerLocations.addAll( Arrays.asList( ARM_TOOLCHAIN ) );
225 }
226 else if ( ndkArchitecture.startsWith( "x86" ) )
227 {
228 gdbServerLocations.add( "android-x86" );
229 gdbServerLocations.addAll( Arrays.asList( X86_TOOLCHAIN ) );
230 }
231 else if ( ndkArchitecture.startsWith( "mips" ) )
232 {
233 gdbServerLocations.add( "android-mips" );
234 gdbServerLocations.addAll( Arrays.asList( MIPS_TOOLCHAIN ) );
235 }
236
237
238 for ( String location : GDB_SERVER_LOCATIONS )
239 {
240 for ( String gdbServerLocation : gdbServerLocations )
241 {
242 File gdbServerFile = new File( ndkPath, String.format( location, gdbServerLocation ) );
243 if ( gdbServerFile.exists() )
244 {
245 return gdbServerFile;
246 }
247 }
248 }
249
250
251 throw new MojoExecutionException( "gdbserver binary for architecture " + ndkArchitecture
252 + " does not exist, please double check the toolchain and OS used" );
253 }
254 }