Subversion Repositories DevTools

Rev

Rev 261 | 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   : wc386
# Module type   : Makefile system
# Compiler(s)   : ANSI C
# Environment(s): AMX/EOS
#
#                       ! WARNING - do not detab !
#
# Description:
#       Watcom C/C++ toolset, using TNT70 and MASM
#
# Version   Who      Date        Description
# 1.0       APY      07/05/99    Created
# 1.2       APY      06/12/99    - Linker network options
#                                - Corrected DEBUG test within
#                                       linker command file generation.
# 1.3       APY      09/12/99    - ToolsetProg() calls added.
#                                - Build application dependency list
# 1.4       APY      06/01/00    Linker --Kdb support
#                    07/01/00    ifeq "$(IFLAG)" "3"
#                                  around -include directives
#                    14/03/00     vpath2()
#                    13/06/00    --Stack  
#           APY      13/11/00    ${exe} now embeddes '.' if required.
#                    26/02/02    remove generated asm list files
# 2.0       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.
#
# $Source: /cvsroot/etm/devl/CFG/TOOLSET/WC386,v $
# $Revision: 1.1 $ $Date: 2003/07/03 15:15:03 $ $State: Exp $
# $Author: ayoung $ $Locker:  $
#............................................................................#

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

ToolsetInit();

sub ToolsetInit
{
#.. standard.rul requirements
    $s = 'asm';
    $o = 'obj';
    $a = 'lib';
    $exe = ".exp";

#.. define WATCOM environment
    Init( "watcom" );
    ToolsetDefines( "wc386.def" );
    ToolsetRules( "wc386.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();
}


###############################################################################
#   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
{
#.. Parse arguments
#

#.. Cleanup rules
#
#       name.lst                Generated 'list/xref' file.
#
    ToolsetGenerate( "\$(OBJDIR)/${name}.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
#       --[wlib|386lib]         Librarian (todo)
#
#   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" );
        }
    }

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

#.. Build library with AMX configuration
#
    foreach (@isp) {
        AmxLibISP( $name, $_ );
    }
    AmxLib( $name, $amx, $insight )
        if ( $amx );

#.. Build library rule (just append to standard rule)
#
    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)
#       --Tnt70                 Link TNT70 libs
#       --Rel                   n/a under DOS
#       --Abs                   n/a under DOS
#       --[Wlink|Pharlap]       linker (todo)
#       --Stack=#[k]            Stack size
#
#   Output:
#       $(BINDIR)/name${exe}:
#                       $(BINDIR)/name.dep
#           $(LD)
#
#       $(BINDIR)/name.dep:    $(SCM_PLATFORM).mk
#               $(LDDEPEND)
#
#       ifeq "$(IFLAG)" "3"
#       -include        "$(BINDIR)/name.dep"
#       endif
#
#       name_ld += ...
#           :
#
###############################################################################

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

#.. Parse arguments
#
    $stack = 0;
    $linker = "wlink";                          # linker
    $amx = $flags = $insight = $tnt70 = 0;      # options

    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: not suitable under WC386 '$_' -- ignored\n" );
        } elsif (/^--Bin=(.*)/) {               # Download image
            Message( "LD: not suitable under WC386 '$_' -- ignored\n" );
        } elsif (/^--Abs/) {
            Message( "LD: not suitable under WC386 '$_' -- ignored\n" );
        } elsif (/^--Kdb/) {                    # Kernel debugger
            $flags = $flags | $EOS_KDB;
            $laddr = "$1";                      # Load address

    #.. Toolset specific
    #
        } elsif (/^--Tnt70=(.*)/) {             # Link TNT70
            $tnt70   = 1;
        } elsif (/^--wlink$/) {                 # use wlink linker (default)
            $linker  = "wlink";
        } elsif (/^--386link$/) {               # use 386linker
            $linker  = "386link";
        } 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, "\$(tnt70)/lib/dosx32" )
        if ($flags || $amx || $tnt70);
    push( @$pLibs, "\$(watcom)/lib386/dos/clib3r" );
    push( @$pLibs, "\$(watcom)/lib386/dos/emu387" );
    push( @$pLibs, "\$(watcom)/lib386/math387r" );

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

#.. Linker command file
#
#       Now the fun part... piecing together a variable $(name_ld)
#       which ends up in the command file.
#
    MakePrint( "\\\n\t\t\$(BINDIR)/${name}.dep\n" .
               "\t\$(LD)\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" );

    $varname = "${name}_ld";
    sub VarCmd {                                # with line feed ...
        MakeQuote ("$varname += @_\\n\n");
    }
    sub VarCmd2 {                               # without line feed ...
        MakeQuote ("$varname += @_\n");
    }
    sub VarPrt {
        MakePrint ("@_\n");
    }

        VarCmd( "FORMAT Pharlap Extended" );
        VarPrt( "ifeq \"\$(DEBUG)\" \"1\"" );
        VarCmd( "DEBUG  Watcom All" );
        VarPrt( "endif" );

    foreach $i ( @$pObjs ) {
        VarCmd( "FILE   \$(subst /,\\\\,\$(strip $i)).${o}" );
    }

        VarCmd2( "\$(patsubst %,LIBPATH %\\n,\$(subst /,\\\\,\$(LIBDIRS)))" );

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

                                             # .. entry
        VarCmd( "LIBRARY        \$(subst /,\\\\,\$(strip $_)).${a}" );

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

        VarCmd( "OPTION CaseExact" );
        VarCmd( "OPTION NoDefaultLibs" );
        VarCmd( "OPTION Offset=0x1000" );
        VarCmd( "OPTION Map=\$(subst /,\\\\,\$(BINDIR)/${name}.map)" );
        VarCmd( "OPTION Stack=$stack" )
            if ($stack);
        VarCmd( "OPTION Verbose" );
        VarCmd( "RUNTIME        Privileged" );

    if ($flags || $amx) {
        VarCmd( "RUNTIME        RealBreak=_cj_psedata" );
        VarCmd( "RUNTIME        MinReal=0x8000" );
        VarCmd( "RUNTIME        MaxReal=0x8000" );
        VarCmd( "RUNTIME        NiStack=18" );
    } else {
        VarCmd( "RUNTIME        RealBreak=0" );
    }

        VarCmd( "NAME   \$(subst /,\\\\,\$(BINDIR)/${name}${exe})" );
        VarPrt( "" );

#.. Dependency link,
#
#       Now piece together a variable $(name_dp) which ends up in
#       the command file building the application dependency list.
#
    $varname = "${name}_dp";

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

                                             # .. entry
        VarCmd("\$(BINDIR)/${name}${exe}:       @(vpath2,$_.${a},WC386_LIB)" );

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

#.. Successful termination
1;