Subversion Repositories DevTools

Rev

Rev 5709 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
261 dpurdie 1
########################################################################
5709 dpurdie 2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
227 dpurdie 3
#
261 dpurdie 4
# Module name   : ToolsetPrinter.pm
5
# Module type   : Perl Module
6
# Compiler(s)   : Perl
7
# Environment(s): jats
227 dpurdie 8
#
261 dpurdie 9
# Description   : Common toolset utils
10
#                 Toolset I/O stream for creating makefile rules and recipes
11
# Usage:
227 dpurdie 12
#
13
#       New         Create a new stream
14
#
15
#       Prt         Print a raw line
16
#
17
#       PrtLn       Print a raw line and a new line
18
#
4728 dpurdie 19
#       PrtPart     Print a raw line that will be extended. Contains continuation charaters and a new line
20
#
227 dpurdie 21
#       Newline     Print a single new line
22
#
23
#       Tag         Tagged line print.
24
#
25
#       Cmd         Command line print, tagged with meta quoted and terminates.
26
#
27
#       SetTag      Set the "tag", default none.
28
#
29
#       SetTerm     Set the command line "terminator", default "\\n\n".
30
#
31
#       Label       Print generalised label
32
#
261 dpurdie 33
#       StartDef    Create a Definition
34
#       Def         Accumulate
35
#       EndDef      Print it out
36
#
227 dpurdie 37
#       ObjList     Generate a object list, using the specified recipe.
38
#
39
#       LibList     Generate a library list, using the specified recipe.
40
#
41
#       DepRules    Generate library dependency rules
42
#
43
###############################################################################
44
 
261 dpurdie 45
use strict;
46
use warnings;
47
 
48
 
227 dpurdie 49
package ToolsetPrinter;
50
 
51
sub New
52
{
53
    my ($tag, $cmdterm) = @_;
54
 
55
    $tag = "" if ( !defined($tag) );            # default tag
56
    $cmdterm = "\\n\n"                          # and terminator
57
        if ( !defined($cmdterm) );
58
 
59
    my ($self) = {
60
            TAG         => $tag,
61
            CMDTERM     => $cmdterm
62
        };
63
    return bless $self, __PACKAGE__;
64
}
65
 
335 dpurdie 66
sub Reset
67
{
68
    my ($self) = shift;
69
    delete $self->{DEPEND_target};
70
    delete $self->{DEPEND_list};
71
    delete $self->{DEPEND_dir};
72
    delete $self->{DEPEND_file};
73
}
227 dpurdie 74
 
75
sub Prt
76
{
77
    my ($self) = shift;
289 dpurdie 78
    ::MakePrint ("@_");
227 dpurdie 79
}
80
 
81
sub PrtLn
82
{
83
    my ($self) = shift;
289 dpurdie 84
    ::MakePrint ("@_\n");
227 dpurdie 85
}
86
 
4728 dpurdie 87
sub PrtPart
88
{
89
    my ($self) = shift;
90
    ::MakePrint ("@_ \\\n");
91
}
92
 
227 dpurdie 93
sub Entry
94
{
95
    my ($self) = shift;
96
    ::MakeEntry( @_ );
97
}
98
 
99
 
100
sub Newline
101
{
102
    my ($self) = shift;
289 dpurdie 103
    ::MakePrint ("\n");
227 dpurdie 104
}
105
 
106
 
107
sub SetTag
108
{
109
    my ($self) = shift;
110
    my ($tag) = @_;
111
 
112
    $tag = "" if ( !defined($tag) );
113
    $self->{TAG} = $tag;
114
}
115
 
116
 
117
sub SetTerm
118
{
119
    my ($self) = shift;
120
    my ($cmdterm) = @_;
121
 
122
    $cmdterm = "\\n\n"                          # default terminator
123
        if ( !defined($cmdterm) );
124
    $self->{CMDTERM} = $cmdterm;
125
}
126
 
127
 
128
sub Cmd
129
{
130
    my ($self) = shift;
289 dpurdie 131
    ::MakeQuote ("$self->{TAG}\t+=@_$self->{CMDTERM}");
227 dpurdie 132
}
133
 
134
 
135
sub Tag
136
{
137
    my ($self) = shift;
289 dpurdie 138
    ::MakePrint ("$self->{TAG}\t+=@_\n");
227 dpurdie 139
}
140
 
141
 
142
sub Label
143
{
144
    my ($self) = shift;
145
    my ($desc, $target) = @_;
146
 
147
    $self->Prt( "#.. $desc ($target)\n\n" );
148
}
149
 
150
 
151
sub ObjList
152
{
153
    my ($self) = shift;
154
    my ($target, $objs, $genrecipe, @uargs) = @_;
155
 
156
    foreach (@$objs)
157
    {
158
        &$genrecipe( $self, $target, $_, @uargs );
159
    }
160
}
161
 
261 dpurdie 162
sub StartDef
163
{
164
    my ($self) = shift;
165
    my ($tag) = @_;
227 dpurdie 166
 
261 dpurdie 167
    $tag = "" if ( !defined($tag) );
168
    $self->{DEF} = $tag;
169
    $self->{DEFS} = [];
170
}
171
 
172
sub Def
173
{
174
    my ($self) = shift;
175
    push @{$self->{DEFS}}, "@_";
176
}
177
 
178
sub EndDef
179
{
180
    my ($self) = shift;
181
    ::MakeDefEntry ( $self->{DEF}, '=' , $self->{DEFS} );
182
    delete $self->{DEFS};
183
}
184
 
185
 
227 dpurdie 186
#private
187
sub CondParse
188
{
189
    my ($target, $cond) = @_;
190
 
191
    if ($cond =~ /^--ifdef=(.*)/) {             # .. ifdef XXX
192
        $cond = "ifdef $1";
193
 
194
    } elsif ($cond =~ /^--ifndef=(.*)/) {       # .. ifndef XXX
195
        $cond = "ifndef $1";
196
 
197
    } elsif ($cond =~ /^--ifdebug$/) {          # .. if DEBUG
198
        $cond = "ifeq \"\$(DEBUG)\" \"1\"";
199
 
200
    } elsif ($cond =~ /^--ifprod$/) {           # .. if PRODUCTION
201
        $cond = "ifeq \"\$(DEBUG)\" \"0\"";
202
 
203
    } elsif ($cond =~ /^--ifeq=(.*):(.*)$/) {   # .. ifeq XXXX:YYYY
204
        $cond = "ifeq \"\$($1)\" \"$2\"";
205
 
206
    } elsif ($cond =~ /^--ifneq=(.*):(.*)$/) {  # .. ifneq XXXX:YYYY
207
        $cond = "ifneq \"\$($1)\" \"$2\"";
208
 
209
    } else {                                    # .. unknown
210
        ::Error( "$target: unknown conditional construct '$cond'" );
211
        $cond = "";
212
    }
213
    return $cond;
214
}
215
 
216
 
217
#private
218
sub CondOpen
219
{
220
    my ($self) = shift;
221
 
222
    @{$self->{CONDSTACK}} = ();
223
}
224
 
225
 
226
#private
227
sub CondModify
228
{
229
    my ($self) = shift;
230
    my ($newstack) = @_;
231
    my ($oldstack) = \@{$self->{CONDSTACK}};
232
    my ($idx, $cond);
233
 
234
#   Diff the two stacks
235
#
236
    $idx = 0;
237
    while ( $idx <= $#$newstack &&
238
            $idx <= $#$oldstack &&
239
            $$newstack[$idx] eq $$oldstack[$idx] ) {
240
        $idx++;
241
    }
242
 
243
#   Pop diff
244
#
245
    while ($idx <= $#$oldstack) {
246
        $cond = pop @$oldstack;
247
        $self->Prt( "  " x ($#$oldstack+1) . "endif\n" );
248
    }
249
 
250
#   Push diff
251
#
252
    while ($idx <= $#$newstack) {
253
        $self->Prt( "  " x $idx . "$$newstack[$idx]\n" );
254
        $idx++;
255
    }
256
 
257
    @{$self->{CONDSTACK}} = @$newstack;
258
}
259
 
260
 
261
#private
262
sub CondClose
263
{
264
    my ($self) = shift;
265
    my (@newstack) = ();
266
 
267
    $self->CondModify( \@newstack );            # pop any stacked conditionals
268
}
269
 
270
 
271
sub LibList
272
{
273
    my ($self) = shift;
274
    my ($target, $libs, $genrecipe, @uargs) = @_;
275
    my (@cond, $t_cond) = ();
276
 
277
    $self->CondOpen();                          # open a conditional session
278
 
279
    foreach (@$libs)
280
    {
281
        if (/^--if/)                            # inlined conditionals
282
        {
283
            push @cond, $t_cond
284
                if (($t_cond = CondParse( $target, $_ )) ne "");
285
        }
286
        elsif (/^--/)                           # arguments
287
        {
288
            &$genrecipe( $self, $target, $_, @uargs );
289
        }
290
        else                                    # library
291
        {
292
            my (@args) = split( "\n\t\t", $_ ); # see makeif.pl
293
            my ($lib) = shift @args;
294
 
295
            #   Associated conditionals (if any)
296
            #
297
            foreach (@args) {
298
                push @cond, $t_cond
299
                    if (($t_cond = CondParse( $target, $_ )) ne "");
300
            }
301
            $self->CondModify( \@cond );        # modify
302
            @cond = ();
303
 
304
            #   Generate recipe
305
            #
306
            &$genrecipe( $self, $target, $lib, @uargs );
307
        }
308
    }
309
    $self->CondClose();                         # close session
310
}
311
 
335 dpurdie 312
#-------------------------------------------------------------------------------
313
# Function        : SetShldTarget
314
#
315
# Description     : Set up the Shared Library target information
316
#                   Main function is to calculate the name of the
317
#                   dependency file so that it can be used
318
#
319
#                   Must be called before SHLDDEPEND or DepRules
320
#
321
# Inputs          : $self
322
#                   $target         - Name of the target library
323
#                                     May or may not have $(GBE_TYPE)
324
#                   $dir            - Optional alternate directory
325
#                                     Default: LIBDIR
326
#
327
# Returns         : Full name of the dependency file
328
#
227 dpurdie 329
 
335 dpurdie 330
sub SetShldTarget
331
{
332
    my ($self, $target, $dir ) = @_;
333
    ::Warning("Internal: SetShldTarget already specified") if ( defined $self->{DEPEND_target} );
227 dpurdie 334
 
335 dpurdie 335
    #   Create a 'tag' to be used within the makefile
336
    #
337
    $self->{DEPEND_target} = $target;
338
    $self->{DEPEND_list} = $target . '_shdp';
339
 
340
    #
341
    #   Set up the name of the dependency file
342
    #
343
    $dir = 'LIBDIR' unless ( defined $dir );
344
    $self->{DEPEND_dir} = $dir;
345
 
346
    my $depfile = "\$($dir)/${target}";
347
    $depfile .= '$(GBE_TYPE)' unless ( $depfile =~ m~\$\(GBE_TYPE\)~ );
348
    $depfile .= '.dep';
349
    $self->{DEPEND_file} = $depfile;
350
 
351
    ::Verbose3("SetShldTarget",
352
                "DepDir:  $self->{DEPEND_dir}",
353
                "DepFile: $self->{DEPEND_file}",
354
                "DepList: $self->{DEPEND_list}" );
355
 
356
    return $depfile;
357
}
358
 
359
#-------------------------------------------------------------------------------
360
# Function        : SHLDDEPEND
361
#
362
# Description     : Create a set of rules and recipes to handle the creation
363
#                   of dependency files used in the creation of shared
364
#                   libraries
365
#
366
#
367
# Inputs          : $self
368
#                   $base       - SHBASE: Defines the shared library name (eg: lib)
369
#                   $name       - SHNAME: Defines the base library name (eg: lib.so.1.1)
370
#
227 dpurdie 371
sub SHLDDEPEND
372
{
373
    my ($self) = shift;
335 dpurdie 374
    my ($base, $name) = @_;
227 dpurdie 375
 
335 dpurdie 376
    #
377
    #   Sanity test: The name of the list must have been setup
378
    #
379
    my $depfile = $self->{DEPEND_file} || ::Error ("Internal error: SetShldTarget not called before SHLDDEPEND");
227 dpurdie 380
 
335 dpurdie 381
    $self->Newline();
382
    $self->Label( "Include Shared Library Dependency Rules", $self->{DEPEND_target} );
383
 
384
    $self->Prt(
385
"${depfile}:\tSHBASE=${base}
386
${depfile}:\tSHNAME=${name}
387
${depfile}:\tDPLIST=$self->{DEPEND_list}
388
${depfile}:\t\$(GBE_$self->{DEPEND_dir}) \$(SCM_MAKEFILE)
227 dpurdie 389
	\$(SHLDDEPEND)
390
 
391
ifneq \"\$(findstring \$(IFLAG),23)\" \"\"
335 dpurdie 392
-include\t${depfile}
227 dpurdie 393
endif
394
 
395
" );
335 dpurdie 396
 
397
    #   Mark file as generated by the toolset
398
    #
399
    ::ToolsetGenerate( $depfile );
227 dpurdie 400
}
401
 
335 dpurdie 402
#-------------------------------------------------------------------------------
403
# Function        : SetLdTarget
404
#
405
# Description     : Set up the Program target information
406
#                   Main function is to calculate the name of the
407
#                   dependency file so that it can be used
408
#
409
#                   Must be called before LDDEPEND or DepRules
410
#
411
# Inputs          : $self
412
#                   $target         - Name of the target program
413
#                   $dir            - Optional alternate directory
414
#                                     Default: BINDIR
415
#
416
# Returns         : Full name of the dependency file
417
#
418
sub SetLdTarget
419
{
420
    my ($self, $target, $dir ) = @_;
421
    ::Warning("Internal: SetLdTarget already specified") if ( defined $self->{DEPEND_target} );
227 dpurdie 422
 
335 dpurdie 423
    #   Create a 'tag' to be used within the makefile
424
    #
425
    $self->{DEPEND_target} = $target;
426
    $self->{DEPEND_list} = $target . '_dp';
427
 
428
    #
429
    #   Set up the name of the dependency file
430
    #
431
    $dir = 'BINDIR' unless ( defined $dir );
432
    $self->{DEPEND_dir} = $dir;
433
 
434
    my $depfile = "\$($dir)/${target}.dep";
435
    $self->{DEPEND_file} = $depfile;
436
 
437
    ::Verbose3("SetLdTarget",
438
                "DepDir:  $self->{DEPEND_dir}",
439
                "DepFile: $self->{DEPEND_file}",
440
                "DepList: $self->{DEPEND_list}" );
441
 
442
    return $depfile;
443
}
444
 
445
#-------------------------------------------------------------------------------
446
# Function        : LDDEPEND
447
#
448
# Description     : Create a set of rules and recipes to handle the creation
449
#                   of dependency files used in the creation of a program
450
#
451
#
452
# Inputs          : $self
453
#
227 dpurdie 454
sub LDDEPEND
455
{
456
    my ($self) = shift;
457
 
335 dpurdie 458
    #
459
    #   Sanity test: The name of the list must have been setup
460
    #
461
    my $depfile = $self->{DEPEND_file} || ::Error ("Internal error: SetLdTarget not called before LDDEPEND");
462
 
463
    $self->Newline();
464
    $self->Label( "Include Library Dependency Rules", $self->{DEPEND_target} );
227 dpurdie 465
 
335 dpurdie 466
    $self->Prt(
467
"${depfile}:\tDPLIST=$self->{DEPEND_list}
468
${depfile}:\t\$(GBE_$self->{DEPEND_dir}) \$(SCM_MAKEFILE)
227 dpurdie 469
	\$(LDDEPEND)
470
 
471
ifeq \"\$(IFLAG)\" \"3\"
335 dpurdie 472
-include\t${depfile}
227 dpurdie 473
endif
474
 
475
" );
335 dpurdie 476
 
477
    #   Mark file as generated by the toolset
478
    #
479
    ::ToolsetGenerate( $depfile );
227 dpurdie 480
}
481
 
335 dpurdie 482
#-------------------------------------------------------------------------------
483
# Function        : DepRules
484
#
485
# Description     : Create the list of dependency rules used
486
#                   within the dependency include file
487
#
488
# Inputs          : $libs       - Ref to a list of libraries
489
#                   $librecipe  - Ref to code to create the library recipe
490
#                   @uargs      - User arguments, passed to the librecipe function
491
#
492
# Returns         : Nothing
493
#
227 dpurdie 494
sub DepRules
495
{
496
    my ($self) = shift;
335 dpurdie 497
    my ( $libs, $librecipe, @uargs) = @_;
227 dpurdie 498
 
335 dpurdie 499
    #
500
    #   Sanity test: The name of the list must have been setup
501
    #
502
    my $target = $self->{DEPEND_target} || ::Error ("Internal error: SetShldTarget/SetLdTarget not called before DepRules");
503
 
504
    $self->SetTag( $self->{DEPEND_list});                   # command tag
505
    $self->SetTerm();
227 dpurdie 506
    unless ( $self->{DepRulesHeaderDone}{$target} )
507
    {
508
        $self->{DepRulesHeaderDone}{$target} = 1;
509
 
335 dpurdie 510
        $self->Label( "Linker Dependencies", $target );    # label
511
                                                           # library depends
261 dpurdie 512
        $self->Tag( "\\# DO NOT REMOVE - dependencies\\\\n" );
513
        $self->Tag( "\\#\\\\n" );
227 dpurdie 514
    }
261 dpurdie 515
 
227 dpurdie 516
    $self->LibList( $target, $libs, $librecipe, @uargs );
517
}
518
 
519
1;
520