# -*- 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;