Rev 327 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
################################################################################ Module name : TOOLSET/KeilArmV3# Module type : Makefile system# Environment(s):## Description:# Keil MDK Arm V4.3 toolset# A very simple toolset to support# 1) C compiliation# 2) Generation of libaries# 3) Merging of libraries# 4) Executables# 5) Assembler files## Does not support ( because its not needed yet )# a) Shared libraries###############################################################################our @ScmToolsetArgs;############################################################################### ToolsetInit()# Runtime initialisation###############################################################################ToolsetInit();sub ToolsetInit{my $KeilVersion = "MDK Arm V4.3";my $GenThumb;my $GenDevice;#.. Parse arguments#foreach $_ ( @ScmToolsetArgs ) {if ( m~^--Thumb~ ) {$GenThumb=1;} elsif ( m~^--Device=(.*)~ ) {$GenDevice = $1;} else {Message( "KeilArmV3: unknown option $_ -- ignored\n" );}}Error ("KeilArmV3: Toolset error. --Device must be specified")unless ( $GenDevice );#.. Standard.rul requirements#$s = 's';$o = 'o';$a = 'lib';$exe = '.bin';AddSourceType( ".$s", '.asm' );#.. Define environment#Init( "KeilArmV3" );ToolsetDefine( "#################################################" );ToolsetDefine( "# Compiler version" );ToolsetDefine( "#" );ToolsetDefine( "KeilC Version = \"$KeilVersion\"" );ToolsetDefine( "USE_THUMB = 1" ) if $GenThumb;ToolsetDefine( "USE_DEVICE = $GenDevice" );ToolsetDefine( "" );ToolsetDefine( "#" );ToolsetDefines( "KeilArmV3.def" );ToolsetRules ( "KeilArmV3.rul" );ToolsetRules ( "standard.rul" );## Extend the cleanup rule#ToolsetGenerate( '*.lst' );#.. Extend the CompilerOption directive# Create a standard data structure# This is a hash of hashes# The first hash is keyed by CompileOption keyword# The second hash contains pairs of values to set or remove#%::ScmToolsetCompilerOptions =('nowarn=' => { 'NOWARNLIST' ,\&NoWarns }, # Suppress warnings'timeoptimization' => { 'OPT_MODE' , 'time' }, # Time optimize'spaceoptimization' => { 'OPT_MODE' , 'space' }, # Space optimize'defaultoptimization' => { 'OPT_MODE' , undef }, # Default (?space));## Set default options# $::ScmCompilerOpts{'xxxx'} = 'yyy';#$::ScmCompilerOpts{'NOWARNLIST'} = '';$::ScmCompilerOpts{'OPT_MODE'} = 'space';}#-------------------------------------------------------------------------------# Function : NoWarns## Description : ScmToolsetCompilerOptions extension function# Accumulates the NoWarn options as a comma seperated list## Inputs : $key - Name of the Option# $value - Option Value. Comma sep list of numbers# $ukey - User key (within $::ScmCompilerOpts)## Returns : New sting to save#sub NoWarns{my ($key, $value, $ukey) = @_;my @NoWarnList = split (',', $::ScmCompilerOpts{$ukey});UniquePush ( \@NoWarnList, split (',', $value) );return join ',', @NoWarnList;}################################################################################ ToolsetAS( $source, $obj, \@args )# This subroutine takes the user options and builds the rule(s)# required to compile the source file 'source' to 'obj'################################################################################sub ToolsetAS{MakePrint( "\n\t\$(AS)\n" );}sub ToolsetASDepend{}################################################################################ ToolsetCC( $source, $obj, \@args )# This subroutine takes the user options and builds the rule(s)# required to compile the source file 'source' to 'obj'################################################################################sub ToolsetCC{my( $source, $obj, $pArgs ) = @_;Debug( "CC: $source -> $obj" );foreach ( @$pArgs ) {Debug( "option: $_" );if ( /--Shared$/ ) { # Building a 'shared' object$cflags = "$cflags \$(SHCFLAGS)";Debug( "CC: as shared object" );} else { # unknown optionMessage( "CC: unknown option $_ -- ignored\n" );}}MakePrint( "\n\t\$(CC)\n" );MakePrint( "\$(OBJDIR)/$i.${o}:\tCFLAGS +=$cflags\n" )if ( $cflags );}################################################################################ ToolsetCCDepend( $depend, \@sources )# This subroutine takes the user options and builds the# rule(s) required to build the dependencies for the source# files 'sources' to 'depend'.################################################################################sub ToolsetCCDepend{MakePrint( "\t\$(CCDEPEND)\n" );}################################################################################ ToolsetAR( $name, \@args, \@objs )# This subroutine takes the user options and builds the rules# required to build the library 'name'.## Arguments:# n/a## Output:# [ $(BINDIR)/name$.${a}: .... ]# $(AR)################################################################################sub ToolsetAR{my( $name, $pArgs, $pObjs ) = @_;#.. Parse arguments#foreach $_ ( @$pArgs ){Message( "AR: unknown option $_ -- ignored\n" );}#MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).${a}:\t", "", " \\\n\t\t", ".${o}", @$pObjs );#.. Build library rule (just append to standard rule)#MakePrint( "\n\t\$(AR)\n\n" );}################################################################################ ToolsetARMerge()# Generate the recipe to merge libraries.# The dependency list is created by the caller.################################################################################sub ToolsetARMerge{MakePrint( "\n\t\$(ARMERGE)\n\n" );}#-------------------------------------------------------------------------------# ToolsetLD( $name, \@pArgs, \@pObjs, \@pLibs )# This subroutine takes the user options and builds the rules# required to link the program 'name'.## Toolset is configured to suppress partial creation of the Package# Rules. This function must create the complete rule and recipe set.## Arguments:# $name - Name of the output# $pArgs - Ref to array of args# $pObjs - Ref to array of objects# $pLibs - Ref to array of libs## Options:# --Map - Create a MAP file# --NoMap - Don't create a MAP file# --Scatter=file - Names a scatter file to be used# --ro-base=text - Names the ReadOnly base# --rw-base=text - Names the ReadWrite base# --Script=file - Additional Linker commands## Output:# Generates makefile rules and recipes to create a program#sub ToolsetLD{my( $name, $pArgs, $pObjs, $pLibs ) = @_;my $map_file;my $scatter_file;my $ro_base;my $rw_base;my @script_files;#.. Parse arguments#foreach ( @$pArgs ){if ( m~^--Map~i ) {$map_file = 1;} elsif ( m~^--NoMap~i ) {$map_file = 0;} elsif ( m~^--Scatter=(.+)~i ) {Src ('*', $1 );$scatter_file = MakeSrcResolve($1);} elsif ( m~^--Script=(.+)~i ) {Src ('*', $1 );push @script_files, MakeSrcResolve($1);} elsif ( /^--ro-base=(.+)/i ) {$ro_base = $1;} elsif ( m~^--rw-base=(.+)~i ) {$rw_base = $1;} else {Error( "LD: unknown option $_ -- ignored\n" );}}## Sanity test#Error ("Can't use --scatter in conjunction with -ro-base or -rw-base")if ( $scatter_file && ( $ro_base || $rw_base) );## Determine the target output name#my $root = "\$(BINDIR)/$name";my $full = $root . $::exe;my $axf = $root . '.axf';my $dep = $root . '.dep';my $map = $root . '.map';my $call = $root . '.htm';#.. Packageing# Have supressed default Prog building# Need to specify the files to Package#PackageProgAddFiles ( $name, $full );PackageProgAddFiles ( $name, $map, 'Class=map' ) if $map_file;#.. Cleanup rules#ToolsetGenerate( $dep );ToolsetGenerate( $map );ToolsetGenerate( $axf );ToolsetGenerate( $call );#.. Build rules#my ($io) = ToolsetPrinter::New();## Standard Dependency rules# Will generate rules to# 1) Determine at make-time the full paths to the libraries# 2) Include the above information#$io->LDDEPEND( $name ); # standard LDDEPEND rules#.. Dependency link,## Now piece together a variable $(name_dp) which ends up in# the command file building the application dependency list.#$io->SetTag( "${name}_dp" ); # macro tag$io->SetTerm();$io->DepRules( $name, $pLibs, \&ToolsetLibRecipe ); # library depends rules$io->Newline();## List the object files# Create a definition for the objects#$io->Label( "Object files", $name ); # label$io->StartDef ("${name}_obj");$io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );$io->EndDef ();$io->Newline();## Define the program and its dependencies# Place the .dep file first - this will ensure that failure# to create this file will create an error before the object# files are compiled. This makes it obvious what the error is.#$io->Label( "Program", $name ); # label$io->Prt( "$axf : \t$dep" ); # Dependencies$io->Prt( " \\\n\t$scatter_file" ) if ($scatter_file);$io->Prt( " \\\n\t$_" ) foreach (@script_files);$io->Prt( " \\\n\t\$(${name}_obj)" ." \\\n\t\$(${name}_lib)" );$io->Newline();## Recipe to build the program#$io->PrtLn( "\t\$(LD)" );#.. Linker command file## Create a variable $(name_ld) which will be the linker# command line. Use previosly defined values#$io->Label( "Linker commands", $name ); # label$io->StartDef ("${name}_ld");$io->Def( "\$(${name}_obj)" ); # Object file list variable$io->Def( "\$(${name}_lib)" ); # Library list variable$io->Def( "--scatter=$scatter_file" ) if ($scatter_file);$io->Def( "--ro-base=$ro_base" ) if defined ($ro_base);$io->Def( "--rw-base=$rw_base" ) if defined ($rw_base);$io->Def( "--list=$map" ) if ( $map_file );$io->Def( "--via=$_" ) foreach (@script_files);$io->EndDef ();$io->Newline();## Create rules to convert the .axf file into a bin file# Done as a seperate step##$io->Label( "Elf Converion ", $name ); # label$io->Prt( "$full : \t$axf\n" ); # Dependencies## Recipe to build the program#$io->PrtLn( "\t\$(FROMELF)" );}########################################################################## Generate a linker object recipe. This is a helper function used# within this toolset.## Arguments:# $io I/O stream## $target Name of the target## $obj Library specification#########################################################################sub ToolsetObjRecipe{my ($io, $target, $obj) = @_;$io->Def( "$obj.$::o" );}################################################################################# Parse a linker lib list# This is a helper function used within this toolset## Used to create a variable that will be fedd into 'cmdfile'# The output will then be included in the makefile# The output extends the definitions of the program being built# to contain the absolute pathnames to the libraries being consumed.## Arguments:# $io io printer class## $target Name of the target## $lib Library specification################################################################################sub ToolsetLibRecipe{my ($io, $target, $lib) = @_;$io->Cmd( "${target}_lib += @(vglob2,$lib.$::a,LIB)" );}#.. Successful termination1;