Subversion Repositories DevTools

Rev

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

# -*- mode: perl; indent-width: 4; show-tabs: yes; -*-
#
# Module name   : PD386
# Module type   : Makefile system
# Compiler(s)   : ANSI C
# Environment(s): AMX/EOS
#
#                       ! WARNING - do not detab !
#
# Description:
#       Paradigm C/C++ toolset
#
# Version   Who      Date        Description
# 1.0       APY      20/02/02    Created (from WatcomC)
#           APY      26/02/02    Build system +v2 support.
#                                - prefixed 'exp' with '.' and
#                                  remove '.' from $(exe) references.
#                                - reconstructed isp creation
#                                - replaced ToolsetProg() with ToolsetGenerate().
#                                - ToolsetCC and ToolsetCXX switch processing
#                    30/04/02    --Isp must allow mutliple specifications.
#                    17/07/02    - c0t32
#                    16/04/04    - GBE_TARGET, replaced with GBE_PLATFORM
#
# $Source: /cvsroot/etm/devl/CFG/TOOLSET/PD386,v $
# $Revision: 1.2 $ $Date: 2004/04/23 05:47:03 $ $State: Exp $
# $Author: ayoung $ $Locker:  $
#............................................................................#

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

ToolsetInit();

sub ToolsetInit
{
#.. standard.rul requirements
    $s = 'asm';
    $o = 'obj';
    $a = 'lib';
    $rom = ".rom";         # inter-immediate link stage image
    $bin = ".bin";         # binary (BOOTBIOS) image
    $axe = ".axe";         # debug image

#.. define environment
    Init( "paradigm" );
    ToolsetDefines( "pd386.def" );
    ToolsetRules( "pd386.rul" );
    ToolsetRules( "standard.rul" );
}

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


###############################################################################
#   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
{
    my( $source, $obj, $pArgs ) = @_;
    my( $cflags ) = "";

    Debug( "CCX: $source -> $obj" );
    foreach ( @$pArgs ) {
        Debug( "option:    $_" );
        if ( /--Shared$/ ) {                    # Building a 'shared' object
            $cflags = "$cflags \$(SHCXXFLAGS)";
            Debug( "CCX:    as shared object" );

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

    MakePrint( "\n\t\$(CXX)\n" );
    MakePrint( "\$(OBJDIR)/$i.${o}:\tCXXFLAGS +=$cflags\n" )
        if ( $cflags );
}


###############################################################################
#   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() handles both CC and CXX source
}


###############################################################################
#   ToolsetAS( $source, $obj, \@args )
#       This subroutine takes the user options and builds the rule(s)
#       required to compile the source file 'source' to 'obj'
#
#   Output:
#       [ $(OBJDIR)/name$.${o}:         source-file ]
#           $(AS)
#
###############################################################################

sub ToolsetAS
{
    my( $source, $obj, $pArgs ) = @_;

    Debug( "AS: $source -> $obj" );
    foreach ( @$pArgs ) {
        Debug( "option:    $_" );
        Message( "AS: unknown option $_ -- ignored\n" );
    }

#.. Cleanup rules
#       name.lst                Generated 'list/xref' file.
#
    ToolsetGenerate( "\$(OBJDIR)/${obj}.lst" );

#.. Build rule (just append to standard rule)
#
    MakePrint( "\n\t\$(AS)\n" );
}

sub ToolsetASDepend
{
}


###############################################################################
#   ToolsetAR( $name, \@args, \@objs )
#       This subroutine takes the user options and builds the rules
#       required to build the library 'name'.
#
#   Arguments:
#       --Amx[=prefix]          local AMX configuration (defaults to platform)
#       --Isp=name              ISP module
#
#   Output:
#       [ $(BINDIR)/name$.${a}:   .... ]
#           $(AR)
#
#       name_ld += ...  Linker command file
#           :
#
#       name_dp += ...  Dependency list
#           :
#
###############################################################################

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

    local( $name_ld );

#.. Parse arguments
#
    $amx = $insight = 0;                        # options
    foreach $_ ( @$pArgs ) {
        if (/^--Amx$/) {                        # Local AMX config
            $amx     = "\$(SCM_PLATFORM)";
        } elsif (/^--Amx=(.*)/) {               # Specific AMX config
            $amx     = "$1";

        } elsif (/^--Isp=(.*)/) {               # ISP module
            push( @isp, "$1" );

        } elsif (/^--Insight$/) {               # Enable insight
            $insight = 1;
        } elsif (/^--Insight=(.*)/) {           # Specific insight
            $insight = "$1";

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

#.. Cleanup rules
#
#       library.lst             Generated 'list' file.
#
    ToolsetGenerate( "\$(LIBDIR)/${name}\$(SCM_TYPE).lst" );    

#.. Standard library builds, plus AMX configuration
#
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).${a}:\t",
                  "", "\\\n\t\t", ".${o} ", @$pObjs );

    foreach (@isp) {
        AmxLibISP( $name, $_ );
    }
    AmxLib( $name, $amx, $insight )
        if ( $amx );

    MakePrint( "\n\t\$(AR)\n\n" );
}


###############################################################################
#   ToolsetLD( $name, \@args, \@objs, \@libraries )
#       This subroutine takes the user options and builds the rules
#       required to link the program 'name'.
#
#   Arguments:
#       --Eos                   EOS application
#       --Eosx                  Extended EOS application
#       --NetUdp                Networking with UDP support
#       --NetTcp                Networking with TCP support
#       --Amx[=prefix]          Local AMX configuration (defaults to platform)
#       --Isp=name              ISP module
#       --Insight[=prefix]      Enable insight (default to platform.icf)
#       --Stack=#[k]            Stack size
#
#       Linker specific:
#       --Exe
#       --Bin                   Download image
#       --Axe                   Absolute image (PDREMOTE)
#       --Axe=monitor           Axe with using explicit monitor
#       --Section=...           Linker sector order directives
#
#   Output:
#       $(BINDIR)/name.exe:     << Generated by makelib
#                       $(BINDIR)/name.dep \
#                       $(BINDIR)/name.[axe|bin]
#
#       $(BINDIR)/name.dep:     $(SCM_PLATFORM).mk
#               $(LDDEPEND)
#
#       ifeq "$(IFLAG)" "3"
#       -include        "$(BINDIR)/name.dep"
#       endif
#
#       $(BINDIR)/name.[axe|bin]
#                       objs ...
#               {$(LDAXE)|$(LDBIN)}
#
#       name_ld += ...
#           :
#
###############################################################################

sub ToolsetLD
{
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
    my( $linker, $flags, $amx, $insight, $type, $idx );
    my( $cond );
    local( $varname );

#.. Parse arguments
#
    $stack = 0;
    $amx = $flags = $insight = 0;            # Options

    $type = ${axe};
    $section = "\$(GBE_PLATFORM).loc";
    $monitor = "\$(paradigm)/pdremote.rom/pdrem32";
    $bootcode = "\$(paradigm)/bin/biosboot.exe";

    foreach $_ ( @$pArgs )
    {
    #.. EOS
    #
       if (/--Eos$/) {                       # EOS standard
           $flags = $flags | $EOS_LNK;
       } elsif (/^--Eosx$/) {                # EOS extended
           $flags = $flags | $EOS_LNK | $EOS_EXT;

    #.. Networking
    #
        } elsif (/^--NetUdp$/) {
            $flags = $flags | $NET_UDP;
        } elsif (/^--NetTcp$/) {
            $flags = $flags | $NET_TCP;

    #.. AMX
    #
        } elsif (/^--Amx$/) {                # Local AMX config
            $amx = "\$(SCM_PLATFORM)";
        } elsif (/^--Amx=(.*)/) {            # Specific AMX config
            $amx = "$1";

        } elsif (/^--Isp=(.*)/) {            # ISP module
            AmxLinkISP( $name, "$1", $pObjs, $pLibs );

        } elsif (/^--Insight$/) {            # Enable insight
            $insight = "\$(SCM_PLATFORM)";
        } elsif (/^--Insight=(.*)/) {        # Specific insight
            $insight = "$1";

    #.. Target specific
    #
        } elsif (/^--Rom=/) {                # ROM image
            Message( "LD: linker option '$_' not supported -- ignored\n" );

        } elsif (/^--Bin/) {                 # Download image
            $type = ${bin};

        } elsif (/^--Axe/ || /^--Abs/) {     # PD. PDMONITOR image
            $type = ${axe};

        } elsif (/^--Axe=(.*)/) {            # PD, explicited PDMONITOR image
            $type = ${axe};
            $monitor = "$1";

        } elsif (/^--Biosboot=(.*)/) {       # PD, explicited BIOSBOOT image
            $type = ${bin};
            $bootcode = "$1";

        } elsif (/^--Section=(.*)/) {        # LOCATE32 section config
            $section = "$1";

        } elsif (/^--Kdb/) {                 # Kernel debugger
            $flags = $flags | $EOS_KDB;

    #.. Toolset specific
    #
        } elsif (/^--Stack=(.*)/) {          # stack size
            $stack = "$1";

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

#.. Command file, EOS and/or AMX dependencies
#
#   Library search order,
#       Application
#       EOS
#       AMX
#       Toolset (TNT/WATCOM)
#
    if ( $flags ) {
        EosLink( $name, $flags, $pObjs, $pLibs );
        if ( $amx ) {
            AmxLinkCfg( $name, $amx, $insight, $pObjs, $pLibs );
        } else {
            AmxLinkStd( $name, $pObjs, $pLibs );
        }
    } elsif ( $amx ) {
        AmxLinkCfg( $name, $amx, $insight, $pObjs, $pLibs );
    }

    push( @$pLibs, "\$(paradigm)/lib/noeh32" ); # toolset libraries
    push( @$pLibs, "\$(paradigm)/lib/embed32" );
    push( @$pLibs, "\$(paradigm)/lib/cw32" );

#.. Cleanup rules (generic)
#
    ToolsetGenerate( "\$(BINDIR)/${name}.ld" );
    ToolsetGenerate( "\$(BINDIR)/${name}.dep" );
    ToolsetGenerate( "\$(BINDIR)/${name}.map" );

#.. Linker command file
#
# PLINK32 objfiles, exefile, mapfile, libfiles, deffile, resfiles
# @xxxx indicates use response file xxxx
# -m      Map file with publics     -x       No map
# -s      Detailed segment map      -L       Specify library search paths
# -M      Map with mangled names    -j       Specify object search paths
# -c      Case sensitive link       -v       Full symbolic debug information
# -Enn    Max number of errors      -n       No default libraries
# -P-     Disable code packing      -H:xxxx  Specify app heap reserve size
# -B:xxxx Specify image base addr   -Hc:xxxx Specify app heap commit size
# -wxxx   Warning control           -S:xxxx  Specify app stack reserve size
# -Txx    Specify output file type  -Sc:xxxx Specify app stack commit size
# -Tpx          PE image            -Af:nnnn Specify file alignment
#               (x: e=EXE, d=DLL)   -Ao:nnnn Specify object alignment
# -ax     Specify application type  -o       Import by ordinals
#         -ap Windowing Compatible  -Vd.d    Specify Windows version
#         -aa Uses Windowing API    -r       Verbose link
#
#   Now the fun part... piecing together a variable $(name_ld)
#   which ends up in the command file.
#
# Outputs:
#   name.rom/     
#    name.exe     these files represent the link stage of the development, 
#                 where all of the objects are linked together.
#
#   name.map      Linker map
#
#   name.axe      Absolute image
#
#   name.rtb      RtTarget binary file
#
#   name.loc      Locator map
#
    $varname = "${name}_ld";
    sub LdCmd {                              # with line feed ...
        MakeQuote ("$varname +=@_\\n\n");
    }                                        
    sub LdTxt {                              # without line feed ...
        MakeQuote ("$varname +=@_\n");
    }
    sub LdPrt {
        MakeQuote ("@_");
    }

  if ( $type eq ${axe} || $type eq ${bin} )
  {
                                             # Additional generated images
    ToolsetGenerate( "\$(BINDIR)/${name}${type}" );
    ToolsetGenerate( "\$(BINDIR)/${name}.exe" );
    ToolsetGenerate( "\$(BINDIR)/${name}.loc" );
    ToolsetGenerate( "\$(BINDIR)/${name}.rtb" );

                                             # Rules
    MakePrint( " \\\n\t\t\$(BINDIR)/${name}.dep" );
    MakePrint( " \\\n\t\t\$(BINDIR)/${name}${type}" );
    MakePrint( " \n\n" );

    MakePrint( "\$(BINDIR)/${name}.dep:\t\$(SCM_PLATFORM).mk\n".
               "\t\$(LDDEPEND)\n\n" );

    MakePrint( "ifeq \"\$(IFLAG)\" \"3\"\n" .
               "-include\t\$(BINDIR)/${name}.dep\n" .
               "endif\n\n" );

                                             # Linker
    MakePrint( "\$(BINDIR)/${name}${rom}:\t\$(BINDIR)/${name}.dep" );
    foreach $i ( @$pObjs ) {
        MakePrint( " \\\n\t\t$i.${o}" );
    }
    MakePrint( "\n\t\$(LD)\n\n" );

                                             # Locate32
                  # If building a bin,
                  #    name.axe,    deleted, image can not be loaded.
                  #    name.rtb,    renamed to 'name.bin'.
                  #
    MakePrint( "\$(BINDIR)/${name}${type}:\tLOCATEOPT=-D__PDREMOTE__=".
         "\$(subst /,\\\\,$monitor)\n" )
         if ( $type eq ${axe});
    MakePrint( "\$(BINDIR)/${name}${type}:\tLOCATEOPT=-D__PDBOOTCODE__=".
         "\$(subst /,\\\\,$bootcode)\n" )
         if ( $type eq ${bin});
    MakePrint( "\$(BINDIR)/${name}${type}:\tLOCATECFG=$section\n" );
    MakePrint( "\$(BINDIR)/${name}${type}:\t\$(BINDIR)/${name}${rom}\n" );
    MakePrint( "\t\$(LD2)\n" );
    if ( $type eq ${bin} ) 
    {
       MakePrint( "\t@\$(rm) -f \$(BINDIR)/${name}${axe}\n");
       MakePrint( "\t@\$(rm) -f \$(BINDIR)/${name}${bin}\n");
       MakePrint( "\t@\$(mv) \$(BINDIR)/${name}.rtb \$(BINDIR)/${name}${bin}\n");
    }
    MakePrint( "\n" );

    #   Piece together a variable $(name_ld) which ends up 
    #   in the PLINK32 command file.  Note the order of arguments 
    #   is criticial and must be seperated by a comma(,) with 
    #   plus(+) used for line continuation.
    #
    $varname = "${name}_ld";

                                             # Objects,
                                             # .. startup code
        # C0T32: C run time library entry point for "tiny" NT apps.
        # C0X32: C run time library entry point for NT apps.
        #
    if (($flags & $EOS_LNK) || $amx) {
        LdTxt( "\$(subst /,\\\\,\$(paradigm)/lib/c0t32).${o}" );
    } else {
        LdTxt( "\$(subst /,\\\\,\$(paradigm)/lib/c0x32).${o}" );
    }

                                             # .. users objects
    foreach $i ( @$pObjs ) {
        LdTxt( "+\\n\$(subst /,\\\\,\$(strip $i)).${o}" )
    }
        LdCmd( "" );

                                             # Output files
        LdCmd( "\$(subst /,\\\\,\$(BINDIR)/${name}${rom})" );
        LdCmd( "\$(subst /,\\\\,\$(BINDIR)/${name}.map)" );

                                             # Libraries
    foreach $_ ( @$pLibs ) {
        if (/^--ifdef=(.*)/) {               # .. conditionals
            $cond = "$1";
            LdPrt( "ifdef $cond\n" );
            next;
        } elsif (/^--ifndef=(.*)/) {
            $cond = "$1";
            LdPrt( "ifndef $cond\n" );
            next;
        } elsif (/^--*/) {                   # .. unknown
            Message( "LD: unknown lib option $_ -- ignored\n" );
            next;
        }

                                             # ... entry
                                             # Note the line continuation !
        LdCmd("\@(dosify,@(vpath2,$_.${a},PD386_LIB)) +");

        if ($cond) {                         # .. end condition
            LdPrt("endif\t# $cond\n");
            $cond = "";
        }
    }
    MakePrint( "\n" );                       # .. terminate library list

    #   Now Piece together a variable $(name_dp) which ends up in the 
    #   command file building the application dependency list. Note
    #   the dependency are on the 'rom' image not the 'exe'.
    #
    $varname = "${name}_dp";

    $cond = "";
    foreach $_ ( @$pLibs ) {
        if (/^--ifdef=(.*)/) {               # .. conditionals
            $cond = "$1";
            LdPrt( "ifdef $cond\n" );
            next;
        } elsif (/^--ifndef=(.*)/) {
            $cond = "$1";
            LdPrt( "ifndef $cond\n" );
            next;
        } elsif (/^--*/) {                   # .. unknown
            Message( "LD: unknown lib option $_ -- ignored\n" );
            next;
        }

                                             # ... entry
        LdCmd("\$(BINDIR)/${name}${rom}:\t@(vpath2,$_.${a},PD386_LIB)" );

        if ($cond) {                         # .. end condition
            LdPrt("endif\t# $cond\n");
            $cond = "";
        }
    }
  }
  else  # "rom"
  {
  }
}

#.. Successful termination
1;