Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
283 dpurdie 1
##############################################################################
2
#
3
# Module name   : TOOLSET/KeilArmV3
4
# Module type   : Makefile system
5
# Environment(s):
6
#
7
# Description:
8
#   Keil MDK Arm V4.3 toolset
9
#   A very simple toolset to support
10
#       1) C compiliation
11
#       2) Generation of libaries
12
#       3) Merging of libraries
13
#       4) Executables
14
#       5) Assembler files
15
#
16
#   Does not support ( because its not needed yet )
17
#       a) Shared libraries
18
#
19
##############################################################################
20
 
21
our @ScmToolsetArgs;
22
 
23
##############################################################################
24
#   ToolsetInit()
25
#       Runtime initialisation
26
#
27
##############################################################################
28
 
29
ToolsetInit();
30
 
31
sub ToolsetInit
32
{
33
    my $KeilVersion = "MDK Arm V4.3";
34
    my $GenThumb;
35
    my $GenDevice;
36
 
37
#.. Parse arguments
38
#
39
    foreach $_ ( @ScmToolsetArgs ) {
40
        if ( m~^--Thumb~ ) {
41
            $GenThumb=1;
42
 
43
        } elsif ( m~^--Device=(.*)~ ) {
44
            $GenDevice = $1;
45
 
46
        } else {
47
            Message( "KeilArmV3: unknown option $_ -- ignored\n" );
48
        }
49
    }
50
    Error ("KeilArmV3: Toolset error. --Device must be specified")
51
        unless ( $GenDevice );
52
 
53
#.. Standard.rul requirements
54
#
55
    $s = 's';
56
    $o = 'o';
57
    $a = 'lib';
58
    $exe = '.bin';
59
 
60
    AddSourceType( ".$s", '.asm' );
61
 
62
#.. Define environment
63
#
64
    Init( "KeilArmV3" );
65
 
66
    ToolsetDefine( "#################################################" );
67
    ToolsetDefine( "# Compiler version" );
68
    ToolsetDefine( "#" );
69
    ToolsetDefine( "KeilC Version      = \"$KeilVersion\"" );
70
    ToolsetDefine( "USE_THUMB = 1" ) if $GenThumb;
71
    ToolsetDefine( "USE_DEVICE = $GenDevice" );
72
    ToolsetDefine( "" );
73
    ToolsetDefine( "#" );
74
 
75
    ToolsetDefines( "KeilArmV3.def" );
76
    ToolsetRules  ( "KeilArmV3.rul" );
77
    ToolsetRules  ( "standard.rul" );
78
 
79
    #
80
    #   Extend the cleanup rule
81
    #
82
    ToolsetGenerate( '*.lst' );
83
 
84
#.. Extend the CompilerOption directive
85
#   Create a standard data structure
86
#   This is a hash of hashes
87
#       The first hash is keyed by CompileOption keyword
88
#       The second hash contains pairs of values to set or remove
89
#
90
    %::ScmToolsetCompilerOptions =
91
    (
92
        'nowarn='             => { 'NOWARNLIST'   ,\&NoWarns }, # Suppress warnings
93
        'timeoptimization'    => { 'OPT_MODE' , 'time'  },      # Time optimize
94
        'spaceoptimization'   => { 'OPT_MODE' , 'space' },      # Space optimize
95
        'defaultoptimization' => { 'OPT_MODE' , undef },        # Default (?space)
96
    );
97
 
98
 
99
    #
100
    #   Set default options
101
    #       $::ScmCompilerOpts{'xxxx'} = 'yyy';
102
    #
103
    $::ScmCompilerOpts{'NOWARNLIST'}  = '';
104
    $::ScmCompilerOpts{'OPT_MODE'}    = 'space';
105
 
106
}
107
 
108
#-------------------------------------------------------------------------------
109
# Function        : NoWarns
110
#
111
# Description     : ScmToolsetCompilerOptions  extension function
112
#                   Accumulates the NoWarn options as a comma seperated list
113
#
114
# Inputs          : $key        - Name of the Option
115
#                   $value      - Option Value. Comma sep list of numbers
116
#                   $ukey       - User key (within $::ScmCompilerOpts)
117
#
118
# Returns         : New sting to save
119
#
120
sub NoWarns
121
{
122
    my ($key, $value, $ukey) = @_;
123
    my @NoWarnList =  split (',', $::ScmCompilerOpts{$ukey});
124
    UniquePush ( \@NoWarnList, split (',', $value) );
125
    return join ',', @NoWarnList;
126
}
127
 
128
 
129
###############################################################################
130
#   ToolsetAS( $source, $obj, \@args )
131
#       This subroutine takes the user options and builds the rule(s)
132
#       required to compile the source file 'source' to 'obj'
133
#
134
###############################################################################
135
 
136
sub ToolsetAS
137
{
138
    MakePrint( "\n\t\$(AS)\n" );
139
}
140
 
141
sub ToolsetASDepend
142
{
143
}
144
 
145
###############################################################################
146
#   ToolsetCC( $source, $obj, \@args )
147
#       This subroutine takes the user options and builds the rule(s)
148
#       required to compile the source file 'source' to 'obj'
149
#
150
###############################################################################
151
 
152
sub ToolsetCC
153
{
154
    my( $source, $obj, $pArgs ) = @_;
155
 
156
    Debug( "CC:  $source -> $obj" );
157
    foreach ( @$pArgs ) {
158
        Debug( "option:    $_" );
159
        if ( /--Shared$/ ) {                    # Building a 'shared' object
160
            $cflags = "$cflags \$(SHCFLAGS)";
161
            Debug( "CC:    as shared object" );
162
        } else {                                # unknown option
163
            Message( "CC: unknown option $_ -- ignored\n" );
164
        }
165
    }
166
 
167
    MakePrint( "\n\t\$(CC)\n" );
168
    MakePrint( "\$(OBJDIR)/$i.${o}:\tCFLAGS +=$cflags\n" )
169
        if ( $cflags );
170
}
171
 
172
###############################################################################
173
#   ToolsetCCDepend( $depend, \@sources )
174
#       This subroutine takes the user options and builds the
175
#       rule(s) required to build the dependencies for the source
176
#       files 'sources' to 'depend'.
177
#
178
###############################################################################
179
 
180
sub ToolsetCCDepend
181
{
182
    MakePrint( "\t\$(CCDEPEND)\n" );
183
}
184
 
185
###############################################################################
186
#   ToolsetAR( $name, \@args, \@objs )
187
#       This subroutine takes the user options and builds the rules
188
#       required to build the library 'name'.
189
#
190
#   Arguments:
191
#       n/a
192
#
193
#   Output:
194
#       [ $(BINDIR)/name$.${a}:   .... ]
195
#           $(AR)
196
#
197
###############################################################################
198
 
199
sub ToolsetAR
200
{
201
    my( $name, $pArgs, $pObjs ) = @_;
202
 
203
#.. Parse arguments
204
#
205
    foreach $_ ( @$pArgs ) 
206
    {
207
        Message( "AR: unknown option $_ -- ignored\n" );
208
    }
209
 
210
#
211
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).${a}:\t", "", " \\\n\t\t", ".${o}", @$pObjs );
212
 
213
#.. Build library rule (just append to standard rule)
214
#
215
    MakePrint( "\n\t\$(AR)\n\n" );
216
}
217
 
218
 
219
###############################################################################
220
#   ToolsetARMerge()
221
#       Generate the recipe to merge libraries.
222
#       The dependency list is created by the caller.
223
#
224
###############################################################################
225
 
226
sub ToolsetARMerge
227
{
228
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
229
}
230
 
231
 
232
#-------------------------------------------------------------------------------
233
#   ToolsetLD( $name, \@pArgs, \@pObjs, \@pLibs )
234
#       This subroutine takes the user options and builds the rules
235
#       required to link the program 'name'.
236
#
237
#   Toolset is configured to suppress partial creation of the Package
238
#   Rules. This function must create the complete rule and recipe set.
239
#
240
#   Arguments:
241
#       $name           - Name of the output
242
#       $pArgs          - Ref to array of args
243
#       $pObjs          - Ref to array of objects
244
#       $pLibs          - Ref to array of libs
245
#
246
#  Options:
247
#       --Map           - Create a MAP file
248
#       --NoMap         - Don't create a MAP file
249
#       --Scatter=file  - Names a scatter file to be used
250
#       --ro-base=text  - Names the ReadOnly base
251
#       --rw-base=text  - Names the ReadWrite base
252
#       --Script=file   - Additional Linker commands
253
#
254
#   Output:
255
#       Generates makefile rules and recipes to create a program
256
#
257
 
258
sub ToolsetLD
259
{
260
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
261
    my $map_file;
262
    my $scatter_file;
263
    my $ro_base;
264
    my $rw_base;
265
    my @script_files;
266
 
267
#.. Parse arguments
268
#
269
 
270
    foreach ( @$pArgs )
271
    {
272
        if ( m~^--Map~i ) {
273
            $map_file = 1;
274
 
275
        } elsif ( m~^--NoMap~i ) {
276
            $map_file = 0;
277
 
278
        } elsif ( m~^--Scatter=(.+)~i ) {
279
            Src ('*', $1 );
280
            $scatter_file = MakeSrcResolve($1);
281
 
282
        } elsif ( m~^--Script=(.+)~i ) {
283
            Src ('*', $1 );
284
            push @script_files, MakeSrcResolve($1);
285
 
286
        } elsif ( /^--ro-base=(.+)/i ) {
287
            $ro_base = $1;
288
 
289
        } elsif ( m~^--rw-base=(.+)~i ) {
290
            $rw_base = $1;
291
 
292
        } else {
293
            Error( "LD: unknown option $_ -- ignored\n" );
294
        }
295
    }
296
 
297
    #
298
    #   Sanity test
299
    #
300
    Error ("Can't use --scatter in conjunction with -ro-base or -rw-base")
301
        if ( $scatter_file && ( $ro_base || $rw_base) );
302
 
303
    #
304
    #   Determine the target output name
305
    #
306
    my $root = "\$(BINDIR)/$name";
307
    my $full = $root . $::exe;
308
    my $axf  = $root . '.axf';
309
    my $dep  = $root . '.dep';
310
    my $map  = $root . '.map';
311
    my $call = $root . '.htm';
312
 
313
    #.. Packageing
314
    #   Have supressed default Prog building
315
    #   Need to specify the files to Package
316
    #
317
    PackageProgAddFiles ( $name, $full );
318
    PackageProgAddFiles ( $name, $map, 'Class=map' ) if $map_file;
319
 
320
 
321
    #.. Cleanup rules
322
    #
323
    ToolsetGenerate( $dep );
324
    ToolsetGenerate( $map );
325
    ToolsetGenerate( $axf );
326
    ToolsetGenerate( $call );
327
 
328
    #.. Build rules
329
    #
330
    my ($io) = ToolsetPrinter::New();
331
 
332
    #
333
    #   Standard Dependency rules
334
    #   Will generate rules to
335
    #       1) Determine at make-time the full paths to the libraries
336
    #       2) Include the above information
337
    #
338
    $io->LDDEPEND( $name );                         # standard LDDEPEND rules
339
 
340
    #.. Dependency link,
341
    #
342
    #       Now piece together a variable $(name_dp) which ends up in
343
    #       the command file building the application dependency list.
344
    #
345
    $io->SetTag( "${name}_dp" );                    # macro tag
346
    $io->SetTerm();
347
    $io->DepRules( $name, $pLibs, \&ToolsetLibRecipe ); # library depends rules
348
    $io->Newline();
349
 
350
    #
351
    #   List the object files
352
    #   Create a definition for the objects
353
    #
354
    $io->Label( "Object files", $name );            # label
355
    $io->StartDef ("${name}_obj");
356
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
357
    $io->EndDef ();
358
    $io->Newline();
359
 
360
    #
361
    #   Define the program and its dependencies
362
    #   Place the .dep file first - this will ensure that failure
363
    #   to create this file will create an error before the object
364
    #   files are compiled. This makes it obvious what the error is.
365
    #
366
    $io->Label( "Program", $name );                     # label
367
    $io->Prt( "$axf : \t$dep" );                        # Dependencies
368
    $io->Prt( " \\\n\t$scatter_file" ) if ($scatter_file);
369
    $io->Prt( " \\\n\t$_" ) foreach (@script_files);
370
    $io->Prt( " \\\n\t\$(${name}_obj)" .
371
              " \\\n\t\$(${name}_lib)" );
372
    $io->Newline();
373
 
374
    #
375
    #   Recipe to build the program
376
    #
377
    $io->PrtLn( "\t\$(LD)" );
378
 
379
 
380
    #.. Linker command file
381
    #
382
    #       Create a variable $(name_ld) which will be the linker
383
    #       command line. Use previosly defined values
384
    #
385
    $io->Label( "Linker commands", $name );         # label
386
    $io->StartDef ("${name}_ld");
387
    $io->Def( "\$(${name}_obj)" );                  # Object file list variable
388
    $io->Def( "\$(${name}_lib)" );                  # Library list variable
389
    $io->Def( "--scatter=$scatter_file" ) if ($scatter_file);
390
    $io->Def( "--ro-base=$ro_base" ) if defined ($ro_base);
391
    $io->Def( "--rw-base=$rw_base" ) if defined ($rw_base);
392
    $io->Def( "--list=$map" ) if ( $map_file );
393
    $io->Def( "--via=$_" ) foreach (@script_files);
394
    $io->EndDef ();
395
    $io->Newline();
396
 
397
    #
398
    #   Create rules to convert the .axf file into a bin file
399
    #   Done as a seperate step
400
    #
401
    #
402
    $io->Label( "Elf Converion ", $name );             # label
403
    $io->Prt( "$full : \t$axf\n" );                    # Dependencies
404
 
405
    #
406
    #   Recipe to build the program
407
    #
408
    $io->PrtLn( "\t\$(FROMELF)" );
409
 
410
}
411
 
412
 
413
########################################################################
414
#
415
#   Generate a linker object recipe.  This is a helper function used 
416
#   within this toolset.
417
#
418
#   Arguments:
419
#       $io         I/O stream
420
#
421
#       $target     Name of the target
422
#
423
#       $obj        Library specification
424
#
425
########################################################################
426
 
427
sub ToolsetObjRecipe
428
{
429
    my ($io, $target, $obj) = @_;
430
 
431
    $io->Def( "$obj.$::o" );
432
}
433
 
434
 
435
###############################################################################
436
#
437
#   Parse a linker lib list
438
#   This is a helper function used within this toolset
439
#
440
#   Used to create a variable that will be fedd into 'cmdfile'
441
#   The output will then be included in the makefile
442
#   The output extends the definitions of the program being built
443
#   to contain the absolute pathnames to the libraries being consumed.
444
#
445
#   Arguments:
446
#       $io         io printer class
447
#
448
#       $target     Name of the target
449
#
450
#       $lib        Library specification
451
#
452
###############################################################################
453
 
454
sub ToolsetLibRecipe
455
{
456
    my ($io, $target, $lib) = @_;
457
 
458
    $io->Cmd( "${target}_lib += @(vglob2,$lib.$::a,LIB)" );
459
}
460
 
461
#.. Successful termination
462
1;
463