Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4937 dpurdie 1
########################################################################
2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
3
#
4
# Module name   : androidBuilder.pl
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : This program is invoked by the JATS Makefile System
10
#                 to 'build' an Android project from an AndroidStudio based
11
#                 Android project. It does this by:
12
#                   Creating a build.xml file from the Eclispe files
13
#                   Injecting properties into the build
14
#                       Create gradle.properties (Must not be version controlled)
15
#                       Create local.properties (Must not be version controlled)
16
#                   Insert external dependencies
17
#                       Jar files
18
#                       Aar files
19
#                       JNI Libraries
20
#                   Invoking 'gradle' to perform the build 
21
#
22
#                 This process requires external tool - delivered in packages
23
#                 These are:
24
#                   gradle      - Provides the core of gradle
25
#                   androidSdk  - From package rather than installed
26
#                                 This provides flexability when a new Sdk
27
#                                 is required
28
#
29
# Usage:        The utility is invoked in a controlled manner from a Jats
30
#               makefile. The call is generated by the Android Toolset
31
#               Arguments:
32
#                -verbose                   - Increase debugging
33
#                -verbose=n                 - Increase debugging
34
#                -f=manifestFile.xml        - project Manifest file
35
#                -i=path                    - Path to the interface directory
36
#                -t=[P|D]"                  - Build Type. Production or Debug
37
#                -pn=PackageName            - Package Name
38
#                -pv=PackageVersion         - Package Version
39
#                -clean                     - Will clean the build
40
#                -populate                  - Test Env and Populate 'libs'
41
#               Aguments that can be provided by the user
42
#                -Jar=name                  - Name of a Jar to include
43
#                -Aar=name                  - Name of an Aar to include
44
#                -lname                     - Name of a Jats library to include
45
#                -Lname                     - Name of a 3rd party library to include
46
#
47
# Note: This function may be provided by several packages, 
48
#       thus the interface must not change - this include the name of 
49
#       this file. See the AndroidBuilder package too.
50
#
51
#
52
#......................................................................#
53
 
54
require 5.008_002;
55
use strict;
56
use warnings;
57
 
58
use Getopt::Long qw(:config pass_through);
59
use File::Path;
60
 
61
use JatsError;
62
use JatsSystem;
63
use JatsEnv;
64
use FileUtils;
65
use JatsProperties;
66
use JatsVersionUtils;
67
use ReadBuildConfig;
68
use JatsCopy;
69
use ArrayHashUtils;
70
 
71
#
72
#   Globals
73
#   Command line arguments
74
#
75
my $opt_verbose = $ENV{GBE_VERBOSE};
76
my $opt_buildFile;
77
my $opt_interface;
78
my $opt_gbetype = 'P';
79
my $opt_clean;
80
my $opt_pkgname;
81
my $opt_pkgversion;
82
my $opt_platform;
83
my $opt_populate;
84
my @opt_jlibs;                  # List of Jats Libraries
85
my @opt_elibs;                  # List of 3rd party libraries
86
my @opt_jars;                   # List of JARs
87
my @opt_aars;                   # List of AARs
88
 
89
#
90
#   Configuration
91
#   Map JATS platforms to Shared library targets
92
#
93
my %SharedLibMap = (
94
    'ANDROIDARM'    => 'armeabi',
95
    'ANDROIDMIPS'   => 'mips',
96
    'ANDROIDX86'    => 'x86',
97
    );
98
 
99
our $GBE_HOSTMACH;              # Sanity Test of machine type
100
our $GBE_MAKE_TARGET;           # Current build target
101
 
102
my $androidJars;                # Root of injected JARs and AARs
103
my $androidJniBase;             # Root of injected JNI files
104
my $androidJniProd;             # Root of injected JNI files - Prod
105
my $androidJniDebug;            # Root of injected JNI files - Debug
106
my $androidBuildSuffix = '';    # Prefix build commands
107
 
108
#-------------------------------------------------------------------------------
109
# Function        : Main Entry Point 
110
#
111
# Description     : Main entry to this program
112
#
113
# Inputs          : @ARGV           - Array of command line arguments
114
#                                     See file header
115
#
116
# Returns         : 0               - No Error
117
#                   1               - Error encountered    
118
#
119
InitFileUtils();
120
ErrorConfig( 'name'    => 'ANDROIDBUILDER',
121
             'verbose' => $opt_verbose);
122
$opt_verbose = $::ScmVerbose;               # Get the calculated verbosity level
123
 
124
#
125
#   Install local signal handlers to process GetOptions messages
126
#
127
local $SIG{__WARN__} = sub { ReportError('AndroidBuilder.' . "@_"); };
128
local $SIG{__DIE__} = sub { ReportError('AndroidBuilder.' . "@_"); };
129
my $result = GetOptions (
130
                "verbose:+"     => \$opt_verbose,       # flag
131
                "f=s"           => \$opt_buildFile,     # string
132
                "i=s"           => \$opt_interface,     # Interface directory
133
                "t=s"           => \$opt_gbetype,       # string
134
                "pn=s"          => \$opt_pkgname,       # string
135
                "pv=s"          => \$opt_pkgversion,    # string
136
                "pf=s"          => \$opt_platform,      # string
137
                "clean"         => \$opt_clean,         # flag
138
                "populate"      => \$opt_populate,      # flag
139
                "Jar=s"         => \@opt_jars,
140
                "Aar=s"         => \@opt_aars,
141
                );
142
 
143
#
144
#   Restore signal handlers and report parse errors
145
#
146
$SIG{__WARN__} = 'DEFAULT';
147
$SIG{__DIE__} = 'DEFAULT';
148
Error('AndroidBuilder. Invalid call options detected') if (!$result);
149
 
150
#
151
#   Process remaining arguments
152
#   Only --Lname and --lname are valid
153
#
154
foreach my $arg (@ARGV) {
155
    if ($arg =~ m~^[-]{1,2}l(.*)~) {
156
        push @opt_jlibs, $1;
157
    } elsif ($arg =~ m~^[-]{1,2}L(.*)~) {
158
        push @opt_elibs, $1;
159
    } else {
160
        ReportError("Invalid option: $arg");
161
    }
162
}
163
ErrorDoExit();
164
 
165
#
166
#   Sanity Test
167
#
168
ReportError ("Gradle build file not specified") unless ( defined $opt_buildFile); 
169
ReportError ("Gradle build file not found: $opt_buildFile") unless ( -f $opt_buildFile);
170
 
171
ReportError ("Interface directory not specified") unless ( defined $opt_interface);
172
ReportError ("Interface directory not found: $opt_interface") unless ( -d $opt_interface);
173
 
174
ReportError ("Package Name not specified") unless ( defined $opt_pkgname); 
175
ReportError ("Package Version not specified") unless ( defined $opt_pkgversion); 
176
 
177
EnvImport('GBE_HOSTMACH');
178
ReportError ("AndroidStudioBuilder is only supported under win32","This machine is: ".$::GBE_HOSTMACH ) unless ( $::GBE_HOSTMACH eq 'win32' );
179
ReportError ("Platform not found") unless ( defined $opt_platform );
180
 
181
ErrorDoExit();
182
 
183
#
184
#   Basic setup
185
#
186
$androidBuildSuffix = ($opt_gbetype eq 'P') ? 'Release' : 'Debug';
187
 
188
#
189
#   The user provides the root build.gradle file
190
#   There MUST be a settings.gradle in the same directory
191
#       This is a JATS assumption - subject to change
192
#   There will be some other files there too
193
#   Calculate the root of the project
194
#
195
$opt_buildFile = RelPath(AbsPath($opt_buildFile));
196
my $project_root = StripFileExt($opt_buildFile);
197
   $project_root = '.' unless $project_root;
198
my $project_settingsFile = catfile($project_root, 'settings.gradle');
199
 
200
Message ("Project Base:" . Getcwd());
201
Message ("Project Root:" . $project_root);
202
Verbose ("Project Settings file:" . $project_settingsFile);
203
 
204
#
205
#   Directories to store Jar's, Aar's and JNI shared libarares
206
#   are created in the interface directory
207
#
208
$androidJars      = catdir($opt_interface, 'jatsLibs');
209
$androidJniBase   = catdir($opt_interface, 'jatsJni');
210
$androidJniProd   = catdir($androidJniBase, 'Release');
211
$androidJniDebug  = catdir($androidJniBase, 'Debug');
212
 
213
Verbose ("Interface:" . $opt_interface);
214
Verbose ("Android Jars: $androidJars");
215
Verbose ("Android JNI : $androidJniBase");
216
 
217
Error ("Gradle settings file not found: $project_settingsFile") unless ( -f $project_settingsFile);
218
 
219
#
220
#   Essential tool
221
#       gradle     - setup 
222
#                    GRADLE_USER_HOME
223
#                    JAVA_HOME
224
#                    
225
ReadBuildConfig( $opt_interface, $opt_platform, '--NoTest' );
226
 
227
my $gradleTool = getToolInfo('gradle', 'JAVA_VERSION', 'GRADLE_BIN');
228
my $gradleBinDir = catdir($gradleTool->{PKGBASE}, $gradleTool->{TOOLROOT}, $gradleTool->{GRADLE_BIN});
229
 
230
#
231
#   Setup a gradle home
232
#   Its used to cache stuff - create it within the interface directory
233
#
234
my $gradleHomeTarget = CleanPath(FullPath(catdir($opt_interface, 'gradleUserHome')));
235
mkpath($gradleHomeTarget, 0, 0775) 
236
    unless ( -d $gradleHomeTarget);
237
$ENV{GRADLE_USER_HOME} = $gradleHomeTarget;
238
Verbose("GRADLE_USER_HOME:", $ENV{GRADLE_USER_HOME});
239
 
240
#
241
#   Setup the required version of Java for the tool
5289 dpurdie 242
#   Force JAVA_OPTS to set Min/Max Heap
243
#       Use JAVA_OPTS because
244
#           _JAVA_OPTIONS causes ssytem to emit a lot of warnings that _JAVA_OPTIONS is being used
245
#           Use of org.gradle.jvmargs in gradle.properties causes warnins about forking speed
246
#           Fixing the max size will provide consistent builds
247
#           Perhaps one day it will be configured 
4937 dpurdie 248
#
249
my $javaVersion = $gradleTool->{JAVA_VERSION};
250
ReportError ("$javaVersion not defined.", "Building ANDROID requires $javaVersion be installed and correctly configured.") 
251
    unless $ENV{$javaVersion};
252
$ENV{JAVA_HOME}=$ENV{$javaVersion};
5289 dpurdie 253
$ENV{JAVA_OPTS} = '-Xms256m -Xmx1024m';
4937 dpurdie 254
 
255
#
256
#   Essential tool
257
#       androidSdk  - setup path to the android executable
258
#
259
my $androidSdkTool = getToolInfo('androidSdk');
260
my $androidSdk = catdir($androidSdkTool->{PKGBASE}, $androidSdkTool->{TOOLROOT} );
261
Verbose ("Android SDK : $androidSdk");
262
ReportError("Tool Package 'androidSdk' - Invalid SDK Basedir", "Sdk Base: $androidSdk" )
263
    unless -d ($androidSdk);
264
 
265
#   Essential tool
266
#       androidGradleRepo   - A repo of gradle plugings for android
267
#
268
my $androidGradleRepo = getToolInfo('androidGradleRepo');
269
my $gradleMavenRepo = catdir($androidGradleRepo->{PKGBASE}, $androidGradleRepo->{TOOLROOT});
270
Verbose ("Maven Repo. Gradle support for android : $gradleMavenRepo");
271
 
272
ErrorDoExit();
273
 
274
#
275
#   Create a gradle file with JATS provided version information
276
#   and paths for use within the gradle build.
277
#
278
#   Always do this as the 'clean' will need them
279
#
280
createGradleFiles($opt_clean);
281
 
282
#
283
#   Clean out any build artifacts
284
#
285
if ($opt_clean)
286
{
287
    #
288
    #   Invoke GRADLE on the build script - if present
289
    #
290
    Message ("Clean the existing build");
291
    runGradle ('clean');
292
    deleteGeneratedFiles();
293
    exit 0;
294
}
295
 
296
#
297
#   If we are only populating the build then we 
298
#   need to inject dependencies.
299
#
300
if ($opt_populate)
301
{
302
    deleteInjectedFiles();
303
    injectDependencies();
304
 
305
    Verbose ("Populate complete");
306
    exit 0;
307
}
308
 
309
#
310
#   Build the Android project through gradle
311
#
312
Message ("Build the android project: $androidBuildSuffix");
313
my $rv = runGradle( 'assemble' . $androidBuildSuffix);
314
Error("Cannot build AndroidStudio project") if $rv;
315
exit(0);
316
 
317
#-------------------------------------------------------------------------------
318
# Function        : runGradle 
319
#
320
# Description     : Run gradle to build the project
321
#                   Generate a command like:
322
#                   PathToGradle/gradle --offline -I SomePath/init.gradle <task> 
323
#
324
#                   Use an init-script to inject a sanity test into the build
325
#                   Ensure that the user is using our version numbers.
326
#
327
# Inputs          : task        - Task to run
328
#
329
# Returns         : Returns the error code of the build
330
#
331
sub runGradle
332
{
333
    my ($task) = @_;
334
    Verbose ("runGradle: $task");
335
 
336
    #   The Windows batch file can run in debug mode
337
    #   Make sure that it doesn't by default
338
    $ENV{DEBUG} = "" unless $opt_verbose;
339
 
340
    my $gradleProg = catdir($gradleBinDir, 'gradle');
341
    Verbose ("GradleProg: $gradleProg");
342
 
343
    #
344
    #   Locate the 'init.gradle' script
345
    #   Its co-located with this script
346
    #
347
    my $initScript = catdir(StripFileExt(__FILE__), 'init.gradle');
348
    Verbose ("Gradle Init Script: $initScript");
349
 
350
    #
351
    #   Build up the arg list
352
    #
353
    my @gradleArgs;
354
    push (@gradleArgs, '--offline');
355
#    push (@gradleArgs, '--info');
356
#    push (@gradleArgs, '--debug');
5307 dpurdie 357
#    push (@gradleArgs, '--stacktrace');
4937 dpurdie 358
    push (@gradleArgs, '--info') if $opt_verbose;
359
    push (@gradleArgs, '--debug') if ($opt_verbose > 2);
5307 dpurdie 360
    push (@gradleArgs, '--stacktrace') if ($opt_verbose > 3);
4937 dpurdie 361
    push (@gradleArgs, '-I', $initScript) unless ($task =~ m/clean/); 
5307 dpurdie 362
    push (@gradleArgs, '-p', $project_root);
4937 dpurdie 363
 
364
    my $rv = System('--NoShell', '--NoExit', $gradleProg, @gradleArgs, $task);
365
    return $rv;
366
}
367
 
368
#-------------------------------------------------------------------------------
369
# Function        : createGradleFiles 
370
#
371
# Description     : Calculate Version information
372
#                       gradle.properies
373
#                       local.properties
374
#
375
# Inputs          : quiet           - No output 
376
#
377
# Returns         : Nothing
378
#
379
sub createGradleFiles
380
{
381
    my ($quiet) = @_;
382
 
383
    #
384
    #   Generate Package Versioning information   
385
    #       Need a text string and a number
386
    #       Generate the 'number' from the version number
387
    #
388
    my $version_text;
389
    my $version_num;
390
 
391
    $version_text = $opt_pkgversion;
392
    my ($major, $minor, $patch, $build )= SplitVersion($opt_pkgversion);
393
    foreach my $item ($major, $minor, $patch, $build)
394
    {
395
        Error("Package version has invalid form. It contains non-numeric parts", $item)
396
            unless ( $item =~ m~^\d+$~);
397
    }
398
    $version_num = ($major << 24) + ($minor << 16) + ($patch << 8) + $build;
399
 
400
    Message ("Project Version Txt:" . $version_text) unless $quiet;
401
    Message ("Project Version Num:" . $version_num) unless $quiet;
402
 
403
    #
404
    #   Create the gradle.properties file
405
    #       It needs to be in the projects root directory
406
    #
407
    my $gradleProperies = catfile($project_root,'gradle.properties');
408
    Message ("Create gradle.properties file: " . $gradleProperies) unless $quiet;
409
 
410
    my $data = JatsProperties::New();
411
 
412
    $data->setProperty('GBE_VERSION_NAME' , $version_text);
413
    $data->setProperty('GBE_VERSION_CODE' , $version_num);
414
 
415
    $data->setProperty('GBE_JARLIBS'        , NicePath($androidJars));
416
    $data->setProperty('GBE_JNI_RELEASE'    , NicePath($androidJniProd));
417
    $data->setProperty('GBE_JNI_DEBUG'      , NicePath($androidJniDebug));
418
    $data->setProperty('GBE_GRADLE_REPO'    , NicePath($gradleMavenRepo));
419
 
420
    $data->store( $gradleProperies );
421
 
422
    #
423
    #   Create the local.properties file
424
    #       It needs to be in the projects root directory
425
    #
426
    #   May be able to do without this file - iff we set ANDROID_HOME
427
    #
428
    my $localProperies = catfile($project_root,'local.properties');
429
    Message ("Create local.properties file: " . $localProperies) unless $quiet;
430
 
431
    $data = JatsProperties::New();
432
    $data->setProperty('sdk.dir' , NicePath($androidSdk));
433
    $data->store( $localProperies );
434
}
435
 
436
#-------------------------------------------------------------------------------
437
# Function        : injectDependencies 
438
#
439
# Description     : Inject dependencies
440
#
441
#                   The android build can make use of files in a specific directory
442
#                   Place Jar and Aar files in a specific directory under the root of the project
443
#                   Use a directory called jatsLibs
444
#                   There are two types of files that can be placed in that directory
445
#                   These appear to be:
446
#                       1) .jar files
447
#                       2) .aar files
448
#
449
#                   NDK files will be process automatically by the builder, once the build is made
450
#                   aware of the location. We are not using the AndroidStudio default location
451
#                   Place them into jatsJni within the project root
452
#                       1) Shared libraries provided by NDK components
453
#
454
#                   Need to keep the production and debug JNI files seperate
455
#
456
#                   The gradle dependency processing needs both production and
457
#                   debug dependencies to be present at all times
458
#                   
459
#                   Create three areas:
460
#                       jatsLibs        - Prod and Debug Jars and Ars
461
#                       jatsJniDebug    - Debug JNI files
462
#                       jatsJniProd     - Production JNI files
463
#
464
# Inputs          : 
465
#
466
# Returns         : 
467
#
468
sub injectDependencies
469
{
470
    my @jlist;                  # List of JARs from default directories
471
    my @jpathlist;              # List of JARs from named directories
472
    my @alist;                  # List of AARs from default directories
473
    my @apathlist;              # List of AARs from named directories
474
    my @libListProd;            # List of production libraries
475
    my @libListDebug;           # List of debug libraries
476
    my @platformParts;          # Platforms Parts
477
 
4990 dpurdie 478
    my @jarSearch;              # Search paths - diagnostic display
479
    my @aarSearch;
480
    my @libSearch;
4937 dpurdie 481
 
4990 dpurdie 482
 
4937 dpurdie 483
    #
484
    #   Only if we need to do something
485
    #
486
    return unless (@opt_jars || @opt_aars || @opt_elibs || @opt_jlibs);
487
 
488
    #
489
    #   Determine the list of platformm parts
490
    #   This is where 'lib' files will be found
491
    #
492
    @platformParts = getPlatformParts();
493
    Verbose("Platform Parts", @platformParts);
494
 
495
    #
496
    #   Create search entries suitable for the CopyDir
497
    #   We will delete entries as the files are copied
498
    #   Allow for:
499
    #       jar/aar files to have a .jar /.aar suffix (optional)
500
    #       jar/aar files to have path specified with a package
501
    #
502
    #   Split into two lists ( per type ): 
503
    #       Those with a path and those without
504
    #
505
    foreach my $item ( @opt_jars) {
506
        $item =~ s~\.jar~~i;
507
        if ($item =~ m~/~) {
508
            UniquePush \@jpathlist, $item;
509
        } else {
510
            UniquePush \@jlist, $item;
511
        }
512
    }
513
 
514
    foreach my $item ( @opt_aars) {
515
        $item =~ s~\.aar~~i;
516
        if ($item =~ m~/~) {
517
            UniquePush \@apathlist, $item;
518
        } else {
519
            UniquePush \@alist, $item;
520
        }
521
    }
522
 
523
    #   Shared libraries
524
    #   Create full names
525
    foreach my $item ( @opt_elibs) {
526
        UniquePush \@libListDebug, 'lib' . $item . '.so';
527
        UniquePush \@libListProd,  'lib' . $item . '.so';
528
    }
529
 
530
    foreach my $item ( @opt_jlibs) {
531
        UniquePush \@libListDebug, 'lib' . $item . 'D.so';
532
        UniquePush \@libListProd , 'lib' . $item . 'P.so';
533
    }
534
 
535
    #
536
    #   Where does it go
537
    #       JARs/AARs - ROOT/jatsLibs
538
    #       LIBS      - ROOT/jatsJni
539
    #
540
    #   Scan all external packages, and the interface directory
541
    #       Transfer in the required file types
542
    #
543
    my @pkg_paths = getPackagePaths("--Interface=$opt_interface");
544
    foreach my $pkg ( @pkg_paths)
545
    {
546
        #
547
        #   Copy in all JAR files found in dependent packages
548
        #   Need to allow for Jars that have a P/D suffix as well as those that don't
549
        #
550
        my $jarDir = catdir($pkg,'jar');
4990 dpurdie 551
        push @jarSearch, $jarDir;
4937 dpurdie 552
        if (-d $jarDir && @jlist)
553
        {
554
            Verbose("Jar Dir Found found", $jarDir);
555
            Message ("Copy in: $jarDir");
556
 
557
            #
558
            #   Create a matchlist from the JAR list
559
            #   Create a regular expresssion to find a suitable file
560
            #
561
            my @mlist;
562
            foreach  ( @jlist) {
563
                push @mlist, $_ . '.jar|' . $_ . 'P.jar|'. $_ . 'D.jar';
564
            }
565
            CopyDir ( $jarDir, $androidJars,
566
                        'MatchRE' => \@mlist,
567
                        'Log' => $opt_verbose + 1,
568
                        'SymlinkFiles' => 1,
569
                        'Examine' => sub 
570
                            {
571
                                my ($opt) = @_;
572
                                my $baseName = $opt->{file};
573
                                $baseName =~ s~\.jar~~;
574
                                $baseName =~ s~[PD]$~~;
575
                                ArrayDelete \@jlist, $baseName;
576
                                return 1;
577
                            },
578
                    );
579
        }
580
 
581
        #
582
        #   Copy in JARs specified by a full pathname
583
        #   Need to allow for Jars that have a P/D suffix as well as those that don't
584
        #
585
        my @jpathlistBase = @jpathlist;
586
        foreach my $file (@jpathlistBase) 
587
        {
588
            foreach my $suffix ( '', 'P' ,'D')
589
            {
590
                my $jarFile = catdir($pkg, $file . $suffix . '.jar');
4990 dpurdie 591
                push @jarSearch, $jarFile;
4937 dpurdie 592
                if (-f $jarFile)
593
                {
594
                    Verbose("Jar File Found found", $jarDir);
595
                    Message ("Copy in: $jarFile");
596
                    CopyFile ( $jarFile, $androidJars,
597
                                'Log' => $opt_verbose + 1,
598
                                'SymlinkFiles' => 1,
599
                             );
600
                    ArrayDelete \@jpathlist, $file;
601
                }
602
            }
603
        }
604
 
605
        #
606
        #   Copy in AAR files found in dependent packages
607
        #   Need to allow for both AAR files with a -debug/-release suffix 
608
        #   as well as those without
609
        #
610
        foreach my $part (@platformParts)
611
        {
612
            my $aarDir = catdir($pkg,'lib/' . $part);
4990 dpurdie 613
            push @aarSearch, $aarDir;
4937 dpurdie 614
            if (-d $aarDir && @alist)
615
            {
616
                Verbose("Library Dir Found found", $aarDir);
617
                Message ("Copy in: $aarDir");
618
 
619
                #
620
                #   Create a matchlist from the AAR list
621
                #   Create a regular expresssion to find a suitable file
622
                #
623
                my @mlist;
624
                foreach  ( @alist) {
625
                    push @mlist, $_ . '.aar|' . $_ . '-debug.aar|' . $_ . '-release.aar';
626
                }
627
 
628
                CopyDir ( $aarDir, $androidJars,
629
                            'MatchRE' => \@mlist,
630
                            'Log' => $opt_verbose + 1,
631
                            'SymlinkFiles' => 1,
632
                            'Examine' => sub 
633
                                {
634
                                    my ($opt) = @_;
635
                                    my $baseName = $opt->{file};
636
                                    $baseName =~ s~\.aar$~~;
637
                                    $baseName =~ s~-release$~~;
638
                                    $baseName =~ s~-debug$~~;
639
                                    ArrayDelete \@alist, $baseName;
640
                                    return 1;
641
                                },
642
                            );
643
            }
644
        }
645
 
646
 
647
        #
648
        #   Copy in AAR files specified by a full pathname
649
        #   Need to allow for both AAR files with a -debug/-release suffix 
650
        #   as well as those without
651
        #
652
        my @apathlistBase = @apathlist;
653
        foreach my $file (@apathlistBase) 
654
        {
655
            foreach my $suffix ( '', '-release', '-debug')
656
            {
657
                my $aarFile = catdir($pkg, $file . $suffix . '.aar');
4990 dpurdie 658
                push @aarSearch, $aarFile;
4937 dpurdie 659
                if (-f $aarFile)
660
                {
661
                    Verbose("Aar File Found found", $aarFile);
662
                    Message ("Copy in: $aarFile");
663
                    CopyFile ( $aarFile, $androidJars,
664
                                'Log' => $opt_verbose + 1,
665
                                'SymlinkFiles' => 1,
666
                             );
667
                    ArrayDelete \@apathlist, $file;
668
                }
669
            }
670
        }
671
 
672
        #
673
        #   Build up the Shared Library structure as used by JNI
674
        #   Note: Only support current JATS format
675
        #   Copy in .so files and in to process massage the pathname so that
676
        #   it confirms to that expected by the Android Project
677
        #
678
        my $libDir = catdir($pkg, 'lib');
4990 dpurdie 679
        push @libSearch, $libDir;
4937 dpurdie 680
        if (-d $libDir && @libListProd)
681
        {
682
            Verbose("Lib Dir Found found", $libDir);
683
            Message ("Copy in: $libDir");
684
            CopyDir ( $libDir, $androidJniProd,
685
                        'Match' => \@libListProd,
686
                        'Log' => $opt_verbose + 1,
687
                        'SymlinkFiles' => 1,
688
                        'Examine' => sub 
689
                            { 
690
                                my ($opt) = @_;
691
                                foreach my $platform ( keys %SharedLibMap ) {
692
                                    my $replace = $SharedLibMap{$platform};
693
                                    if ($opt->{'target'} =~ s~/$platform/~/$replace/~)
694
                                    {
695
                                        ArrayDelete \@libListProd, $opt->{file};
696
                                        return 1;
697
                                    }
698
                                }
699
                                return 0;
700
                            },
701
                    );
702
        }
703
 
704
        if (-d $libDir && @libListDebug)
705
        {
706
            Verbose("Lib Dir Found found", $libDir);
707
            Message ("Copy in: $libDir");
708
            CopyDir ( $libDir, $androidJniDebug,
709
                        'Match' => \@libListDebug,
710
                        'Log' => $opt_verbose + 1,
711
                        'SymlinkFiles' => 1,
712
                        'Examine' => sub 
713
                            { 
714
                                my ($opt) = @_;
715
                                foreach my $platform ( keys %SharedLibMap ) {
716
                                    my $replace = $SharedLibMap{$platform};
717
                                    if ($opt->{'target'} =~ s~/$platform/~/$replace/~)
718
                                    {
719
                                        ArrayDelete \@libListDebug, $opt->{file};
720
                                        return 1;
721
                                    }
722
                                }
723
                                return 0;
724
                            },
725
                    );
726
        }
727
 
728
    }
729
 
730
    #
731
    #   Report files that could not be located. They were deleted from the lists
732
    #   as they were processed
733
    #
4990 dpurdie 734
    if (@jlist || @jpathlist || @alist || @apathlist ||  @libListProd || @libListDebug )
4937 dpurdie 735
    {
4990 dpurdie 736
        ReportError("External dependencies not found:", @jlist , @jpathlist , @alist , @apathlist ,  @libListProd , @libListDebug);
737
        if (@jlist || @jpathlist)
738
        {
739
            ReportError("Jar Search Path", @jarSearch);
740
        }
741
 
742
        if (@alist || @apathlist)
743
        {
744
            ReportError("Aar Search Path", @aarSearch);
745
        }
746
 
747
        if ( @libListProd || @libListDebug)
748
        {
749
            ReportError("Lib Search Path", @libSearch);
750
        }
751
    ErrorDoExit();
4937 dpurdie 752
    }
753
}
754
 
755
#-------------------------------------------------------------------------------
756
# Function        : deleteGeneratedFiles 
757
#
758
# Description     : Delete files that we generate
759
#
760
# Inputs          : 
761
#
762
# Returns         : 
763
#
764
sub deleteGeneratedFiles
765
{
766
    #
767
    #   Delete files that we will create
768
    #
769
    my @deleteList = qw(local.properties gradle.properties);
770
    foreach my $file (@deleteList)
771
    {
772
        Verbose ("Deleting $project_root/$file");
773
        unlink catfile($project_root, $file);
774
    }
775
 
776
}
777
 
778
#-------------------------------------------------------------------------------
779
# Function        : deleteInjectedFiles 
780
#
781
# Description     : Delete files that we inject
782
#
783
# Inputs          : 
784
#
785
# Returns         : 
786
#
787
sub deleteInjectedFiles
788
{
789
    #
790
    #   Remove the jatsJars and JatsJni directories
791
    #   These are created by this tool
792
    #
793
    Verbose("RmDirTree($androidJars)");
794
    RmDirTree($androidJars);
795
 
796
    Verbose("RmDirTree($androidJniBase)");
797
    RmDirTree($androidJniBase);
798
}
799
 
800
 
801
#-------------------------------------------------------------------------------
802
# Function        : NicePath 
803
#
804
# Description     : Process a path and return one that is
805
#                       An absolute Path
806
#                       Uses '/'
807
#
808
# Inputs          : path            - Path to process
809
#
810
# Returns         : A Nice version of path
811
#
812
sub NicePath
813
{
814
    my ($path) = @_;
815
    $path = FullPath($path);
816
    $path =~ s~\\~/~g;
817
    $path = CleanPath($path);
818
    return $path;
819
}
820