Subversion Repositories DevTools

Rev

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