1
2
3
4
5
6
7
8
9
10
11
12
13
14 package com.simpligility.maven.plugins.androidndk;
15
16 import com.simpligility.maven.plugins.androidndk.configuration.ArchitectureToolchainMappings;
17 import com.simpligility.maven.plugins.androidndk.phase05compile.NdkBuildMojo;
18 import org.apache.commons.lang3.SystemUtils;
19 import org.apache.maven.plugin.MojoExecutionException;
20
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26
27
28
29
30
31
32 public class AndroidNdk
33 {
34
35 public static final String PROPER_NDK_HOME_DIRECTORY_MESSAGE = "Please provide a proper Android NDK directory path as configuration parameter <ndk><path>...</path></ndk>"
36 + " in the plugin <configuration/>. As an alternative, you may add the parameter to commandline: -Dandroid.ndk.path=... or set environment variable "
37 + NdkBuildMojo.ENV_ANDROID_NDK_HOME + ".";
38
39 public static final String[] NDK_ARCHITECTURES = { "arm64-v8a", "armeabi", "armeabi-v7a", "mips", "mips64", "x86", "x86_64" };
40
41
42
43
44 public static final String[] ARM_TOOLCHAIN = { "arm-linux-androideabi-4.9", "arm-linux-androideabi-4.8", "arm-linux-androideabi-4.7", "arm-linux-androideabi-4.6",
45 "arm-linux-androideabi-4.4.3", "arm-linux-androidabi-clang3.5", "arm-linux-androidabi-clang3.6" };
46
47
48
49
50 public static final String[] ARM_64_TOOLCHAIN = { "aarch64-linux-android-4.9", "aarch64-linux-android-clang3.5", "aarch64-linux-android-clang3.6" };
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", "x86-clang3.5", "x86-clang3.6" };
56
57
58
59
60 public static final String[] X86_64_TOOLCHAIN = { "x86_64-4.9", "x86_64-clang3.5", "x86_64-clang3.6" };
61
62
63
64
65 public static final String[] MIPS_TOOLCHAIN = { "mipsel-linux-android-4.9", "mipsel-linux-android-4.8", "mipsel-linux-android-4.7", "mipsel-linux-android-4.6", "mipsel-linux-android-4.4.3",
66 "mipsel-linux-android-clang3.5", "mipsel-linux-android-clang3.6" };
67
68 public static final String[] MIPS_64_TOOLCHAIN = { "mips64el-linux-android-4.9", "mips64el-linux-android-clang3.5", "mips64el-linux-android-clang3.6" };
69
70
71
72
73 private static final String[] GDB_SERVER_LOCATIONS = { "toolchains/%s/prebuilt/gdbserver", "prebuilt/%s/gdbserver/gdbserver" };
74
75
76
77
78 private static final String TOOLCHAIN_LOCATION = "toolchains/%s";
79
80 private final File ndkPath;
81
82 public AndroidNdk( File ndkPath )
83 {
84 assertPathIsDirectory( ndkPath );
85 this.ndkPath = ndkPath;
86 }
87
88 private void assertPathIsDirectory( final File path )
89 {
90 if ( path == null )
91 {
92 throw new InvalidNdkException( PROPER_NDK_HOME_DIRECTORY_MESSAGE );
93 }
94 if ( !path.isDirectory() )
95 {
96 throw new InvalidNdkException(
97 "Path \"" + path + "\" is not a directory. " + PROPER_NDK_HOME_DIRECTORY_MESSAGE );
98 }
99 }
100
101
102
103
104
105
106 public String getNdkBuildPath()
107 {
108 if ( SystemUtils.IS_OS_WINDOWS )
109 {
110 return new File( ndkPath, "/ndk-build.cmd" ).getAbsolutePath();
111 }
112 else
113 {
114 return new File( ndkPath, "/ndk-build" ).getAbsolutePath();
115 }
116 }
117
118 public File getGdbServer( String ndkArchitecture ) throws MojoExecutionException
119 {
120
121 List<String> gdbServerLocations = new ArrayList<String>();
122 if ( ndkArchitecture.startsWith( "arm64-v8a" ) )
123 {
124 gdbServerLocations.add( "android-arm64" );
125 gdbServerLocations.addAll( Arrays.asList( ARM_64_TOOLCHAIN ) );
126 }
127 else if ( ndkArchitecture.startsWith( "arm" ) )
128 {
129 gdbServerLocations.add( "android-arm" );
130 gdbServerLocations.addAll( Arrays.asList( ARM_TOOLCHAIN ) );
131 }
132
133 else if ( ndkArchitecture.startsWith( "x86_64" ) )
134 {
135 gdbServerLocations.add( "android-x86_64" );
136 gdbServerLocations.addAll( Arrays.asList( X86_TOOLCHAIN ) );
137 }
138 else if ( ndkArchitecture.startsWith( "x86" ) )
139 {
140 gdbServerLocations.add( "android-x86" );
141 gdbServerLocations.addAll( Arrays.asList( X86_TOOLCHAIN ) );
142 }
143 else if ( ndkArchitecture.startsWith( "mips" ) )
144 {
145 gdbServerLocations.add( "android-mips" );
146 gdbServerLocations.addAll( Arrays.asList( MIPS_TOOLCHAIN ) );
147 }
148
149
150 for ( String location : GDB_SERVER_LOCATIONS )
151 {
152 for ( String gdbServerLocation : gdbServerLocations )
153 {
154 File gdbServerFile = new File( ndkPath, String.format( location, gdbServerLocation ) );
155 if ( gdbServerFile.exists() )
156 {
157 return gdbServerFile;
158 }
159 }
160 }
161
162
163 throw new MojoExecutionException( "gdbserver binary for architecture " + ndkArchitecture
164 + " does not exist, please double check the toolchain and OS used" );
165 }
166
167
168
169
170
171
172
173
174
175
176
177
178 public String getToolchainFromArchitecture( final String ndkArchitecture, final ArchitectureToolchainMappings architectureToolchainMappings ) throws MojoExecutionException
179 {
180
181 if ( ndkArchitecture.startsWith( "arm64-v8a" ) )
182 {
183 if ( architectureToolchainMappings != null )
184 {
185 return architectureToolchainMappings.getArm64 ();
186 }
187 return findHighestSupportedToolchain( AndroidNdk.ARM_64_TOOLCHAIN );
188 }
189 else if ( ndkArchitecture.startsWith( "arm" ) )
190 {
191 if ( architectureToolchainMappings != null )
192 {
193 return architectureToolchainMappings.getArmeabi();
194 }
195 return findHighestSupportedToolchain( AndroidNdk.ARM_TOOLCHAIN );
196 }
197
198 else if ( ndkArchitecture.startsWith( "x86_64" ) )
199 {
200 if ( architectureToolchainMappings != null )
201 {
202 return architectureToolchainMappings.getX8664 ();
203 }
204 return findHighestSupportedToolchain( AndroidNdk.X86_64_TOOLCHAIN );
205 }
206 else if ( ndkArchitecture.startsWith( "x86" ) )
207 {
208 if ( architectureToolchainMappings != null )
209 {
210 return architectureToolchainMappings.getX86();
211 }
212 return findHighestSupportedToolchain( AndroidNdk.X86_TOOLCHAIN );
213 }
214 else if ( ndkArchitecture.startsWith( "mips" ) )
215 {
216 if ( architectureToolchainMappings != null )
217 {
218 return architectureToolchainMappings.getMips();
219 }
220 return findHighestSupportedToolchain( AndroidNdk.MIPS_TOOLCHAIN );
221 }
222
223
224 throw new MojoExecutionException( "Toolchain for architecture " + ndkArchitecture + " does not exist, please double check the setup" );
225 }
226
227 public static void validateToolchainDirectory( File toolchainDirectory ) throws MojoExecutionException
228 {
229 if ( !toolchainDirectory.exists() )
230 {
231
232 throw new MojoExecutionException( "Toolchain directory " + toolchainDirectory + " does not exist" );
233 }
234 if ( !toolchainDirectory.canRead() )
235 {
236
237 throw new MojoExecutionException( "Toolchain directory " + toolchainDirectory + " exist but can not be read" );
238 }
239 }
240
241 private String findHighestSupportedToolchain( final String[] toolchains ) throws MojoExecutionException
242 {
243 for ( String toolchain : toolchains )
244 {
245 File toolchainDirectory = new File( ndkPath, String.format( TOOLCHAIN_LOCATION, toolchain ) );
246 if ( toolchainDirectory.exists() )
247 {
248 AndroidNdk.validateToolchainDirectory( toolchainDirectory );
249 return toolchain;
250 }
251 }
252
253
254 throw new MojoExecutionException( "No valid toolchain could be found in the " + ndkPath + "/toolchains directory" );
255 }
256 }
257