1 | |
|
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
package com.simpligility.maven.plugins.androidndk.phase05compile; |
15 | |
|
16 | |
import com.simpligility.maven.plugins.androidndk.AndroidNdk; |
17 | |
import com.simpligility.maven.plugins.androidndk.CommandExecutor; |
18 | |
import com.simpligility.maven.plugins.androidndk.common.ArtifactResolverHelper; |
19 | |
import com.simpligility.maven.plugins.androidndk.common.Const; |
20 | |
import com.simpligility.maven.plugins.androidndk.common.MavenToPlexusLogAdapter; |
21 | |
import com.simpligility.maven.plugins.androidndk.common.NativeHelper; |
22 | |
import com.simpligility.maven.plugins.androidndk.configuration.AdditionallyBuiltModule; |
23 | |
import com.simpligility.maven.plugins.androidndk.configuration.HeaderFilesDirective; |
24 | |
import com.simpligility.maven.plugins.androidndk.configuration.ArchitectureToolchainMappings; |
25 | |
import com.simpligility.maven.plugins.androidndk.configuration.IgnoreHeaderFilesArchive; |
26 | |
import org.apache.commons.lang3.StringUtils; |
27 | |
import org.apache.maven.archiver.MavenArchiveConfiguration; |
28 | |
import org.apache.maven.archiver.MavenArchiver; |
29 | |
import org.apache.maven.artifact.Artifact; |
30 | |
import org.apache.maven.artifact.handler.ArtifactHandler; |
31 | |
import org.apache.maven.artifact.resolver.ArtifactResolver; |
32 | |
import org.apache.maven.plugin.AbstractMojo; |
33 | |
import org.apache.maven.plugin.MojoExecutionException; |
34 | |
import org.apache.maven.plugin.MojoFailureException; |
35 | |
import org.apache.maven.plugins.annotations.Component; |
36 | |
import org.apache.maven.plugins.annotations.LifecyclePhase; |
37 | |
import org.apache.maven.plugins.annotations.Mojo; |
38 | |
import org.apache.maven.plugins.annotations.Parameter; |
39 | |
import org.apache.maven.project.MavenProject; |
40 | |
import org.apache.maven.project.MavenProjectHelper; |
41 | |
import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder; |
42 | |
import org.codehaus.plexus.archiver.jar.JarArchiver; |
43 | |
import org.codehaus.plexus.util.IOUtil; |
44 | |
|
45 | |
import java.io.File; |
46 | |
import java.io.FileInputStream; |
47 | |
import java.io.FileOutputStream; |
48 | |
import java.io.FilenameFilter; |
49 | |
import java.io.IOException; |
50 | |
import java.util.ArrayList; |
51 | |
import java.util.Arrays; |
52 | |
import java.util.LinkedHashSet; |
53 | |
import java.util.List; |
54 | |
import java.util.Map; |
55 | |
import java.util.Properties; |
56 | |
import java.util.Set; |
57 | |
import java.util.regex.Matcher; |
58 | |
import java.util.regex.Pattern; |
59 | |
|
60 | |
|
61 | |
|
62 | |
|
63 | |
@Mojo( name = "ndk-build", defaultPhase = LifecyclePhase.COMPILE ) |
64 | 0 | public class NdkBuildMojo extends AbstractMojo |
65 | |
{ |
66 | |
|
67 | |
|
68 | |
|
69 | |
public static final String ENV_ANDROID_NDK_HOME = "ANDROID_NDK_HOME"; |
70 | |
|
71 | |
|
72 | |
|
73 | |
|
74 | |
|
75 | |
@Parameter( property = "android.ndk.ndkPath", readonly = true ) |
76 | |
private File ndkPath; |
77 | |
|
78 | |
|
79 | |
|
80 | |
|
81 | |
@Parameter( property = "android.ndk.ndkBuildExecutable" ) |
82 | |
private String ndkBuildExecutable; |
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
@Parameter( property = "android.ndk.buildDirectory", defaultValue = "${project.build.directory}/android-ndk-maven-plugin", readonly = true ) |
88 | |
private File buildDirectory; |
89 | |
|
90 | |
|
91 | |
|
92 | |
@Parameter( property = "android.ndk.workingDirectory", defaultValue = "${project.basedir}", readonly = true ) |
93 | |
private File workingDirectory; |
94 | |
|
95 | |
|
96 | |
|
97 | |
@Parameter( property = "android.ndk.classifier" ) |
98 | |
private String classifier; |
99 | |
|
100 | |
|
101 | |
|
102 | |
@Parameter( property = "android.ndk.additionalCommandline" ) |
103 | |
protected String additionalCommandline; |
104 | |
|
105 | |
|
106 | |
|
107 | |
|
108 | |
|
109 | |
@Parameter( property = "android.ndk.objectsOutputDirectory", defaultValue = "${project.build.directory}/obj" ) |
110 | |
private File objectsOutputDirectory; |
111 | |
|
112 | |
|
113 | |
|
114 | |
|
115 | |
|
116 | |
@Parameter( property = "android.ndk.librariesOutputDirectory", defaultValue = "${project.build.directory}/ndk-libs" ) |
117 | |
private File librariesOutputDirectory; |
118 | |
|
119 | |
|
120 | |
|
121 | |
|
122 | |
@Parameter( property = "unpackedLibsFolder", defaultValue = "${project.build.directory}/unpacked-libs" ) |
123 | |
private File unpackedLibsFolder; |
124 | |
|
125 | |
|
126 | |
|
127 | |
|
128 | |
@Parameter( property = "android.ndk.target" ) |
129 | |
private String target; |
130 | |
|
131 | |
|
132 | |
|
133 | |
|
134 | |
@Parameter( property = "android.ndk.architectures" ) |
135 | |
private String architectures; |
136 | |
|
137 | |
|
138 | |
|
139 | |
|
140 | |
|
141 | |
|
142 | |
|
143 | |
|
144 | |
@Parameter |
145 | |
private ArchitectureToolchainMappings architectureToolchainMappings; |
146 | |
|
147 | |
|
148 | |
|
149 | |
|
150 | |
|
151 | |
@Parameter( property = "android.ndk.attachHeaderFiles", defaultValue = "true" ) |
152 | |
private Boolean attachHeaderFiles; |
153 | |
|
154 | |
|
155 | |
|
156 | |
|
157 | |
@Parameter( property = "android.ndk.attachLibrariesArtifacts", defaultValue = "true" ) |
158 | |
private Boolean attachLibrariesArtifacts; |
159 | |
|
160 | |
|
161 | |
|
162 | |
|
163 | |
@Parameter( property = "android.ndk.leaveTemporaryBuildArtifacts", defaultValue = "false" ) |
164 | |
private Boolean leaveTemporaryBuildArtifacts; |
165 | |
|
166 | |
|
167 | |
|
168 | |
|
169 | |
|
170 | |
|
171 | |
|
172 | |
|
173 | |
@Parameter( property = "android.ndk.useLocalSrcIncludePaths", defaultValue = "false" ) |
174 | |
private Boolean useLocalSrcIncludePaths; |
175 | |
|
176 | |
|
177 | |
|
178 | |
|
179 | |
|
180 | |
|
181 | |
|
182 | |
|
183 | |
|
184 | |
|
185 | |
|
186 | |
|
187 | |
|
188 | |
|
189 | |
|
190 | |
|
191 | |
|
192 | |
|
193 | |
|
194 | |
|
195 | |
|
196 | |
|
197 | |
|
198 | |
|
199 | |
|
200 | |
|
201 | |
|
202 | |
|
203 | |
|
204 | |
|
205 | |
|
206 | |
|
207 | |
|
208 | |
@Parameter |
209 | |
private List<HeaderFilesDirective> headerFilesDirectives; |
210 | |
|
211 | |
|
212 | |
|
213 | |
|
214 | |
|
215 | |
@Parameter( property = "android.ndk.build.use-header-archive", defaultValue = "true" ) |
216 | |
private Boolean useHeaderArchives; |
217 | |
|
218 | |
|
219 | |
|
220 | |
|
221 | |
|
222 | |
|
223 | |
|
224 | |
|
225 | |
|
226 | |
|
227 | |
|
228 | |
|
229 | |
|
230 | |
|
231 | |
|
232 | |
|
233 | |
|
234 | |
|
235 | |
|
236 | |
@Parameter |
237 | |
private List<IgnoreHeaderFilesArchive> ignoreHeaderFilesArchives; |
238 | |
|
239 | |
|
240 | |
|
241 | |
|
242 | |
|
243 | |
|
244 | |
|
245 | |
|
246 | |
|
247 | |
|
248 | |
|
249 | |
|
250 | |
@Parameter |
251 | |
private Map<String, String> systemProperties; |
252 | |
|
253 | |
|
254 | |
|
255 | |
|
256 | |
|
257 | |
@Parameter( property = "android.ndk.ignoreBuildWarnings", defaultValue = "true" ) |
258 | |
private Boolean ignoreBuildWarnings; |
259 | |
|
260 | |
|
261 | |
|
262 | |
|
263 | |
|
264 | |
|
265 | |
|
266 | |
|
267 | |
@Parameter( property = "android.ndk.buildWarningsRegularExpression", defaultValue = ".*[warning|note]: .*" ) |
268 | |
private String buildWarningsRegularExpression; |
269 | |
|
270 | |
|
271 | |
|
272 | |
@Parameter( property = "android.ndk.build.ndk-toolchain" ) |
273 | |
private String ndkToolchain; |
274 | |
|
275 | |
|
276 | |
|
277 | |
|
278 | |
|
279 | |
@Parameter( property = "android.ndk.finalLibraryName" ) |
280 | |
private String finalLibraryName; |
281 | |
|
282 | |
|
283 | |
|
284 | |
|
285 | |
@Parameter( property = "android.ndk.makefile" ) |
286 | |
private String makefile; |
287 | |
|
288 | |
|
289 | |
|
290 | |
|
291 | |
@Parameter( property = "android.ndk.applicationMakefile" ) |
292 | |
private String applicationMakefile; |
293 | |
|
294 | |
|
295 | |
|
296 | |
|
297 | |
@Parameter( property = "android.ndk.maxJobs", defaultValue = "false" ) |
298 | |
private Boolean maxJobs; |
299 | |
|
300 | |
|
301 | |
|
302 | |
|
303 | |
@Parameter() |
304 | |
private List<AdditionallyBuiltModule> additionallyBuiltModules; |
305 | |
|
306 | |
|
307 | |
|
308 | |
|
309 | |
@Parameter( defaultValue = "false" ) |
310 | |
private boolean skip; |
311 | |
|
312 | |
|
313 | |
|
314 | |
|
315 | |
@Parameter( defaultValue = "false" ) |
316 | |
private boolean allowMultiArtifacts; |
317 | |
|
318 | |
|
319 | |
|
320 | |
|
321 | |
@Component( role = org.codehaus.plexus.archiver.Archiver.class, hint = "jar" ) |
322 | |
private JarArchiver jarArchiver; |
323 | |
|
324 | |
@Component( role = org.apache.maven.artifact.handler.ArtifactHandler.class, hint = "har" ) |
325 | |
private ArtifactHandler harArtifactHandler; |
326 | |
|
327 | |
|
328 | |
|
329 | |
|
330 | |
@Parameter( defaultValue = "${project}", readonly = true, required = true ) |
331 | |
protected MavenProject project; |
332 | |
|
333 | |
|
334 | |
|
335 | |
|
336 | |
@Component |
337 | |
protected MavenProjectHelper projectHelper; |
338 | |
|
339 | |
@Component |
340 | |
private ArtifactResolver artifactResolver; |
341 | |
|
342 | |
|
343 | |
|
344 | |
|
345 | |
@Component( hint = "default" ) |
346 | |
protected DependencyGraphBuilder dependencyGraphBuilder; |
347 | |
|
348 | |
private ArtifactResolverHelper artifactResolverHelper; |
349 | |
private NativeHelper nativeHelper; |
350 | |
|
351 | |
|
352 | |
|
353 | |
|
354 | |
@Component |
355 | |
private org.apache.maven.plugin.MojoExecution execution; |
356 | |
|
357 | |
|
358 | |
|
359 | |
|
360 | |
|
361 | |
public void execute() throws MojoExecutionException, MojoFailureException |
362 | |
{ |
363 | 0 | if ( skip ) |
364 | |
{ |
365 | 0 | getLog().info( "Skipping execution as per configuration" ); |
366 | 0 | return; |
367 | |
} |
368 | |
|
369 | 0 | if ( !attachLibrariesArtifacts && NativeHelper.isNativeArtifactProject( project ) ) |
370 | |
{ |
371 | 0 | getLog().warn( "Configured to not attach artifacts, this may cause an error at install/deploy time" ); |
372 | |
} |
373 | |
|
374 | |
|
375 | 0 | final File ndkBuildFile = new File( getAndroidNdk().getNdkBuildPath() ); |
376 | 0 | NativeHelper.validateNDKVersion( ndkBuildFile.getParentFile() ); |
377 | |
|
378 | 0 | validateMakefile( project, makefile ); |
379 | |
|
380 | 0 | final String[] resolvedNDKArchitectures = NativeHelper.getNdkArchitectures( architectures, applicationMakefile, project.getBasedir() ); |
381 | |
|
382 | |
|
383 | |
|
384 | 0 | final Set<Artifact> nativeLibraryArtifacts = findNativeLibraryDependencies(); |
385 | |
|
386 | |
|
387 | 0 | final Set<Artifact> resolvedNativeLibraryArtifacts = getArtifactResolverHelper().resolveArtifacts( nativeLibraryArtifacts ); |
388 | |
|
389 | 0 | getLog().debug( "resolveArtifacts found " + resolvedNativeLibraryArtifacts.size() + ": " + resolvedNativeLibraryArtifacts.toString() ); |
390 | |
|
391 | 0 | CompileCommand compileCommand = new CompileCommand (); |
392 | 0 | compileCommand.nativeLibraryDepedencies = resolvedNativeLibraryArtifacts; |
393 | 0 | compileCommand.resolvedArchitectures = resolvedNDKArchitectures; |
394 | |
|
395 | 0 | setupOutputDirectories( compileCommand ); |
396 | |
|
397 | 0 | compile ( compileCommand ); |
398 | |
|
399 | 0 | } |
400 | |
|
401 | |
private void setupOutputDirectories ( final CompileCommand compileCommand ) |
402 | |
{ |
403 | 0 | compileCommand.librariesOutputDirectory = librariesOutputDirectory; |
404 | 0 | compileCommand.objectsOutputDirectory = objectsOutputDirectory; |
405 | |
|
406 | |
|
407 | |
|
408 | |
|
409 | |
|
410 | |
|
411 | |
|
412 | |
|
413 | |
|
414 | 0 | if ( ! "default-ndk-build".equals( execution.getExecutionId () ) && ! "default".equals ( execution.getExecutionId () ) ) |
415 | |
{ |
416 | 0 | String libsOut = librariesOutputDirectory.getAbsolutePath(); |
417 | 0 | String out = objectsOutputDirectory.getAbsolutePath(); |
418 | |
|
419 | 0 | libsOut = libsOut + "/" + execution.getExecutionId (); |
420 | 0 | out = out + "/" + execution.getExecutionId (); |
421 | |
|
422 | |
|
423 | |
|
424 | |
|
425 | |
|
426 | |
} |
427 | |
|
428 | 0 | getLog ().debug ( "Setting library out to " + compileCommand.librariesOutputDirectory.getAbsolutePath () ); |
429 | 0 | getLog ().debug ( "Setting out to " + compileCommand.objectsOutputDirectory.getAbsolutePath () ); |
430 | |
|
431 | 0 | } |
432 | |
|
433 | 0 | private class CompileCommand |
434 | |
{ |
435 | |
private File objectsOutputDirectory; |
436 | |
private File librariesOutputDirectory; |
437 | |
|
438 | |
private Set<Artifact> nativeLibraryDepedencies; |
439 | |
private String[] resolvedArchitectures; |
440 | |
|
441 | |
public Set<Artifact> getNativeLibraryDepedencies () |
442 | |
{ |
443 | 0 | return nativeLibraryDepedencies; |
444 | |
} |
445 | |
|
446 | |
public String[] getResolvedArchitectures () |
447 | |
{ |
448 | 0 | return resolvedArchitectures; |
449 | |
} |
450 | |
} |
451 | |
|
452 | |
private void compile ( CompileCommand compileCommand ) throws MojoExecutionException |
453 | |
{ |
454 | 0 | MakefileHelper.MakefileResponse makefileResponse = null; |
455 | |
try |
456 | |
{ |
457 | |
|
458 | 0 | final CommandExecutor executor = CommandExecutor.Factory.createDefaultCommmandExecutor (); |
459 | |
|
460 | |
|
461 | |
|
462 | |
|
463 | 0 | executor.setErrorListener ( getNdkErrorListener () ); |
464 | |
|
465 | 0 | final Set<Artifact> nativeLibraryArtifacts = compileCommand.getNativeLibraryDepedencies (); |
466 | |
|
467 | 0 | final Set<Artifact> resolvedNativeLibraryArtifacts = getArtifactResolverHelper ().resolveArtifacts ( nativeLibraryArtifacts ); |
468 | |
|
469 | 0 | getLog ().debug ( "resolveArtifacts found " + resolvedNativeLibraryArtifacts.size () + ": " + resolvedNativeLibraryArtifacts.toString () ); |
470 | |
|
471 | 0 | final File buildFolder = new File ( buildDirectory, "makefile" ); |
472 | 0 | buildFolder.mkdirs (); |
473 | |
|
474 | 0 | final File androidMavenMakefile = new File ( buildFolder, "android_maven_plugin_makefile.mk" ); |
475 | 0 | final MakefileHelper makefileHelper = new MakefileHelper ( project, getLog (), getArtifactResolverHelper (), harArtifactHandler, unpackedLibsFolder, |
476 | |
buildDirectory ); |
477 | |
|
478 | 0 | MakefileHelper.MakefileRequest makefileRequest = new MakefileHelper.MakefileRequest (); |
479 | 0 | makefileRequest.artifacts = resolvedNativeLibraryArtifacts; |
480 | 0 | makefileRequest.defaultNDKArchitecture = "armeabi"; |
481 | 0 | makefileRequest.useHeaderArchives = useHeaderArchives; |
482 | 0 | makefileRequest.ignoreHeaderFilesArchives = ignoreHeaderFilesArchives; |
483 | 0 | makefileRequest.leaveTemporaryBuildArtifacts = leaveTemporaryBuildArtifacts; |
484 | 0 | makefileRequest.architectures = compileCommand.getResolvedArchitectures (); |
485 | |
|
486 | 0 | makefileResponse = makefileHelper.createMakefileFromArtifacts ( makefileRequest ); |
487 | |
|
488 | 0 | final FileOutputStream output = new FileOutputStream ( androidMavenMakefile ); |
489 | |
try |
490 | |
{ |
491 | 0 | IOUtil.copy ( makefileResponse.getMakeFile (), output ); |
492 | |
} |
493 | |
finally |
494 | |
{ |
495 | 0 | output.close (); |
496 | 0 | } |
497 | |
|
498 | |
|
499 | 0 | executor.addEnvironment ( "ANDROID_MAVEN_PLUGIN_MAKEFILE", androidMavenMakefile.getAbsolutePath () ); |
500 | |
|
501 | 0 | setupNativeLibraryEnvironment ( executor, makefileResponse ); |
502 | |
|
503 | |
|
504 | |
|
505 | |
|
506 | 0 | final File makefileCaptureFile = File.createTempFile ( "android_maven_plugin_makefile_captures", ".tmp", buildDirectory ); |
507 | |
|
508 | 0 | if ( !leaveTemporaryBuildArtifacts ) |
509 | |
{ |
510 | 0 | makefileCaptureFile.deleteOnExit (); |
511 | |
} |
512 | |
|
513 | 0 | executor.addEnvironment ( MakefileHelper.MAKEFILE_CAPTURE_FILE, makefileCaptureFile.getAbsolutePath () ); |
514 | |
|
515 | |
|
516 | 0 | if ( systemProperties != null && !systemProperties.isEmpty() ) |
517 | |
{ |
518 | 0 | for ( Map.Entry<String, String> entry : systemProperties.entrySet() ) |
519 | |
{ |
520 | 0 | executor.addEnvironment( entry.getKey(), entry.getValue() ); |
521 | 0 | } |
522 | |
} |
523 | |
|
524 | 0 | executor.setLogger( this.getLog() ); |
525 | |
|
526 | |
|
527 | 0 | final List<String> commands = new ArrayList<String>(); |
528 | |
|
529 | 0 | configureArchitectures( commands, compileCommand.getResolvedArchitectures () ); |
530 | |
|
531 | 0 | configureBuildDirectory( compileCommand, commands ); |
532 | |
|
533 | 0 | configureMakefile( commands ); |
534 | |
|
535 | 0 | configureApplicationMakefile( commands ); |
536 | |
|
537 | 0 | configureMaxJobs( commands ); |
538 | |
|
539 | |
|
540 | 0 | if ( compileCommand.getResolvedArchitectures ().length == 1 ) |
541 | |
{ |
542 | 0 | configureNdkToolchain ( compileCommand.getResolvedArchitectures ()[0], commands ); |
543 | |
} |
544 | |
|
545 | 0 | configureAdditionalCommands( commands ); |
546 | |
|
547 | |
|
548 | 0 | commands.add ( target != null ? target : "all" ); |
549 | |
|
550 | 0 | final String ndkBuildPath = resolveNdkBuildExecutable (); |
551 | 0 | getLog ().debug ( ndkBuildPath + " " + commands.toString () ); |
552 | 0 | getLog ().info ( "Executing NDK make at : " + buildDirectory ); |
553 | |
|
554 | 0 | executor.setCaptureStdOut ( true ); |
555 | 0 | executor.executeCommand ( ndkBuildPath, commands, buildDirectory, true ); |
556 | 0 | getLog ().debug ( "Executed NDK make at : " + buildDirectory ); |
557 | |
|
558 | 0 | if ( attachLibrariesArtifacts ) |
559 | |
{ |
560 | |
|
561 | 0 | for ( int i = 0; i < compileCommand.getResolvedArchitectures ().length; i++ ) |
562 | |
{ |
563 | 0 | String architecture = compileCommand.getResolvedArchitectures ()[ i ]; |
564 | 0 | processCompiledArtifacts ( compileCommand, architecture, makefileCaptureFile ); |
565 | |
} |
566 | |
} |
567 | |
else |
568 | |
{ |
569 | 0 | getLog ().info ( "Will skip attaching compiled libraries as per configuration" ); |
570 | |
} |
571 | |
|
572 | |
} |
573 | 0 | catch ( Exception e ) |
574 | |
{ |
575 | 0 | throw new MojoExecutionException ( "Failure during build: " + e.getMessage (), e ); |
576 | |
} |
577 | |
finally |
578 | |
{ |
579 | 0 | cleanupAfterBuild( makefileResponse ); |
580 | 0 | } |
581 | |
|
582 | 0 | } |
583 | |
|
584 | |
private void configureArchitectures ( final List<String> commands, final String[] resolvedArchitectures ) |
585 | |
{ |
586 | 0 | StringBuilder sb = new StringBuilder ( ); |
587 | |
|
588 | 0 | for ( int i = 0; i < resolvedArchitectures.length; i++ ) |
589 | |
{ |
590 | 0 | sb.append ( resolvedArchitectures[i] ); |
591 | 0 | if ( ( i + 1 ) < resolvedArchitectures.length ) |
592 | |
{ |
593 | 0 | sb.append ( " " ); |
594 | |
} |
595 | |
} |
596 | |
|
597 | |
|
598 | 0 | commands.add ( "APP_ABI=" + sb.toString () ); |
599 | |
|
600 | 0 | } |
601 | |
|
602 | |
|
603 | |
private void configureBuildDirectory( final CompileCommand compileCommand, final List<String> commands ) |
604 | |
{ |
605 | |
|
606 | |
|
607 | 0 | commands.add( "-C" ); |
608 | 0 | commands.add( workingDirectory.getAbsolutePath() ); |
609 | |
|
610 | |
|
611 | 0 | commands.add( "NDK_LIBS_OUT=" + compileCommand.librariesOutputDirectory.getAbsolutePath () ); |
612 | 0 | commands.add( "NDK_OUT=" + compileCommand.objectsOutputDirectory.getAbsolutePath () ); |
613 | |
|
614 | 0 | } |
615 | |
|
616 | |
private void configureMakefile( final List<String> commands ) throws MojoExecutionException |
617 | |
{ |
618 | |
|
619 | |
|
620 | 0 | if ( makefile != null ) |
621 | |
{ |
622 | 0 | File makeFile = new File( project.getBasedir(), makefile ); |
623 | 0 | if ( !makeFile.exists() ) |
624 | |
{ |
625 | 0 | getLog().error( "Specified makefile " + makeFile + " does not exist" ); |
626 | 0 | throw new MojoExecutionException( "Specified makefile " + makeFile + " does not exist" ); |
627 | |
} |
628 | 0 | commands.add( "APP_BUILD_SCRIPT=" + makefile ); |
629 | |
} |
630 | 0 | } |
631 | |
|
632 | |
private void cleanupAfterBuild ( final MakefileHelper.MakefileResponse makefileResponse ) |
633 | |
{ |
634 | |
|
635 | 0 | if ( makefileResponse != null ) |
636 | |
{ |
637 | 0 | getLog().info( "Cleaning up extracted include directories used for build" ); |
638 | 0 | MakefileHelper.cleanupAfterBuild( makefileResponse ); |
639 | |
} |
640 | 0 | } |
641 | |
|
642 | |
private void configureAdditionalCommands( final List<String> commands ) |
643 | |
{ |
644 | |
|
645 | |
|
646 | 0 | if ( additionalCommandline != null ) |
647 | |
{ |
648 | 0 | final String[] additionalCommands = additionalCommandline.split( " " ); |
649 | 0 | commands.addAll( Arrays.asList( additionalCommands ) ); |
650 | |
} |
651 | 0 | } |
652 | |
|
653 | |
private void configureApplicationMakefile( List<String> commands ) |
654 | |
throws MojoExecutionException |
655 | |
{ |
656 | 0 | if ( applicationMakefile != null ) |
657 | |
{ |
658 | 0 | File appMK = new File( project.getBasedir(), applicationMakefile ); |
659 | 0 | if ( !appMK.exists() ) |
660 | |
{ |
661 | 0 | getLog().error( "Specified application makefile " + appMK + " does not exist" ); |
662 | 0 | throw new MojoExecutionException( "Specified application makefile " + appMK + " does not exist" ); |
663 | |
} |
664 | 0 | commands.add( "NDK_APPLICATION_MK=" + applicationMakefile ); |
665 | |
} |
666 | 0 | } |
667 | |
|
668 | |
private void configureMaxJobs( List<String> commands ) |
669 | |
{ |
670 | 0 | if ( maxJobs ) |
671 | |
{ |
672 | 0 | String jobs = String.valueOf( Runtime.getRuntime().availableProcessors() ); |
673 | 0 | getLog().info( "executing " + jobs + " parallel jobs" ); |
674 | 0 | commands.add( "-j" ); |
675 | 0 | commands.add( jobs ); |
676 | |
} |
677 | 0 | } |
678 | |
|
679 | |
private void configureNdkToolchain( String architecture, List<String> commands ) |
680 | |
throws MojoExecutionException |
681 | |
{ |
682 | 0 | if ( ndkToolchain != null ) |
683 | |
{ |
684 | |
|
685 | |
|
686 | |
|
687 | 0 | commands.add( "NDK_TOOLCHAIN=" + ndkToolchain ); |
688 | 0 | commands.add( "APP_ABI=" + architecture ); |
689 | |
} |
690 | |
else |
691 | |
{ |
692 | |
|
693 | |
|
694 | |
|
695 | |
|
696 | |
|
697 | 0 | final String toolchainFromArchitecture = getAndroidNdk().getToolchainFromArchitecture( architecture, architectureToolchainMappings ); |
698 | 0 | getLog().debug( "Resolved toolchain for " + architecture + " to " + toolchainFromArchitecture ); |
699 | 0 | commands.add( "NDK_TOOLCHAIN=" + toolchainFromArchitecture ); |
700 | 0 | commands.add( "APP_ABI=" + architecture ); |
701 | |
} |
702 | 0 | } |
703 | |
|
704 | |
|
705 | |
|
706 | |
|
707 | |
private void processCompiledArtifacts ( final CompileCommand compileCommand, String architecture, final File makefileCaptureFile ) throws IOException, MojoExecutionException |
708 | |
{ |
709 | |
|
710 | 0 | final File nativeLibraryDirectory = new File( compileCommand.librariesOutputDirectory, architecture ); |
711 | |
|
712 | |
|
713 | 0 | final File nativeObjDirectory = new File( new File( compileCommand.objectsOutputDirectory, "local" ), architecture ); |
714 | |
|
715 | 0 | final List<String> classifiers = new ArrayList<String>(); |
716 | 0 | if ( allowMultiArtifacts ) |
717 | |
{ |
718 | 0 | attachManyArtifacts( nativeLibraryDirectory, architecture, nativeObjDirectory, classifiers ); |
719 | |
} |
720 | |
else |
721 | |
{ |
722 | 0 | attachOneArtifact( nativeLibraryDirectory, architecture, nativeObjDirectory, classifiers ); |
723 | |
} |
724 | |
|
725 | 0 | if ( additionallyBuiltModules != null && !additionallyBuiltModules.isEmpty() ) |
726 | |
{ |
727 | 0 | for ( AdditionallyBuiltModule additionallyBuiltModule : additionallyBuiltModules ) |
728 | |
{ |
729 | 0 | File additionalBuiltModuleFile = nativeLibraryFromName( true, nativeLibraryDirectory, additionallyBuiltModule.getName() ); |
730 | |
|
731 | |
|
732 | 0 | if ( !additionalBuiltModuleFile.exists() ) |
733 | |
{ |
734 | 0 | additionalBuiltModuleFile = nativeLibraryFromName( true, nativeObjDirectory, additionallyBuiltModule.getName() ); |
735 | |
} |
736 | |
|
737 | |
|
738 | 0 | final String additionallyBuiltArtifactType = resolveArtifactType( additionalBuiltModuleFile ); |
739 | |
|
740 | 0 | String additionallyBuiltClassifier = architecture + "-" + additionallyBuiltModule.getClassifier(); |
741 | 0 | projectHelper.attachArtifact( this.project, additionallyBuiltArtifactType, additionallyBuiltClassifier, additionalBuiltModuleFile ); |
742 | 0 | classifiers.add( additionallyBuiltClassifier ); |
743 | 0 | } |
744 | |
} |
745 | |
|
746 | |
|
747 | 0 | if ( attachHeaderFiles ) |
748 | |
{ |
749 | 0 | attachHeaderFiles( compileCommand, makefileCaptureFile, classifiers ); |
750 | |
} |
751 | |
|
752 | |
|
753 | 0 | } |
754 | |
|
755 | |
private void attachManyArtifacts( File nativeLibraryDirectory, String architecture, File nativeObjDirectory, List<String> classifiers ) throws MojoExecutionException |
756 | |
{ |
757 | 0 | List<File> artifacts = Arrays.asList( findNativeLibrary( nativeLibraryDirectory, nativeObjDirectory ) ); |
758 | 0 | for ( File file : artifacts ) |
759 | |
{ |
760 | 0 | attachArtifactFile( architecture, classifiers, file ); |
761 | 0 | } |
762 | 0 | } |
763 | |
|
764 | |
private void attachOneArtifact( File nativeLibraryDirectory, String architecture, File nativeObjDirectory, List<String> classifiers ) throws MojoExecutionException |
765 | |
{ |
766 | |
final File nativeArtifactFile; |
767 | 0 | if ( finalLibraryName == null ) |
768 | |
{ |
769 | 0 | nativeArtifactFile = findNativeLibrary( nativeLibraryDirectory, nativeObjDirectory )[0]; |
770 | |
} |
771 | |
else |
772 | |
{ |
773 | 0 | nativeArtifactFile = nativeLibraryFromName( nativeLibraryDirectory, nativeObjDirectory, finalLibraryName ); |
774 | |
} |
775 | |
|
776 | 0 | attachArtifactFile( architecture, classifiers, nativeArtifactFile ); |
777 | 0 | } |
778 | |
|
779 | |
private void attachArtifactFile( String architecture, List<String> classifiers, File nativeArtifactFile ) |
780 | |
{ |
781 | 0 | final String artifactType = resolveArtifactType( nativeArtifactFile ); |
782 | 0 | getLog().debug( "Adding native compiled artifact: " + nativeArtifactFile ); |
783 | |
|
784 | 0 | final String actualClassifier = ( classifier == null ) ? architecture : architecture + "-" + classifier; |
785 | 0 | projectHelper.attachArtifact( this.project, artifactType, actualClassifier, nativeArtifactFile ); |
786 | 0 | classifiers.add( actualClassifier ); |
787 | 0 | } |
788 | |
|
789 | |
|
790 | |
|
791 | |
|
792 | |
private File[] findNativeLibrary( File nativeLibDirectory, final File nativeObjDirectory ) throws MojoExecutionException |
793 | |
{ |
794 | 0 | getLog().info( "Searching " + nativeLibDirectory + " for built shared library" ); |
795 | |
|
796 | 0 | File[] files = nativeLibDirectory.listFiles( new FilenameFilter() |
797 | 0 | { |
798 | |
public boolean accept( final File dir, final String name ) |
799 | |
{ |
800 | 0 | String libraryName = finalLibraryName; |
801 | |
|
802 | 0 | if ( libraryName == null || libraryName.isEmpty() ) |
803 | |
{ |
804 | 0 | libraryName = project.getArtifactId(); |
805 | |
} |
806 | |
|
807 | |
|
808 | 0 | final String extension = Const.ArtifactType.NATIVE_IMPLEMENTATION_ARCHIVE.equals( project.getPackaging() ) ? ".a" : ".so"; |
809 | 0 | boolean found = name.startsWith( "lib" + libraryName ) && name.endsWith( extension ); |
810 | 0 | if ( !found ) |
811 | |
{ |
812 | |
|
813 | 0 | if ( libraryName.startsWith( "lib" ) ) |
814 | |
{ |
815 | 0 | found = name.startsWith( libraryName ) && name.endsWith( extension ); |
816 | |
} |
817 | |
} |
818 | 0 | return found; |
819 | |
} |
820 | |
} ); |
821 | |
|
822 | |
|
823 | |
|
824 | |
|
825 | 0 | if ( files == null || files.length == 0 ) |
826 | |
{ |
827 | 0 | getLog().info( "Searching " + nativeObjDirectory + " for built static library" ); |
828 | 0 | files = nativeObjDirectory.listFiles( new FilenameFilter() |
829 | 0 | { |
830 | |
public boolean accept( final File dir, final String name ) |
831 | |
{ |
832 | 0 | String libraryName = finalLibraryName; |
833 | |
|
834 | 0 | if ( libraryName == null || libraryName.isEmpty() ) |
835 | |
{ |
836 | 0 | libraryName = project.getArtifactId(); |
837 | |
} |
838 | |
|
839 | |
|
840 | 0 | if ( Const.ArtifactType.NATIVE_IMPLEMENTATION_ARCHIVE.equals( project.getPackaging() ) ) |
841 | |
{ |
842 | 0 | return name.startsWith( "lib" + libraryName ) && name.endsWith( ".a" ); |
843 | |
} |
844 | |
else |
845 | |
{ |
846 | 0 | return name.startsWith( "lib" + libraryName ) && name.endsWith( ".so" ); |
847 | |
} |
848 | |
} |
849 | |
} ); |
850 | |
|
851 | |
} |
852 | |
|
853 | |
|
854 | 0 | if ( ( files == null || files.length != 1 ) && !allowMultiArtifacts ) |
855 | |
{ |
856 | 0 | getLog().warn( "Error while detecting native compile artifacts: " + ( files == null || files.length == 0 ? "None found" : "Found more than 1 artifact" ) ); |
857 | 0 | if ( target != null ) |
858 | |
{ |
859 | 0 | getLog().warn( "Using the 'target' configuration option to specify the output file name is no longer supported, use 'finalLibraryName' instead." ); |
860 | |
} |
861 | |
|
862 | 0 | if ( files != null && files.length > 1 ) |
863 | |
{ |
864 | 0 | getLog().debug( "List of files found: " + Arrays.asList( files ) ); |
865 | 0 | getLog().error( "Currently, only a single, final native library is supported by the build" ); |
866 | 0 | throw new MojoExecutionException( "Currently, only a single, final native library is supported by the build" ); |
867 | |
} |
868 | |
else |
869 | |
{ |
870 | 0 | getLog().error( "No native compiled library found, did the native compile complete successfully?" ); |
871 | 0 | throw new MojoExecutionException( "No native compiled library found, did the native compile complete successfully?" ); |
872 | |
} |
873 | |
} |
874 | 0 | return files; |
875 | |
} |
876 | |
|
877 | |
private File nativeLibraryFromName( File nativeLibDirectory, final File nativeObjDirectory, final String libraryName ) throws MojoExecutionException |
878 | |
{ |
879 | |
try |
880 | |
{ |
881 | 0 | return nativeLibraryFromName( false, nativeLibDirectory, libraryName ); |
882 | |
} |
883 | 0 | catch ( MojoExecutionException e ) |
884 | |
{ |
885 | |
|
886 | 0 | return nativeLibraryFromName( true, nativeObjDirectory, libraryName ); |
887 | |
} |
888 | |
} |
889 | |
|
890 | |
private File nativeLibraryFromName( boolean logErrors, File directory, final String libraryName ) throws MojoExecutionException |
891 | |
{ |
892 | |
final File libraryFile; |
893 | |
|
894 | 0 | if ( Const.ArtifactType.NATIVE_SYMBOL_OBJECT.equals( project.getPackaging() ) || Const.ArtifactType.NATIVE_IMPLEMENTATION_ARCHIVE.equals( project.getPackaging() ) ) |
895 | |
{ |
896 | 0 | libraryFile = new File( directory, "lib" + libraryName + "." + project.getPackaging() ); |
897 | |
} |
898 | |
else |
899 | |
{ |
900 | 0 | final File staticLib = new File( directory, "lib" + libraryName + ".a" ); |
901 | 0 | if ( staticLib.exists() ) |
902 | |
{ |
903 | 0 | libraryFile = staticLib; |
904 | |
} |
905 | |
else |
906 | |
{ |
907 | 0 | libraryFile = new File( directory, "lib" + libraryName + ".so" ); |
908 | |
} |
909 | |
} |
910 | 0 | if ( !libraryFile.exists() ) |
911 | |
{ |
912 | 0 | if ( logErrors ) |
913 | |
{ |
914 | 0 | getLog().error( "Could not locate final native library using the provided finalLibraryName " + libraryName + " (tried " + libraryFile.getAbsolutePath() + ")" ); |
915 | |
} |
916 | 0 | throw new MojoExecutionException( "Could not locate final native library using the provided finalLibraryName " + libraryName + " (tried " + libraryFile.getAbsolutePath() + ")" ); |
917 | |
} |
918 | |
|
919 | 0 | return libraryFile; |
920 | |
} |
921 | |
|
922 | |
|
923 | |
private CommandExecutor.ErrorListener getNdkErrorListener() |
924 | |
{ |
925 | 0 | return new CommandExecutor.ErrorListener() |
926 | 0 | { |
927 | |
@Override |
928 | |
public boolean isError( String error ) |
929 | |
{ |
930 | |
|
931 | |
|
932 | 0 | if ( ignoreBuildWarnings ) |
933 | |
{ |
934 | 0 | return false; |
935 | |
} |
936 | |
|
937 | 0 | final Pattern pattern = Pattern.compile( buildWarningsRegularExpression ); |
938 | 0 | final Matcher matcher = pattern.matcher( error ); |
939 | |
|
940 | |
|
941 | |
|
942 | 0 | if ( matcher.matches() ) |
943 | |
{ |
944 | 0 | return false; |
945 | |
} |
946 | |
|
947 | |
|
948 | 0 | return true; |
949 | |
} |
950 | |
}; |
951 | |
} |
952 | |
|
953 | |
|
954 | |
|
955 | |
|
956 | |
|
957 | |
|
958 | |
private void validateMakefile( MavenProject project, String file ) |
959 | |
{ |
960 | |
|
961 | 0 | } |
962 | |
|
963 | |
private String resolveNdkBuildExecutable() throws MojoExecutionException |
964 | |
{ |
965 | 0 | if ( ndkBuildExecutable != null ) |
966 | |
{ |
967 | 0 | getLog().debug( "ndk-build overriden, using " + ndkBuildExecutable ); |
968 | 0 | return ndkBuildExecutable; |
969 | |
} |
970 | 0 | return getAndroidNdk().getNdkBuildPath(); |
971 | |
} |
972 | |
|
973 | |
private void attachHeaderFiles ( final CompileCommand compileCommand, final File localCIncludesFile, final List<String> classifiers ) throws MojoExecutionException, IOException |
974 | |
{ |
975 | |
|
976 | 0 | final List<HeaderFilesDirective> finalHeaderFilesDirectives = new ArrayList<HeaderFilesDirective>(); |
977 | |
|
978 | 0 | if ( useLocalSrcIncludePaths ) |
979 | |
{ |
980 | 0 | Properties props = new Properties(); |
981 | 0 | props.load( new FileInputStream( localCIncludesFile ) ); |
982 | 0 | String localCIncludes = props.getProperty( "LOCAL_C_INCLUDES" ); |
983 | 0 | if ( localCIncludes != null && !localCIncludes.trim().isEmpty() ) |
984 | |
{ |
985 | 0 | String[] includes = localCIncludes.split( " " ); |
986 | 0 | for ( String include : includes ) |
987 | |
{ |
988 | 0 | final HeaderFilesDirective headerFilesDirective = new HeaderFilesDirective(); |
989 | 0 | File includeDir = new File( project.getBasedir(), include ); |
990 | 0 | headerFilesDirective.setDirectory( includeDir.getAbsolutePath() ); |
991 | 0 | headerFilesDirective.setIncludes( new String[]{ "**/*.h", "**/*.hpp" } ); |
992 | 0 | finalHeaderFilesDirectives.add( headerFilesDirective ); |
993 | |
} |
994 | |
} |
995 | 0 | } |
996 | |
else |
997 | |
{ |
998 | 0 | if ( headerFilesDirectives != null ) |
999 | |
{ |
1000 | 0 | finalHeaderFilesDirectives.addAll( headerFilesDirectives ); |
1001 | |
} |
1002 | |
} |
1003 | 0 | if ( finalHeaderFilesDirectives.isEmpty() ) |
1004 | |
{ |
1005 | 0 | getLog().debug( "No header files included, will add default set" ); |
1006 | 0 | final HeaderFilesDirective e = new HeaderFilesDirective(); |
1007 | 0 | final File folder = new File( project.getBasedir() + "/jni" ); |
1008 | 0 | if ( folder.exists() ) |
1009 | |
{ |
1010 | 0 | e.setDirectory( folder.getAbsolutePath() ); |
1011 | 0 | e.setIncludes( new String[] { "**/*.h", "**/*.hpp" } ); |
1012 | 0 | finalHeaderFilesDirectives.add( e ); |
1013 | |
} |
1014 | |
} |
1015 | 0 | createHeaderArchive( compileCommand, finalHeaderFilesDirectives, classifiers ); |
1016 | 0 | } |
1017 | |
|
1018 | |
private void createHeaderArchive ( final CompileCommand compileCommand, final List<HeaderFilesDirective> finalHeaderFilesDirectives, final List<String> classifiers ) throws MojoExecutionException |
1019 | |
{ |
1020 | |
try |
1021 | |
{ |
1022 | 0 | MavenArchiver mavenArchiver = new MavenArchiver(); |
1023 | 0 | mavenArchiver.setArchiver( jarArchiver ); |
1024 | |
|
1025 | 0 | final File jarFile = File.createTempFile( "tmp", ".har", buildDirectory ); |
1026 | |
|
1027 | 0 | mavenArchiver.setOutputFile( jarFile ); |
1028 | |
|
1029 | 0 | for ( HeaderFilesDirective headerFilesDirective : finalHeaderFilesDirectives ) |
1030 | |
{ |
1031 | 0 | mavenArchiver.getArchiver().addDirectory( new File( headerFilesDirective.getDirectory() ), headerFilesDirective.getIncludes(), headerFilesDirective.getExcludes() ); |
1032 | 0 | } |
1033 | |
|
1034 | 0 | final MavenArchiveConfiguration mavenArchiveConfiguration = new MavenArchiveConfiguration(); |
1035 | 0 | mavenArchiveConfiguration.setAddMavenDescriptor( false ); |
1036 | |
|
1037 | 0 | mavenArchiver.createArchive( project, mavenArchiveConfiguration ); |
1038 | |
|
1039 | 0 | for ( String classifier : classifiers ) |
1040 | |
{ |
1041 | 0 | getLog().debug( "Attaching 'har' classifier=" + classifier + " file=" + jarFile ); |
1042 | 0 | projectHelper.attachArtifact( project, Const.ArtifactType.NATIVE_HEADER_ARCHIVE, classifier, jarFile ); |
1043 | 0 | } |
1044 | |
|
1045 | |
} |
1046 | 0 | catch ( Exception e ) |
1047 | |
{ |
1048 | 0 | throw new MojoExecutionException( e.getMessage() ); |
1049 | 0 | } |
1050 | 0 | } |
1051 | |
|
1052 | |
private void setupNativeLibraryEnvironment ( final CommandExecutor executor, |
1053 | |
final MakefileHelper.MakefileResponse makefileResponse ) |
1054 | |
{ |
1055 | 0 | if ( makefileResponse.hasStaticLibraryDepdendencies() ) |
1056 | |
{ |
1057 | 0 | String staticlibs = makefileResponse.getStaticLibraryList(); |
1058 | 0 | executor.addEnvironment( "ANDROID_MAVEN_PLUGIN_LOCAL_STATIC_LIBRARIES", staticlibs ); |
1059 | 0 | getLog().debug( "Set ANDROID_MAVEN_PLUGIN_LOCAL_STATIC_LIBRARIES = " + staticlibs ); |
1060 | |
} |
1061 | |
|
1062 | 0 | if ( makefileResponse.hasSharedLibraryDepdendencies() ) |
1063 | |
{ |
1064 | 0 | String staticlibs = makefileResponse.getSharedLibraryList(); |
1065 | 0 | executor.addEnvironment( "ANDROID_MAVEN_PLUGIN_LOCAL_SHARED_LIBRARIES", staticlibs ); |
1066 | 0 | getLog().debug( "Set ANDROID_MAVEN_PLUGIN_LOCAL_SHARED_LIBRARIES = " + staticlibs ); |
1067 | |
} |
1068 | 0 | } |
1069 | |
|
1070 | |
private Set<Artifact> findNativeLibraryDependencies() throws MojoExecutionException |
1071 | |
{ |
1072 | 0 | final NativeHelper nativeHelper = getNativeHelper(); |
1073 | 0 | final Set<Artifact> staticLibraryArtifacts = nativeHelper.getNativeDependenciesArtifacts( false ); |
1074 | 0 | final Set<Artifact> sharedLibraryArtifacts = nativeHelper.getNativeDependenciesArtifacts( true ); |
1075 | |
|
1076 | 0 | final Set<Artifact> mergedArtifacts = new LinkedHashSet<Artifact>(); |
1077 | 0 | filterNativeDependencies( mergedArtifacts, staticLibraryArtifacts ); |
1078 | 0 | filterNativeDependencies( mergedArtifacts, sharedLibraryArtifacts ); |
1079 | |
|
1080 | 0 | getLog().debug( "findNativeLibraryDependencies found " + mergedArtifacts.size() + ": " + mergedArtifacts.toString() ); |
1081 | |
|
1082 | 0 | return mergedArtifacts; |
1083 | |
} |
1084 | |
|
1085 | |
|
1086 | |
|
1087 | |
|
1088 | |
|
1089 | |
|
1090 | |
|
1091 | |
|
1092 | |
|
1093 | |
|
1094 | |
|
1095 | |
|
1096 | |
private void filterNativeDependencies( Set<Artifact> targetSet, Set<Artifact> source ) |
1097 | |
{ |
1098 | 0 | for ( Artifact a : source ) |
1099 | |
{ |
1100 | 0 | if ( project.getGroupId().equals( a.getGroupId() ) && project.getArtifactId().equals( a.getArtifactId() ) ) |
1101 | |
{ |
1102 | 0 | getLog().warn( "Excluding native dependency attached by this build" ); |
1103 | |
} |
1104 | |
else |
1105 | |
{ |
1106 | 0 | targetSet.add( a ); |
1107 | |
} |
1108 | 0 | } |
1109 | 0 | } |
1110 | |
|
1111 | |
|
1112 | |
|
1113 | |
|
1114 | |
|
1115 | |
|
1116 | |
|
1117 | |
|
1118 | |
private String resolveArtifactType( File file ) |
1119 | |
{ |
1120 | 0 | if ( Const.ArtifactType.NATIVE_SYMBOL_OBJECT.equals( project.getPackaging() ) || Const.ArtifactType.NATIVE_IMPLEMENTATION_ARCHIVE.equals( project.getPackaging() ) ) |
1121 | |
{ |
1122 | 0 | return project.getPackaging(); |
1123 | |
} |
1124 | |
else |
1125 | |
{ |
1126 | |
|
1127 | 0 | return file.getName().endsWith( Const.ArtifactType.NATIVE_SYMBOL_OBJECT ) ? Const.ArtifactType.NATIVE_SYMBOL_OBJECT : Const.ArtifactType.NATIVE_IMPLEMENTATION_ARCHIVE; |
1128 | |
} |
1129 | |
} |
1130 | |
|
1131 | |
|
1132 | |
|
1133 | |
|
1134 | |
|
1135 | |
|
1136 | |
|
1137 | |
|
1138 | |
|
1139 | |
|
1140 | |
|
1141 | |
|
1142 | |
|
1143 | |
|
1144 | |
protected AndroidNdk getAndroidNdk() throws MojoExecutionException |
1145 | |
{ |
1146 | |
final File chosenNdkPath; |
1147 | |
|
1148 | 0 | if ( ndkPath != null ) |
1149 | |
{ |
1150 | |
|
1151 | 0 | chosenNdkPath = ndkPath; |
1152 | |
} |
1153 | |
else |
1154 | |
{ |
1155 | |
|
1156 | 0 | chosenNdkPath = new File( getAndroidNdkHomeOrThrow() ); |
1157 | |
} |
1158 | |
|
1159 | 0 | return new AndroidNdk( chosenNdkPath ); |
1160 | |
} |
1161 | |
|
1162 | |
|
1163 | |
|
1164 | |
|
1165 | |
|
1166 | |
|
1167 | |
private String getAndroidNdkHomeOrThrow() throws MojoExecutionException |
1168 | |
{ |
1169 | 0 | final String androidHome = System.getenv( ENV_ANDROID_NDK_HOME ); |
1170 | 0 | if ( StringUtils.isBlank( androidHome ) ) |
1171 | |
{ |
1172 | 0 | throw new MojoExecutionException( "No Android NDK path could be found. You may configure it in the pom using <ndkPath>...</ndkPath> or " |
1173 | |
+ "<properties><android.ndk.path>...</android.ndk.path></properties> or on command-line using -Dandroid.ndk.path=... " |
1174 | |
+ "or by setting environment variable " + ENV_ANDROID_NDK_HOME ); |
1175 | |
} |
1176 | 0 | return androidHome; |
1177 | |
} |
1178 | |
|
1179 | |
protected final ArtifactResolverHelper getArtifactResolverHelper() |
1180 | |
{ |
1181 | 0 | if ( artifactResolverHelper == null ) |
1182 | |
{ |
1183 | 0 | artifactResolverHelper = new ArtifactResolverHelper( artifactResolver, new MavenToPlexusLogAdapter( getLog() ), project.getRemoteArtifactRepositories() ); |
1184 | |
} |
1185 | 0 | return artifactResolverHelper; |
1186 | |
} |
1187 | |
|
1188 | |
protected final NativeHelper getNativeHelper() |
1189 | |
{ |
1190 | 0 | if ( nativeHelper == null ) |
1191 | |
{ |
1192 | 0 | nativeHelper = new NativeHelper( project, dependencyGraphBuilder, getLog() ); |
1193 | |
} |
1194 | 0 | return nativeHelper; |
1195 | |
} |
1196 | |
|
1197 | |
|
1198 | |
} |