Subversion Repositories DevTools

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

#..
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
#
# Module name   : AVR32-GNU
# Module type   : Makefile system
# Compiler(s)   : ANSI C
# Environment(s): Atmel AVR
#
# Description:
#       This file provides Toolset initialisation and plugin functions
#       to makelib.pl2
#
# Contents:     AVR32-GNU rules as used for the AVR
#
#............................................................................#

use strict;

our $s;
our $o;
our $so;
our $exe;

#   Toolset specific globals
my $avrPart;                                    # Device Part

##############################################################################
#   ToolsetInit()
#       Runtime initialisation
#
##############################################################################

ToolsetInit();

sub ToolsetInit
{
    my( @args ) = @::ScmToolsetArgs;             # Toolset arguments
    my $toolName = 'avr32_gnu';

    #.. Parse arguments
    #
    Debug( "$toolName(@args)\n" );

    foreach $_ ( @args ) {
        if ( m~^-part=(.*)~) {
            $avrPart = $1;
        } else {
            Message( "$toolName: unknown toolset argument $_ -- ignored\n" );
        }
    }

    #.. Parse Platform Arguments
    #
    foreach $_ ( @::ScmPlatformArgs ) {
        Message( "$toolName: unknown platform argument $_ -- ignored\n" );
    }

    #
    #   Sanity Test
    #   Platform definition MUST supply the Device Part
    #
    Error ('$toolName: No part specified') 
        unless defined $avrPart;

    #.. Standard.rul requirements
    #
    $s = 'asm';             # Assembler source file : Not supported
    $o = 'o';               # Object file
    $a = 'a';               # Library file
    $so = '';               # Shared library : Not supported
    $exe = '.bin';          # Linked binary images

    #.. Toolset configuration
    #
    $::ScmToolsetVersion = "1.0.0";               # our version
    $::ScmToolsetGenerate = 0;                    # generate optional
    $::ScmToolsetProgDependancies = 0;            # handle Prog dependancies myself

    #.. Compiler paths
    #   Based on an environment variable
    #
    my $GCCBin      = '${GBE_AVR32_GNU}' . '/bin/avr32-gcc';
    my $GCCAr       = '${GBE_AVR32_GNU}' . '/bin/avr32-ar';
    my $GCCObjCopy  = '${GBE_AVR32_GNU}' . '/bin/avr32-objcopy';

#.. Define GCC environment
#
    PlatformDefine( "
#################################################
# GCC toolchain definitions 
#
#..");
    PlatformDefine( "GCC_CC             = $GCCBin" );
    PlatformDefine( "GCC_AR             = $GCCAr" );
    PlatformDefine( "GCC_OBJCOPY        = $GCCObjCopy" );

    #
    #   Sanity checking
    #
    PlatformDefine( "GCC_EVERSION       := 4.4.7" );
    PlatformDefine( "GCC_EMACHINE       := avr32" );


    #.. Define AVR32 environment
    #
    #   Define initialisation targets
    #   These will be used to ensure that correct versions of the toolset are present
    #
    Init( "avr32" );

    ToolsetDefine ( "#################################################" );
    ToolsetDefine ( "# AVR32 GNU compiler version" );
    ToolsetDefine ( "#" );
    ToolsetDefines( "avr32_gnu.def" );
    ToolsetRules  ( "avr32_gnu.rul" );
    ToolsetRules  ( "standard.rul" );

    #.. AVR32 definitions
    PlatformDefine("AVR32_PART          := " . $avrPart);

    # Ctags support
    PlatformDefine( "CTAGS_EXE:= ctags" );
    ToolsetRequire( "exctags" );                # and Exuberant Ctags

}

###############################################################################
#   ToolsetCTAGS()
#       This subroutine takes the user options and builds the rules
#       required to build the CTAGS database.
#
#   Arguments:
#       --xxx                   No arguments currently defined
#
#   Output:
#       [ctags:]
#           $(EXCTAGS)
#
###############################################################################

sub ToolsetCTAGS
{
    EXCTAGS( @_ );
}

###############################################################################
#   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
{
    MakePrint( "\n\t\$(CC)\n" );
}

###############################################################################
#   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" );
}


###############################################################################
#   ToolsetCXX( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
###############################################################################

sub ToolsetCXX
{
    MakePrint( "\n\t\$(CXX)\n" );
}

###############################################################################
#   ToolsetCXXDepend( $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 ToolsetCXXDepend
{
    ToolsetCCDepend();
}

###############################################################################
#   ToolsetAR( $name, \@args, \@objs )
#       This subroutine takes the user options and builds the rules
#       required to build the library 'name'.

#
#   Arguments:
#       --xxx                   No arguments currently defined
#
#   Output:
#       [ $(BINDIR)/name$.${a}:   .... ]
#           $(AR)
#
###############################################################################

sub ToolsetAR
{
    my( $name, $pArgs, $pObjs ) = @_;

    Debug("ToolsetAR");

#.. Parse arguments
#
    foreach $_ ( @$pArgs ) {
        if (/^--/) {
            Message( "AR: unknown option $_ -- ignored\n" );
        }
    }

#.. Target
#
    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, \@args, \@objs, \@libraries )
#       This subroutine takes the user options and builds the rules
#       required to link the program 'name'.
#
#   Arguments:
#       --xxx                   No Arguments currently specified
#
#       Linker specific:
#       --Script=filename       Specify the name of a linker script file
#
#   Output:
#
#       name.map                - Linker map
#       name.elf                - Linker Output
#       name.bin                - Generated Program
#
###############################################################################

sub ToolsetLD
{
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
    my( $script );


    #.. Parse arguments
    #
    foreach $_ ( @$pArgs )
    {
        if (/^--Script=(.*)/) {           # External file
            $script = $1;
            $script .= ".lds" unless ( $script =~ m~\.lds$~ );

        } else {
            Message( "Prog: unknown option $_ -- ignored\n" );
        }
    }

    #
    #   Sanity check
    #       - Ensure a linker script has been provided, or guess at a default one
    #       - Use name.lds. Iff it exists in the current directory
    #         Else try name based on the 'part'
    #
    unless ( $script )
    {
        $script = "$name.lds";
        unless (-f $script) {
            $script = 'link_'.$avrPart.'sdram.lds';
        }
        Warning( "Prog: Linker Script file not provided. Using $script" );
    }

    #
    #   Locate the true path of the provided script file
    #   If it is a generate file so it will be in the SRCS hash
    #   Other wise the use will have to use Src to locate the file
    #
    $script = MakeSrcResolve ( $script );

    #
    #   Create a ToolsetPrinter
    #
    my ($io) = ToolsetPrinter::New();
    my $dep = $io->SetLdTarget( $name );

    #
    #   Determine the target output name
    #
    my $root = "\$(BINDIR)/$name";
    my $full = $root . $::exe;
    my $map = $root . '.map';
    my $elf = $root . '.elf';
    

    ########################################################################
    #
    #   Create a makefile recipe to build an ELF file
    #       Depends upon
    #               Library dependency file
    #               User linker script file
    #               Objects
    # 
    $io->Label( "Program", $name );                     # label
    $io->Prt( "$elf : \t$dep" );                        # Dependencies
    $io->Prt( "\\\n\t\t$script" );
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );  # Object Files
    $io->Prt( "\n\t\$(LD)\n" );
    $io->Newline();

    #
    #   Specify files created by the linker
    #   These will be added to the clean list
    #
    ToolsetGenerate( $elf );
    ToolsetGenerate( $map );

    #
    #   Create a linker command file
    #   Piecing together a variable $(name_ld) which ends up in the command file.
    #   This bit of magic will be performed by the LD recipe
    #
    $io->SetTag( "${name}_ld" );                            # macro tag
    $io->Label( "Linker commands", $name );                 # label
    $io->SetTerm( "\n" );

    $io->Cmd('-nostartfiles' );
    $io->Cmd('-Wl,--gc-sections' );
    $io->Cmd('--rodata-writable' );
    $io->Cmd('-Wl,--direct-data' );
    $io->Cmd('-Wl,--relax' );
    $io->Cmd('-Wl,-e,_trampoline' );
    $io->Cmd('-mpart=$(AVR32_PART)' );
    $io->Cmd('-T ' . $script );                             # User script file

    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );      # Object files

    #
    #   Specify the library files
    #
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );      # Specify the libraries too
    $io->Newline();

    #.. Dependency link,
    #   Create a library dependency file
    #       Create command file to build applicaton dependency list
    #       from the list of dependent libraries
    #
    #       Create makefile directives to include the dependency
    #       list into the makefile.
    #
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $elf );
    $io->LDDEPEND(); 

    #
    #   Create a recipe to convert the ELF file to a BIN
    #   The BIN depends only on ELF file
    #
    $io->Label( "Program Bin", $name );                 # label
    $io->Prt( "$full : \t$elf" );                       # Dependencies
    $io->Prt( "\n\t\$(call ELF2BIN,$full,$elf)\n\n" );

    #
    #   Define the files to the packaged up as a part of the prog
    #       BIN file
    #       MAP file - but only if the user wants it
    #
    PackageProgAddFiles ( $name, $full );
    PackageProgAddFiles ( $name, $map , 'Class=map' );
}

########################################################################
#
#   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->Cmd("$obj.$::o" );
}

########################################################################
#
#   Generate a linker/depend library recipe.  This is a helper function
#   used within this toolset.
#
#   Arguments:
#       $io         I/O stream
#
#       $target     Name of the target
#
#       $lib        Library specification
#
#       $dp         If building a depend list, the full target name.
#
########################################################################

sub ToolsetLibRecipe
{
    my ($io, $target, $lib, $dp) = @_;

    if ( ! defined($dp) ) {                     # linker
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
        $io->Cmd( "-l$lib" );
    
    } else {                                    # depend
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );

    }
}

#.. Successful termination
1;