Subversion Repositories DevTools

Rev

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