Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
########################################################################
2
# Copyright (C) 2007 ERG Limited, All rights reserved
3
#
4
# Module name   : jats.sh
5
# Module type   : Makefile system
6
# Compiler(s)   : n/a
7
# Environment(s): jats
8
#
9
# Description   : Top level Makefile supervisor
10
#                 The function of this program is to call the target makefiles
11
#                 in a sutable manner.
12
#
13
# History       : Once upon a time this was done with another makefile and
14
#                 some really ugle shell, embedded within the makefile
15
#                 This had a number of limitations, including
16
#                   - Limited to makefile command line syntax
17
#                   - Overly complex makefile
18
#                   - Slow execution
19
#
20
# Usage:
21
#
22
#......................................................................#
23
 
255 dpurdie 24
require 5.006_001;
227 dpurdie 25
use strict;
26
use warnings;
27
 
28
use Pod::Usage;                             # For help support
29
use JatsError;
30
use JatsSystem;
31
use JatsEnv;
32
use JatsMakeInfo;
33
use ReadBuildConfig qw(:All);
34
use Getopt::Long;
35
use FileUtils;
36
use ArrayHashUtils;
37
use JatsDPackage;
38
 
39
my $VERSION = "1.0.0";                      # Update this
40
 
41
#
42
#   Options
43
#
44
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
45
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
46
my $opt_help = 0;
47
my $opt_silent = 1;
48
my $opt_default;
49
 
50
#
51
#   Global variables
52
#
53
our %cf_info;
54
our $GBE_TOOLS;                             # Base of tools
55
our $GBE_ABT;                               # Optional ABT indication
56
our $GBE_PLATFORM;                          # Optional GBE_PLATFORM
57
our $ScmInterface;                          # Current interface directory
58
our $ScmRoot;                               # Build root
59
 
60
my $Tags;                                   # Reference to hash of tags
61
my %defs;                                   # Make definitions
62
my @defs;                                   # Make definitions
63
my @targets;                                # Make targets
64
my $makelib;                                # Path to makelib.pl
65
my $update = 0;                             # Makefiles updated
66
my $build_error = 0;                        # Build Error encountered
67
my $tlen = 4;                               # Max length of targets
68
my %common_cmd;                             # Short circuit some commands
69
my %gbe_platform;                           # Nice form of GBE_PLATFORM
70
 
71
#
72
#   Known commands
73
#   A hash of known commands an information about the commands
74
#       common      - Command is not executed for Debug and Production
75
#                     Flags: 1 - Command not executed for debug+prod
76
#                     Flags: 2 - Command is only executed ONCE per platform
77
#       local       - The command is handled locally.
78
#       nomakecheck - Don't check for makefile being out of date
79
#       IFLAG       - iteration flag,
80
#                       0   No external dependencies.
81
#                       1   Source dependency list.
82
#                       2   Shared library dependency list.
83
#                       3   Application dependency list.
84
#   Note:   gmake attempts to build includes prior to invoking other
85
#   rules when the source is non-existent, which can/do fail as a
86
#   result of the prereq rules not being executed, the IFLAG inhabits
87
#   includes during these prereq rules.
88
#
89
my %composite_commands = (
90
    #
91
    #   Composite commands
92
    #
93
    'all'                   => [ 'install', 'package', 'deploy' ] ,
94
    'install'               => [ 'build' ] ,
95
    'build'                 => [ 'mkdepends', 'generate', 'install_hdr', 'depend',
96
                                 'make_lib', 'install_lib', 'make_install_shlib',
97
                                 'make_prog', 'make_test', 'install_prog', 'install_class' ] ,
98
    'lint'                  => [ 'mkdepends', 'generate_debug', 'install_hdr_debug',
99
                                 'lint_lib', 'lint_shlib', 'lint_prog' ] ,
100
    'ctags'                 => [ 'mkdepends', 'generate_debug', 'ctags_debug' ] ,
101
    'test'                  => [ 'make_test' ] ,
102
    'mkdepends'             => [ 'makefiles', 'make_init'] ,
103
 
104
    );
105
 
106
my %commands = (
107
    #
108
    #   Basic commands / phases of the build process
109
    #   This should be a list of all known makefile commands
110
    #
111
    'make_usage'            => { 'tag' => 0, 'local' => \&DoHelp },
112
    'help'                  => { 'tag' => 0, 'local' => \&DoHelp },
113
    'rebuild'               => { 'tag' => 0, 'local' => \&TestMakeFiles },
114
    'makefiles'             => { 'tag' => 0, 'local' => \&TestMakeFiles },
115
    'unmakefiles'           => { 'tag' => 0, 'local' => \&UnMakeFiles },
116
    'make_init'             => { 'tag' => 1, 'nomakecheck' => 1, 'common' => 3, },
117
    'generate'              => { 'tag' => 1 },
118
    'install_hdr'           => { 'tag' => 1 },
261 dpurdie 119
    'depend'                => { 'tag' => 1, 'unless' => ['NODEPEND','EXPERT'] },
227 dpurdie 120
    'make_lib'              => { 'tag' => 1, 'IFLAG' => 1 },
261 dpurdie 121
    'make_mlib'             => { 'tag' => 1, 'IFLAG' => 1 },
227 dpurdie 122
    'install_lib'           => { 'tag' => 1, 'IFLAG' => 1 },
123
    'make_install_shlib'    => { 'tag' => 1, 'IFLAG' => 2 },
124
    'make_prog'             => { 'tag' => 1, 'IFLAG' => 3 },
125
    'make_test'             => { 'tag' => 1, 'IFLAG' => 3 },
126
    'install_prog'          => { 'tag' => 1, 'IFLAG' => 3 },
127
    'install_class'         => { 'tag' => 1 },
128
    'package'               => { 'tag' => 1, 'IFLAG' => 3 },
129
    'deploy'                => { 'tag' => 1, 'IFLAG' => 1 },
130
 
131
    #
261 dpurdie 132
    #   Special
133
    #   make_dir is directly invoked by jmake. It doesn't need
134
    #   to be a part of a command sequence
135
    #
136
    'make_dir'              => { 'nomakecheck' => 1, 'tag' => 1 },
137
 
138
    #
227 dpurdie 139
    #   Basic commands, that appear to be unused in composite commands
140
    #   Not too sure why
141
    #
142
    'make_script'           => { 'commands' => [], 'tag' => 1 },
143
 
144
    #
145
    #   Lint related targets
146
    #
147
    'lint_lib',             => { 'tag' => 'make_lib'            , 'IFLAG' => 1 },
148
    'lint_shlib',           => { 'tag' => 'make_install_shlib'  , 'IFLAG' => 2 },
149
    'lint_prog'             => { 'tag' => 'make_prog'           , 'IFLAG' => 3 },
150
 
151
    #
152
    #   Following commands should NOT be a part of a composite command
153
    #
154
    'run_tests'             => { 'nomakecheck' => 1, 'tag' => 1, 'IFLAG' => 3},
155
    'run_unit_tests'        => { 'nomakecheck' => 1, 'tag' => 1, 'IFLAG' => 3},
156
 
157
    'clean'                 => { 'nomakecheck' => 1},
158
    'clobber'               => { 'nomakecheck' => 1},
159
    'rmlitter'              => { 'nomakecheck' => 1},
160
    'unbuild'               => { 'nomakecheck' => 1},
261 dpurdie 161
    'undepend'              => { 'nomakecheck' => 1 , 'tag' => 'depend'},
162
    'ungenerate'            => { 'nomakecheck' => 1 , 'tag' => 'generate'},
227 dpurdie 163
    'uninstall'             => { 'nomakecheck' => 1},
164
    'uninstall_class'       => { 'nomakecheck' => 1},
261 dpurdie 165
    'uninstall_hdr'         => { 'nomakecheck' => 1 , 'tag' => 'install_hdr'},
166
    'uninstall_lib'         => { 'nomakecheck' => 1 , 'tag' => 'install_lib'},
167
    'uninstall_prog'        => { 'nomakecheck' => 1 , 'tag' => 'install_prog'},
168
    'unmake_lib'            => { 'nomakecheck' => 1 , 'tag' => 'make_mlib'},
169
    'unmake_mlib'           => { 'nomakecheck' => 1 , 'tag' => 'make_mlib'},
170
    'unmake_prog'           => { 'nomakecheck' => 1 , 'tag' => 'make_prog'},
171
    'unmake_script'         => { 'nomakecheck' => 1 , 'tag' => 'make_script'},
172
    'unmake_test'           => { 'nomakecheck' => 1 , 'tag' => 'make_test'},
227 dpurdie 173
    'unobj'                 => { 'nomakecheck' => 1},
261 dpurdie 174
    'unpackage'             => { 'nomakecheck' => 1 , 'tag' => 'package'},
175
    'unmake_dir'            => { 'nomakecheck' => 1 , 'tag' => 'make_dir'},
227 dpurdie 176
 
177
    );
178
#    DebugDumpData ("Commands", \%commands);
179
 
180
#-------------------------------------------------------------------------------
181
# Function        : Mainline Entry Point
182
#
183
# Description     :
184
#
185
# Inputs          :
186
#
187
 
188
#
189
#   Parse the user options
190
#
191
my $result = GetOptions (
261 dpurdie 192
                "help:+"        => \$opt_help,              # flag, multiple use allowed
193
                "manual:3"      => \$opt_help,              # flag, multiple use allowed
194
                "verbose:+"     => \$opt_verbose,           # flag, multiple use allowed
195
                "d|debug:+"     => \$opt_debug,             # flag, multiple use allowed
227 dpurdie 196
                "default=s"     => \$opt_default,           # string
197
                );
198
 
199
                #
200
                #   UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
201
                #
202
 
203
#
204
#   Process help and manual options
205
#
206
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
261 dpurdie 207
pod2usage(-verbose => 1)  if ( $opt_help == 2 );
208
pod2usage(-verbose => 2)  if ( $opt_help > 2 );
227 dpurdie 209
 
210
#
211
#   Configure the error reporting process now that we have the user options
212
#
213
ErrorConfig( 'name'    => 'Make',
214
             'verbose' => $opt_verbose,
215
             'debug'   => $opt_debug );
216
 
217
#
218
#   Configure the 'System' process so that it will terminate on any error
219
#   and not report the complete command line
220
#
221
SystemConfig ( 'ExitOnError' => 2);
222
 
223
#
224
#   Extract non-option commands
225
#   Much of this is for backward compatability
226
#   Support the following arguments
227
#       XXXXX=yyyy      Makefile Definition
228
#       -XXXX           Flags passed to make
229
#       XXXX            Raw target name
230
#
231
foreach my $arg ( @ARGV )
232
{
233
    Verbose2 ("Arg: $arg");
234
    if ( $arg =~ m~(\w+)=(.+)~ ) {
235
        $defs{uc($1)} = $2;
236
 
237
    } elsif ( $arg =~ m/^-/ ) {
238
        push @defs, $arg;
239
 
240
    } else {
241
        push @targets, $arg;
242
 
243
    }
244
}
245
 
246
#
247
#   Misc. Initialisation
248
#
249
InitFileUtils();
250
 
251
EnvImport( 'GBE_TOOLS' );
252
$makelib = "$GBE_TOOLS/makelib.pl";
253
Error ("Cannot locate JATS file: $makelib") unless ( -f $makelib );
254
 
255
EnvImportOptional ( 'GBE_ABT' );
256
EnvImportOptional ( 'GBE_PLATFORM' );
257
 
258
#
259
#   Validate user options
260
#
261
@targets = ($opt_default)
262
    if ( $opt_default && ! @targets);
263
Error ("No make targets specified" ) unless ( @targets );
264
 
265
#
266
#   Build the @defs array
267
#   This is a set of definitions passed to the makefiles
268
#   It is created on the fly to allow command line options to modify the definitions
269
#
270
foreach  ( sort keys %defs )
271
{
272
    next if ( m~^DEBUG$~i );                    # Naughty user
273
    push @defs, "$_=$defs{$_}";                 # Makefile defs are XXXX=aaaa
274
}
275
 
276
#
277
#   Look for OPTIONS=*args* and disable the silent make operation
278
#   This will allow the make to output messages
279
#
280
if (( exists $defs{OPTIONS} && $defs{OPTIONS} =~ m/args/ ) || $opt_verbose || $opt_debug )
281
{
282
    $opt_silent = 0;
283
}
284
 
285
#
286
#   Process GBE_PLATFORM and create a usable hash
287
#
288
if ( $GBE_PLATFORM )
289
{
290
    Verbose2 ("GBE_PLATFORM: $GBE_PLATFORM");
291
    $gbe_platform{$_} = 1 foreach ( split( / /, $GBE_PLATFORM ) );
239 dpurdie 292
    $gbe_platform{GENERIC} = 1;
227 dpurdie 293
}
294
 
295
#
296
#   Read in the local Makefile.gbe file
297
#   This will provide a path to the interface directory
298
#
299
ReadMakeInfo();
300
 
301
#
302
#   Read in the global build variables
303
#
304
ReadBuildConfig( "$::ScmRoot/$::ScmInterface" );
305
 
306
#
307
#   Determine the max size of the target name
308
#   Makes a nice display
309
#
310
foreach ( @BUILDPLATFORMS )
311
{
312
    my $len = length ($_);
313
    $tlen = $len if ( $len > $tlen );
314
}
315
 
316
#-------------------------------------------------------------------------------
317
#   Scan the list of targets and perform 'alias' expansion
318
#   targets are of the form
319
#       platform_command_type
320
#       Where:
321
#           type        may be _prod or _debug or not present
322
#           command     may be either a composite command or a simple command
323
#           platform    may be a platform or an alias
324
#
325
#
326
foreach my $arg ( @targets )
327
{
328
    my $suffix = '';
329
    my @commands;
330
    my @platforms;
331
 
332
    #
333
    #   Remove the only available suffix ( _debug | _prod )
334
    #   Also detect commnads of debug or prod
335
    #
336
    if ( $arg =~ m~(.+)_(debug)$~ ) {
337
        $suffix = $2;
338
        $arg = $1;
339
    } elsif ( $arg =~ m~(.+)_(prod)$~ ) {
340
        $suffix = $2;
341
        $arg = $1;
342
    } elsif ( $arg eq 'debug' ) {
343
        $suffix = $arg;
344
        $arg = '';
345
    } elsif ( $arg eq 'prod' ) {
346
        $suffix = $arg;
347
        $arg = '';
348
    }
349
 
350
    #
351
    #   Remove valid make commands from the remaining argument
352
    #   Have a hash of all known makefile commands
353
    #
354
    foreach my $cmd ( keys %composite_commands, keys %commands )
355
    {
356
        if ( $arg eq $cmd )
357
        {
358
            @commands = ExpandComposite($cmd);
359
            $arg = '';
360
        }
361
        elsif ( $arg =~ m~(.+)_($cmd)$~ )
362
        {
363
            $arg = $1;
364
            @commands = ExpandComposite($2);
365
            last;
366
        }
367
    }
368
 
369
    #
370
    #   See of we can extract an platform alias from the command
371
    #   Rip into target + command
372
    #
373
    if ( $arg )
374
    {
375
        if ( exists $ScmBuildAliases{$arg}  )
376
        {
377
            @platforms =  split (/ /, $ScmBuildAliases{$arg} );
378
        }
379
        elsif ( exists $ScmBuildPlatforms{$arg} )
380
        {
381
            @platforms = ($arg);
382
        }
383
        else
384
        {
385
            if ( @commands )
386
            {
387
                Error ("Unknown target: $arg");
388
            }
389
            else
390
            {
391
                Message ("Unknown command. Passed to make: $arg");
392
                @commands = $arg;
393
            }
394
        }
395
    }
396
 
397
    #
398
    #   Insert defaults
399
    #
400
    @platforms = @DEFBUILDPLATFORMS
401
        unless ( @platforms );
402
 
403
    @commands = ExpandComposite('all')
404
        unless ( @commands);
405
 
406
    #
407
    #   Perform GBE_PLATFORM filtering
408
    #
239 dpurdie 409
    @platforms = grep ( exists $gbe_platform{$_} , @platforms )
410
        if ( %gbe_platform );
227 dpurdie 411
 
412
    Error ("No platforms to be processed. Check GBE_PLATFORM")
413
        unless ( @platforms );
414
 
415
    #
416
    #   Iterate commands over platforms
417
    #
418
    foreach my $cmd ( @commands )
419
    {
420
        PerformCommand (\@platforms, $cmd, $suffix );
421
    }
422
}
423
 
424
#
425
#   All done
426
#
427
exit (0);
428
 
429
#-------------------------------------------------------------------------------
430
# Function        : PerformCommand
431
#
432
# Description     : Perform the make on a platform command
433
#
434
# Inputs          : $platform_ref   - platforms to process
435
#                   $cmd            - simple make command
436
#                   $suffix         - debug,prod,none
437
#
438
# Returns         : 
439
#
440
sub PerformCommand
441
{
442
    my ($platform_ref, $cmd, $suffix) = @_;
443
    my $do_prod = 1;
444
    my $do_debug = 1;
445
 
446
    #
447
    #   Clean up some ugly commands from lint and ctags
448
    #
449
    if ( $cmd =~ m~(.+)_(debug)$~ )
450
    {
451
        $cmd = $1;
452
        $suffix = $2;
453
    }
454
    Verbose2 ("Processing Target: $cmd, $suffix");
455
 
456
    #
457
    #   Limit command to production or debug
458
    #
459
    if ( $suffix eq 'debug' ) {
460
        $do_prod  = 0;
461
    } elsif ( $suffix eq 'prod' ) {
462
        $do_debug  = 0;
463
    }
464
 
465
    #
466
    #   Some commands can be suppressed by options
261 dpurdie 467
    #   These are an array of options
227 dpurdie 468
    #
469
    if ( exists $commands{$cmd}{'unless'}  )
470
    {
261 dpurdie 471
        foreach my $check ( @{$commands{$cmd}{'unless'}} )
227 dpurdie 472
        {
261 dpurdie 473
            if ( exists $defs{$check} && $defs{$check} )
474
            {
475
                Verbose2 ("Skipping: $cmd because $check");
476
                return;
477
            }
227 dpurdie 478
        }
479
    }
480
 
481
    #
482
    #   Interecpt commands that are handled locally
483
    #
484
    if ( exists $commands{$cmd}{'local'} )
485
    {
486
        $commands{$cmd}{'local'}( $cmd, $platform_ref );
487
        return;
488
    }
489
 
490
    #
491
    #   Process and recurse directory tree
492
    #
493
    Verbose ("Processing: $cmd, @{$platform_ref}");
494
 
495
    #
496
    #   Determine the local tag name and state
497
    #   The tag is used to short circuit makefile commands in recursive makes
498
    #   It greatly reduces the work required
499
    #
500
    #   Many commands have a tag that is the same as the command, but a few don't
501
    #
502
    my $tag = 0;
503
    if ( exists $commands{$cmd}{tag}  )
504
    {
505
        $tag = $commands{$cmd}{tag};
506
        $tag = $cmd if ( $tag eq '1' );
507
    }
508
 
509
    if ( $commands{$cmd}{'common'} )
510
    {
511
        InvokeSubMake( $::Cwd, $platform_ref ,$cmd, $tag, 1 );
512
    }
513
    else
514
    {
515
        InvokeSubMake( $::Cwd, $platform_ref ,$cmd, $tag, 1 ) if $do_debug;
516
        InvokeSubMake( $::Cwd, $platform_ref ,$cmd, $tag, 0 ) if $do_prod;
517
    }
518
}
519
 
520
#-------------------------------------------------------------------------------
521
# Function        : InvokeSubMake
522
#
523
# Description     : Build recursion
524
#                   Determine if there is anything to be done for the current
525
#                   target within a specified directory
526
#
527
# Inputs          : $dir
528
#                   $pref                   - Ref to an array of platforms
529
#                   $cmd
530
#                   $tag
531
#                   $do_prod
532
#
533
# Returns         : 
534
#
535
sub InvokeSubMake
536
{
537
    my ( $dir, $pref, $cmd, $tag, $do_debug) = @_;
538
 
539
    #
540
    #   Ensure the current directory is known to the Tags database
541
    #
542
    $Tags = ReadMaketags( $dir );
543
    Error ("Directory not in tag database", $dir ) unless ( $Tags );
544
 
545
    #
546
    #   Process commands in the current directory
547
    #   If the command is tagged, then we may be able to skip it
548
    #   Otherwise we need to do it
549
    #
550
    InvokeMake( $dir, $pref, $cmd, $tag, $do_debug );
551
 
552
    #
553
    #   Recurse into any subdirectories that may be a part of the build
554
    #
555
    unless ( exists $defs{NORECURSE} && $defs{NORECURSE}  )
556
    {
557
        #
558
        #   Process subdirectories for the current command
559
        #   If the command is tagged, then we may be able to skip it
560
        #   Otherwise we need to do it
561
        #
562
        foreach my $subdir (@{$Tags->{$dir}{subdirs}} )
563
        {
564
 
565
            InvokeSubMake( CleanDirName( "$dir/$subdir"), $pref, $cmd, $tag, $do_debug );
566
        }
567
    }
568
}
569
 
570
#-------------------------------------------------------------------------------
571
# Function        : InvokeMake
572
#
573
# Description     : Actually invoke the make for debug and production as required
574
#
575
# Inputs          : $dir
576
#                   $pref
577
#                   $cmd
578
#                   $tag
579
#                   $do_debug
580
#
581
#
582
# Returns         : 
583
#
584
sub InvokeMake
585
{
586
    my ( $dir, $pref, $cmd, $tag, $do_debug ) = @_;
587
    my $text = 'C';
588
 
589
    #
590
    #   Ensure that the current directory actually has makefile targets
591
    #   Not all makefile.pl create .mk files
592
    #       1) Top-level makefile.pl
593
    #       2) Makefiles that use --NoPlatformBuilds
594
    #
595
    if ( $Tags->{$dir}{root} )
596
    {
597
        Verbose2 "Root directory has no makefiles: $dir";
598
        return;
599
    }
600
 
601
    if ( $Tags->{$dir}{noplatforms} )
602
    {
603
        Verbose2 "No make targets in $dir";
604
        return;
605
    }
606
 
607
    #
608
    #   Process each platform
609
    #
610
    foreach my $target ( @{$pref} )
611
    {
612
        unless ( exists $Tags->{$dir}{platforms}{$target} )
613
        {
614
            Verbose2 "No make targets in $dir, for $target";
615
            next;
616
        }
617
 
618
        #
619
        #   Do we need to do any thing for this target / tag
620
        #
621
        if ( $tag )
622
        {
623
            unless ( exists $Tags->{$dir}{full}{$target}{'%MakeTags'}{$tag} )
624
            {
261 dpurdie 625
                Verbose2 ("Skipping $cmd in $dir for $tag");
227 dpurdie 626
                next;
627
            }
628
        }
629
 
630
        #
631
        #   common mode == 2
632
        #   Only process target ONCE for each platform
633
        #   Don't care when its used
634
        #
261 dpurdie 635
        if ( exists $commands{$cmd}{'common'} && $commands{$cmd}{'common'} & 2 )
227 dpurdie 636
        {
637
            if ( $common_cmd{$cmd}{$target} )
638
            {
639
                Verbose2 "Already performed $cmd for $target";
640
                next;
641
            }
642
            $common_cmd{$cmd}{$target} = 1;
643
        }
644
 
645
        #
646
        #   Is the build limited to only debug or production
647
        #
261 dpurdie 648
        unless ( exists $commands{$cmd}{'common'} )
227 dpurdie 649
        {
650
            if ( $do_debug == 0 ) {
651
                next unless ( $Tags->{$dir}{platforms}{$target}{prod} );
652
                $text = 'P';
653
 
654
            } elsif  ( $do_debug == 1 ) {
655
                next unless ( $Tags->{$dir}{platforms}{$target}{debug} );
656
                $text = 'D';
657
            }
658
        }
659
 
660
        #
661
        #   Final sanity test
662
        #   Must have the makefile. We should have detected this error before now
663
        #
664
        Error ("Makefile not found - $target") unless ( -f "$dir/$target.mk" );
665
 
666
        #
667
        #   Build up the make command line
668
        #   Examine command specfic flags
669
        #
670
        my @args = @defs;
671
        push @args, "IFLAG=$commands{$cmd}{IFLAG}" if ( exists $commands{$cmd}{IFLAG} );
261 dpurdie 672
        push @args, "NOSCMDEPEND=1";
227 dpurdie 673
 
674
        my $cdir = CleanDirName ($dir);
675
        my @make_command;
676
        push @make_command, "$ENV{GBE_BIN}/xmake";
677
        push @make_command, "-s" if $opt_silent;
678
        push @make_command, "--no-print-directory";
679
        push @make_command, "-C", $cdir unless ( $cdir eq $::Cwd );
680
        push @make_command, "-f", "$target.mk";
681
        push @make_command, @args;
682
        push @make_command, 'make_dir' unless exists $commands{$cmd}{nomakecheck} ;
683
        push @make_command, $cmd;
684
 
685
        Message ( sprintf ("[$text] %-${tlen}s, $cmd, $cdir", $target ));
686
        System (@make_command, "DEBUG=$do_debug" );
687
    }
688
}
689
 
690
#-------------------------------------------------------------------------------
691
# Function        : TestMakeFiles
692
#
693
# Description     : Test all the makefile dependent files to see if any of the
694
#                   makefiles need to be rebuilt.
695
#
696
#                   Walk the directory tree looking for makefiles to be
697
#                   rebuilt.
698
#
699
# Inputs          : $cmd            - Current command
700
#                   $pref           - Ref to an array of platforms
701
#
702
# Returns         : 
703
#
704
sub TestMakeFiles
705
{
706
    my ( $cmd, $pref ) = @_;
707
    Verbose ("Test makefile dependencies");
708
 
709
    #
710
    #   Read in the Tag file for the current directory
711
    #   This will provide the current list of subdirectories
712
    #
713
    #   Process Test the current makefiles, then test any subdirs
714
    #
715
    TestSubMake( $cmd, $Cwd, $pref );
716
 
717
    #
718
    #   Report build errors
719
    #   Done after all makefiles have been processed
720
    #
721
    if ( $build_error )
722
    {
723
        Error ("Error creating makefiles. Errors previously reported");
724
    }
725
 
726
    #
727
    #   Post makefile build processing
728
    #   Only required if a files have been re-built
729
    #
730
    if ( $update )
731
    {
732
        #
733
        #   Sanity test the makefile structure
734
        #   Ensure that makefiles have only one parent.
735
        #
736
        TestParents();
737
 
738
        #
739
        #   Sanity test the installed and packaged files
740
        #   Generate warnings and errors if a file if packaged from two
741
        #   locations
742
        #
743
        TestPackages();
744
 
745
        #
746
        #   Generate DPACKAGE file if required
747
        #
748
        JatsDPackage::DPackageGenerate( $::ScmRoot, $::ScmInterface  );
749
    }
750
 
751
    #
752
    #
753
    #   Check that the build.pl file is not newer that the tags file
754
    #   This will not be an error, but it will be a nagging warning
755
    #
756
    my @build_warn;
757
    my $bstamp = -M "$::ScmRoot/$ScmBuildSrc";
758
    my $tstamp = -M "$::ScmRoot/Makefile.gbe";
759
 
760
    push @build_warn, "Missing: Makefile.gbe" unless ( defined $tstamp );
761
    push @build_warn, "Modified build file ($ScmBuildSrc)" if ( $tstamp && $bstamp < $tstamp );
762
    if ( @build_warn )
763
    {
764
        Warning ("The build file is newer than the generated files",
765
                 "The project needs to be built for these changes to be included",
766
                 @build_warn );
767
    }
768
}
769
 
770
#-------------------------------------------------------------------------------
771
# Function        : TestSubMake
772
#
773
# Description     : Test the makefiles in the current directory
774
#                   Recurse into subdirectories
775
#
776
# Inputs          : $cmd            - Current command
777
#                   $dir            - Directory to test
778
#                   $pref           - Ref to an array of platforms
779
#
780
# Returns         : 
781
#
782
sub TestSubMake
783
{
784
    my ($cmd, $dir, $pref ) = @_;
785
 
786
    $Tags = ReadMaketags( $dir, 1 );
787
    unless ( $Tags )
788
    {
789
        Verbose2 ("TestSubMake :Directory not in tag database", $dir );
790
        MakeBuild( $dir);
791
    }
792
    else
793
    {
794
        TestMake( $cmd, $dir, $pref );
795
    }
796
 
797
    #
798
    #   Recurse into any subdirectories that may be a part of the build
799
    #
800
    unless ( exists $defs{NORECURSE} && $defs{NORECURSE}  )
801
    {
802
        foreach my $subdir (@{$Tags->{$dir}{subdirs}} )
803
        {
804
            TestSubMake( $cmd, CleanDirName( "$dir/$subdir"), $pref );
805
        }
806
    }
807
}
808
 
809
#-------------------------------------------------------------------------------
810
# Function        : TestMake
811
#
812
# Description     : Test the makefiles component files
813
#                   and determine if the makefile(s) need to be rebuilt
814
#
815
# Inputs          : $cmd            - Current command
816
#                   $dir            - Directory to test
817
#                   $pref           - Ref to an array of platforms
818
#
819
# Returns         : 
820
#
821
sub TestMake
822
{
823
    my ( $cmd, $dir, $pref ) = @_;
824
    my @must_rebuild;
825
 
826
    if ( $cmd eq 'rebuild' )
827
    {
828
        MakeBuild( $dir);
829
        return;
830
    }
831
 
832
    #
833
    #   Check that the local makefile.pl is not newer than
834
    #   the Tags file. Not all makefile.pl's create .mk files
835
    #
836
    my $mstamp = -M "$dir/makefile.pl";
837
    my $tstamp = -M "$dir/Makefile.gbe";
838
 
839
    unless ( defined $tstamp )
840
    {
841
        UniquePush (\@must_rebuild, "Missing: $dir/Makefile.gbe");
842
    }
843
 
844
    if ( $mstamp && $mstamp < $tstamp  )
845
    {
846
        UniquePush (\@must_rebuild, "Updated: $dir/makefile.pl");
847
    }
848
    else
849
    {
850
        if ( $Tags->{$dir}{root} )
851
        {
852
            Verbose2 "TestMake: Root directory has no makefiles: $dir";
853
            return;
854
        }
855
 
856
        if ( $Tags->{$dir}{noplatforms} )
857
        {
858
            Verbose2 "TestMake: No make targets in $dir";
859
            return;
860
        }
861
 
862
        #
863
        #   Process only the required build targets
864
        #
865
        foreach my $tgt ( keys %{$Tags->{$dir}{platforms}}   )
866
        {
867
            next if ( %gbe_platform && not exists $gbe_platform{$tgt} );
868
            #
869
            #   Locate all the makefile dependent files
870
            #
871
            my $data = $Tags->{$dir}{full}{$tgt}{'@ScmDepends'};
872
            if ( $data )
873
            {
874
                Verbose2 ("Processing: $dir : $tgt");
875
                my $base_stamp = -M "$dir/$tgt.mk";
876
                unless ( defined $base_stamp )
877
                {
878
                    UniquePush (\@must_rebuild, "Missing: $dir/$tgt.mk");
879
                }
880
                else
881
                {
882
                    foreach my $file ( "$dir/makefile.pl" ,@$data )
883
                    {
884
                        $file = "$dir/$file" if ( $file =~ m~^\.~ );
885
                        my $stamp = -M $file;
886
                        if ( defined $stamp )
887
                        {
888
                            Verbose3 ("Timestamp: $stamp, $file");
889
                            if ( $stamp < $base_stamp  )
890
                            {
891
                                UniquePush (\@must_rebuild, $file);
892
                            }
893
                        }
894
                        else
895
                        {
896
                            UniquePush (\@must_rebuild, "Missing: $file");
897
                        }
898
                    }
899
                }
900
            }
901
            else
902
            {
903
                Warning ("No dependency information for: $tgt in $dir");
904
            }
905
        }
906
    }
907
 
908
    if ( @must_rebuild )
909
    {
910
        my @display;
911
        push (@display, CleanDirName($_) ) foreach ( @must_rebuild );
912
        Message ("One or more JATS source or internal files have changed, Makefiles will be rebuilt",
913
                  "Target is: $dir",
914
                  @display );
915
        MakeBuild ($dir);
916
    }
917
    return;
918
}
919
 
920
#-------------------------------------------------------------------------------
921
# Function        : MakeBuild
922
#
923
# Description     : Rebuild the makefiles in the specified directory
924
#                   This does not involve recursion - thats already been
925
#                   done.
926
#
927
#                   Once the makefiles have been re-built the tags database
928
#                   must be read in again as it may have changed.
929
#
930
# Inputs          : 
931
#
932
# Returns         : 
933
#
934
sub MakeBuild
935
{
936
    my ($dir) = @_;
937
 
938
    #
939
    #   No makefiles to build in the root directory
940
    #   Can't rebuild the top-level Makefile.gbe file
941
    #
942
    return if ( $Tags->{$dir}{root} );
943
 
944
    #
945
    #   Try to rebuild the makefile
946
    #
947
    chdir $dir || Error ("Cannot change directory to $dir");
261 dpurdie 948
    my $result = System ('--NoExit', $ENV{GBE_PERL}, 'makefile.pl',
949
                            $::ScmRoot, $makelib, "--interface=$::ScmInterface" );
227 dpurdie 950
    chdir $::Cwd || Error ("Cannot change directory to $::Cwd");
951
 
952
    #
953
    #   Re-read the tags database
954
    #
955
    $Tags = ReadMaketags( $dir, 2 );
956
 
957
    #
958
    #   Flag that makefiles have been modified
959
    #
960
    $update = 1;
261 dpurdie 961
    $build_error = 1 if ( $result );
227 dpurdie 962
}
963
 
964
#-------------------------------------------------------------------------------
965
# Function        : UnMakeFiles
966
#
967
# Description     : Delete generated makefiles and control files
968
#
969
# Inputs          : $cmd            - Current command
970
#                   $pref           - Ref to an array of platforms
971
#
972
# Returns         : 
973
#
974
sub UnMakeFiles
975
{
976
    #
977
    #   Recurse down the tree
978
    #   Recurse, then performs operations in the current directory
979
    #
980
    sub UnSubMakeFiles
981
    {
982
        my ($dir) = @_;
983
        $Tags = ReadMaketags( $dir, 1 );
984
        foreach my $subdir (@{$Tags->{$dir}{subdirs}} )
985
        {
986
            UnSubMakeFiles( CleanDirName( "$dir/$subdir") );
987
        }
988
        UnMake( $dir );
989
    }
990
 
991
    #
992
    #   Delete makefiles in the current directory
993
    #
994
    sub UnMake
995
    {
996
        my ($dir) = @_;
997
        Verbose("Unmake in $dir");
998
        foreach my $tgt ( keys %{$Tags->{$dir}{platforms}}   )
999
        {
1000
            Verbose2("Unmake. Delete ${tgt}.mk");
1001
            unlink ("$dir/${tgt}.mk");
1002
        }
1003
        unlink ("$dir/Makefile.gbe");
1004
        Verbose2("Unmake. Delete Makefile.gbe");
1005
    }
1006
 
1007
    #
1008
    #   Depth first recursion through the tree
1009
    #
1010
    UnSubMakeFiles ( $Cwd );
1011
}
1012
 
1013
#-------------------------------------------------------------------------------
1014
# Function        : TestParents
1015
#
1016
# Description     : Ensure that each makefile node has exactly one parent
1017
#                   Prevent the user from creating recursive loops
1018
#
1019
# Inputs          : 
1020
#
1021
# Returns         : 
1022
#
1023
my %parents;
1024
sub TestParents
1025
{
1026
    Verbose ("Test makefile parents");
1027
    #
1028
    #   Init the hash. Command may be invoked multiple times
1029
    #
1030
    %parents = ();
1031
 
1032
    #
1033
    #   Recurse down the tree
1034
    #   Recurse, then performs operations in the current directory
1035
    #
1036
    sub RecurseDown
1037
    {
1038
        my ($dir) = @_;
1039
        $Tags = ReadMaketags( $dir, 1 );
1040
        Verbose2("TestParents in $dir");
1041
        foreach my $subdir (@{$Tags->{$dir}{subdirs}} )
1042
        {
1043
            my $subdir = CleanDirName( "$dir/$subdir");
1044
            push @{$parents{$subdir}}, $dir;
1045
            RecurseDown( $subdir );
1046
        }
1047
    }
1048
 
1049
    #
1050
    #   Depth first recursion through the tree
1051
    #
1052
    RecurseDown ( $Cwd );
1053
 
1054
    #
1055
    #   Test for only one parent
1056
    #   The root makefile won't have any
1057
    #
1058
    foreach my $dir ( sort keys %{$Tags} )
1059
    {
1060
        my $count = $#{$parents{$dir}};
1061
        if ( $count > 0 )
1062
        {
1063
            if ( defined($GBE_ABT) )
1064
            {
1065
                Warning ("Error supressed by ABT");
1066
                Warning ("makefile.pl with multiple parents",
1067
                         "makefile.pl in: $dir",
1068
                         "Parented by:", @{$parents{$dir}} );
1069
            }
1070
            else
1071
            {
1072
                unlink $Tags->{$dir}{config};
1073
                Error ("makefile.pl with multiple parents",
1074
                       "makefile.pl in: $dir",
1075
                       "Parented by:", @{$parents{$dir}} );
1076
            }
1077
        }
1078
    }
1079
}
1080
 
1081
#-------------------------------------------------------------------------------
1082
# Function        : TestPackages
1083
#
1084
# Description     : Ensure that files that are packaged and installed are
1085
#                   only done from one makefile. Warn if the same file
1086
#                   is being packaged from multiple makefiles.
1087
#
1088
# Inputs          : 
1089
#
1090
# Returns         : 
1091
#
1092
my %test_packages;
1093
sub TestPackages
1094
{
1095
    Verbose ("Test packaged files");
1096
    #
1097
    #   Init the hash. Command may be invoked multiple times
1098
    #
1099
    %test_packages = ();
1100
 
1101
    #
1102
    #   Recurse down the tree
1103
    #   Recurse, then performs operations in the current directory
1104
    #
1105
    sub TRecurseDown
1106
    {
1107
        my ($dir) = @_;
1108
        Verbose2("TestPackages in $dir");
1109
        $Tags = ReadMaketags( $dir, 1 );
1110
        #
1111
        #   Process makefile
1112
        #   Examine all the %PACKAGE_xxx and %INSTALL_xxx fields thare listed
1113
        #   in the @PACKAGE_VARS and @INSTALL_VARS array
1114
        #
1115
        foreach my $target ( keys %{$Tags->{$dir}{platforms}}   )
1116
        {
1117
            next if ( %gbe_platform && not exists $gbe_platform{$target} );
1118
            foreach my $field ( @{$Tags->{$dir}{full}{$target}{'@PACKAGE_VARS'}},
1119
                                @{$Tags->{$dir}{full}{$target}{'@INSTALL_VARS'}} )
1120
            {
1121
                foreach my $entry ( keys %{$Tags->{$dir}{full}{$target}{$field}} )
1122
                {
1123
                    Verbose3("TestPackages: $target, File: $entry");
1124
                    push @{$test_packages{$target}{$entry}}, $dir;
1125
                }
1126
            }
1127
        }
1128
 
1129
        #
1130
        #   Process subdirectories too
1131
        #
1132
        foreach my $subdir (@{$Tags->{$dir}{subdirs}} )
1133
        {
1134
            TRecurseDown( CleanDirName( "$dir/$subdir") );
1135
        }
1136
    }
1137
 
1138
 
1139
 
1140
    #
1141
    #   Depth first recursion through the tree
1142
    #
1143
    TRecurseDown ( $Cwd );
1144
 
1145
    #
1146
    #   Test and report files that are packaged in different makefiles
1147
    #   There are two issues:
1148
    #       1) Not good practice
1149
    #       2) May be different files
1150
    #   The warning message is a bit ugly - but it shouldn't pop up often.
1151
    #
1152
#    DebugDumpData ("test_packages", \%test_packages);
1153
 
1154
    foreach my $target ( sort keys %test_packages )
1155
    {
1156
        foreach my $file ( sort keys %{$test_packages{$target}} )
1157
        {
1158
            #
1159
            #   The descpkg file is known to be packaged from multiple dirs
1160
            #
1161
            next if ( $file =~ m~/descpkg~ );
1162
            if ( $#{$test_packages{$target}{$file}} > 0 )
1163
            {
1164
                Warning ("File is packaged or installed from multiple makefiles",
1165
                         "Target: $target, Packaged file: $file",
1166
                         "Packaged from the following directories:", @{$test_packages{$target}{$file}} );
1167
            }
1168
        }
1169
    }
1170
}
1171
 
1172
 
1173
#-------------------------------------------------------------------------------
1174
# Function        : DoHelp
1175
#
1176
# Description     : Display basic help information
1177
#
1178
# Inputs          : None
1179
#
1180
# Returns         :
1181
#
1182
sub DoHelp
1183
{
1184
 
1185
#
1186
#   Display basic usage information
1187
#
1188
    pod2usage(-verbose => 0,
1189
              -message => "Version: $VERSION",
1190
              -exitval => 'NOEXIT');
1191
 
1192
    print "Platform targets\n";
1193
    foreach ( sort keys %BUILDINFO )
1194
    {
1195
        print "    $_\n";
1196
    }
1197
 
1198
    my @alias = sort keys %ScmBuildAliases;
1199
    if ( $#alias >=0 )
1200
    {
1201
        print "Alias targets\n";
1202
        foreach ( @alias )
1203
        {
1204
            print "    $_   - $ScmBuildAliases{$_}\n";
1205
        }
1206
    }
1207
}
1208
 
1209
#-------------------------------------------------------------------------------
1210
# Function        : ReadMaketags
1211
#
1212
# Description     : Read in the global make tags data base
1213
#                   This contains information on all the components within
1214
#                   the build. The tags allow recursive makes to be pruned.
1215
#
1216
#                   The file may change while the build is running
1217
#                   It can be read multiple times
1218
#
1219
# Inputs          : $dir            - Directory entry to read
1220
#                   $test           - 1: Read if available
1221
#                                     2: Force read
1222
#
1223
# Returns         : Reference to the tag data for the requested directory
1224
#                   Will error if no available
1225
#
1226
our %cf_minfo;
1227
our %cf_minfo2;
1228
my %tag_data;
1229
sub ReadMaketags
1230
{
1231
    my ($dir, $test) = @_;
1232
 
1233
    #
1234
    #   Force data re-aquisition
1235
    #
1236
    delete $tag_data{$dir}
1237
        if ( $test && $test == 2 );
1238
 
1239
    #
1240
    #   Do we already have the entry
1241
    #
1242
    return \%tag_data
1243
        if ( exists ($tag_data{$dir} ));
1244
 
1245
    #
1246
    #   If the entry is not known, then re-read the index file
1247
    #
1248
    unless ( $::cf_filelist{$dir} )
1249
    {
1250
        my $index_file = "$::ScmRoot/$::ScmInterface/Makefile.cfg";
1251
        Error ("Makefile index missing. Rebuild required") unless ( -f $index_file );
1252
 
1253
        #
1254
        #   Kill the entry in %INC to force the file to be read in
1255
        #
1256
        $::cf_filelist = ();
1257
        delete $INC{ $index_file };
1258
        require $index_file;
1259
    }
1260
 
1261
    my $cfg_filen = $::cf_filelist{$dir};
1262
    unless ( $cfg_filen )
1263
    {
1264
        return undef
1265
            if ( $test );
1266
        Error ("Makefile index entry missing: $dir. Rebuild required");
1267
    }
1268
 
1269
 
1270
    #
1271
    #   Read in all the Makefile_x.cfg files
1272
    #
1273
    %cf_minfo = ();
1274
    %cf_minfo2 = ();
1275
    my $cfg_file = "$::ScmRoot/$::ScmInterface/$cfg_filen";
1276
 
1277
    unless ( -f $cfg_file )
1278
    {
1279
        return undef
1280
            if ( $test );
1281
        Error ("Make data file missing: $cfg_file. Rebuild required");
1282
    }
1283
 
1284
    delete $INC{ $cfg_file };
1285
    require $cfg_file;
1286
 
1287
    Error ("Makefile info2 not present")
1288
        unless ( keys %::cf_info2 );
1289
 
1290
    Error ("Makefile info2 incorrect version. Rebuild required")
1291
        unless ( exists $::cf_info2{version} && $::cf_info2{version} eq 1 );
1292
 
1293
    %{$tag_data{$dir}} = %::cf_info2;
1294
    $tag_data{$dir}{config} = $cfg_file;
1295
    %{$tag_data{$dir}{full}} = %::cf_info;
1296
 
1297
#DebugDumpData ("ReadMaketags", $tag_data{$dir});
1298
    return \%tag_data;
1299
 
1300
}
1301
 
1302
#-------------------------------------------------------------------------------
1303
# Function        : ExpandComposite
1304
#
1305
# Description     : Expand a command via composite command expansion
1306
#                   A composite command may contain other composite commands
261 dpurdie 1307
#                   Detect, as an error, recursive expansions
227 dpurdie 1308
#
1309
# Inputs          : $cmd    - command to expand
1310
#
1311
# Returns         : An array of commands
1312
#
1313
sub ExpandComposite
1314
{
1315
    my ($cmd) = @_;
1316
    my @cmds;
1317
    my @scmds = $cmd;
261 dpurdie 1318
    my %seen;
227 dpurdie 1319
    while ( @scmds )
1320
    {
1321
        my $cmd = shift @scmds;
1322
        if ( exists $composite_commands{$cmd} )
1323
        {
261 dpurdie 1324
 
1325
            Error ("Internal. Recursion in composite command definitions: $cmd")
1326
                if ($seen{$cmd});
1327
 
227 dpurdie 1328
            @scmds = (@{$composite_commands{$cmd}}, @scmds);
261 dpurdie 1329
            $seen{$cmd} = 1;
227 dpurdie 1330
        }
1331
        else
1332
        {
1333
            push @cmds, $cmd;
1334
        }
1335
    }
1336
 
1337
    return @cmds;
1338
}
1339
 
1340
 
1341
#-------------------------------------------------------------------------------
1342
#   Documentation
1343
#
1344
 
1345
=pod
1346
 
1347
=head1 NAME
1348
 
1349
jmake - JATS make support tool
1350
 
1351
=head1 SYNOPSIS
1352
 
1353
 Usage: jats make [options][targets][flags]
1354
 
1355
 Where options:
1356
    -h, -h -h, -man     - Help messages with increasing verbosity
1357
    -verbose            - Verbose operation
1358
    -debug              - Debug operation
1359
    -default=target     - Default 'target' if none is supplied
1360
 
1361
 Where flags are of the form Name=Value
1362
    SHOWENV=1           - Show make environment
1363
    LEAVETMP=1          - Leave temp working files
1364
    NODEPEND=1          - Ignore dependency checking
261 dpurdie 1365
    EXPERT=1            - Ignore dependency on makefiles
227 dpurdie 1366
    OPTIONS=[opt]       - Maketime options [args,allargs,filter...]
1367
 
1368
 Valid targets include:
1369
    all                 - build and install everything(p*)
1370
    build               - build everything (pu)
1371
    debug               - build all things for debug (pu)
1372
    prod                - build all things for production (pu)
1373
    install             - install public components (pu*)
1374
    lint                - lints the source (assumes debug)(p)
1375
    package             - build all packages (pu*)
1376
    package-{set}       - build specific package (see below) (pu*)
1377
    run_tests           - Run the tests specified in the makefile
1378
    run_unit_tests      - Run the automatic unit tests specified in the makefile
1379
    deploy              - Run the deployment scripts (p*)
1380
    rebuild             - recursively rebuild makefiles
1381
    depend              - construct the dependencies (u*)
1382
    rmlitter            - remove build litter (core, tmp and err) (*)
1383
    clean               - delete generate, obj, libraries and programs (p*)
1384
    clobber             - delete everything which can be remade (p*)
1385
    help                - A list of alias and platforms
1386
 
1387
      (u) undo target available (ie uninstall)
1388
      (p) optional [platform_] prefix targets (ie XXX_build)
1389
      (*) optional [_debug|_prod] postfix targets (ie clean_debug)
1390
 
1391
 
1392
=head1 OPTIONS
1393
 
1394
=over 8
1395
 
1396
=item B<-help>
1397
 
1398
Print a brief help message and exits.
1399
 
1400
=item B<-help -help>
1401
 
1402
Print a detailed help message with an explanation for each option.
1403
 
1404
=item B<-man>
1405
 
1406
Prints the manual page and exits.
1407
 
1408
=item B<-verbose>
1409
 
1410
Increase the level of verbosity of the program execution
1411
 
1412
=item B<-debug>
1413
 
1414
Increase the debug output during program execution
1415
 
1416
 
1417
=item B<-default=target>
1418
 
1419
This options specifies the default target if none is provided on the command
1420
line. Used by the jats wrapper to simplify processing.
1421
 
1422
=back
1423
 
261 dpurdie 1424
=head1 TARGETS
227 dpurdie 1425
 
261 dpurdie 1426
Targets are described above.
1427
 
1428
Most targets support three modifiers. These can be used in conjunction with each
1429
other.
1430
 
227 dpurdie 1431
=over 8
1432
 
261 dpurdie 1433
=item undo
1434
 
1435
Many target operation can be undone by prefixing the tarhet with 'un' ie:
1436
uninstall.
1437
 
1438
=item platform prefix
1439
 
1440
Many target operations can be limited to one platform by prefixing the target
1441
with a valid platform name and an underscore. ie WIN32_all
1442
 
1443
=item build postfix. prod or debug
1444
 
1445
Many targets operations can be limited toi either production of debug by
1446
adding '_prod' or '_debug' to the target. ie 'install_debug'
1447
 
1448
=back
1449
 
1450
=head1 FLAGS
1451
 
227 dpurdie 1452
Flags are in the form TAG=value. This is a format that it used as they will be
1453
passed directly to the underlying makefiles. The recognised flags are:
1454
 
261 dpurdie 1455
=over 8
1456
 
227 dpurdie 1457
=item B<SHOWENV=1>
1458
 
1459
This flag will force the 'Environment' to be displayed before commands are executed
1460
 
1461
=item B<LEAVETMP=1>
1462
 
1463
This flag will cause temp files, created by the build process, to notr be deleted.
1464
 
1465
=item B<NODEPEND=1>
1466
 
1467
This flag will supress dependency checking. Makefiles will not be created when
1468
the makefile.pl is changed. Source files will not be scanned for header files.
1469
 
261 dpurdie 1470
=item B<EXPERT=1>
1471
 
1472
This flag will supress dependency checking between object files and the
1473
generated makefile. This option can be used while test building a large build
1474
when the makefile has been rebuilt but the user does not wish all the object
1475
files to be rebuilt.
1476
 
227 dpurdie 1477
=item B<OPTIONS=list,list>
1478
 
1479
This flags passes a list of comma seperated options into the makefile. The exact
1480
set of available options is target specific. Refer to the JATS manual.
1481
 
1482
 
1483
=back