Rev 343 | Blame | Compare with Previous | Last modification | View Log | RSS feed
######################################################################### Copyright (C) 2008 ERG Limited, All rights reserved## Module name : PHARLAP.PL# Module type : JATS TOOLSET# Compiler(s) : Perl# Environment(s): JATS## Description : PharLap (and VC6) for PHARLAP## Based on the WIN32 toolset# Pharlap uses the MS V6 compiler# but provides its own linker## Notes : The Pharlap linker does not support PDB files## Shared Library (DLL) support has not bee implemented# Not currently needed## Building via Visual Studio Project is to be discouraged.# The linker intrerface requires:# 1) Great care# 2) Hacking of the Visual Studio install##......................................................................#use strict;use warnings;## Global data#my $target_file_lib; # Last library builtmy $target_file_dll; # Last dll builtmy $target_file_exe; # Last program builtmy $toolset_name = 'pharlap'; # Toolset name : Error reporting############################################################################### Version information#my $toolset_info;my $toolset_version = 'PHARLAP.10.1';my %ToolsetVersion =('PHARLAP.10.1' => { 'def' => 'PHARLAP.def' ,'buildcmd' => 'msdev =DSW= /make "ALL - =TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'msdev =DSW= /make "ALL - =TYPE=" /clean /useenv' ,'tmp' => 'vc60','VSCOMPILER' => '1',},);############################################################################### ToolsetInit()# Runtime initialisation###############################################################################ToolsetInit();sub ToolsetInit{#.. Parse arguments (Toolset arguments)#Debug( "$toolset_name(@::ScmToolsetArgs)" );foreach $_ ( @::ScmToolsetArgs ) {if (/^--Version=(.*)/) { # MS SDK Version$toolset_version = $1;} else {Message( "$toolset_name toolset: unknown option $_ -- ignored\n" );}}#.. Parse arguments (platform arguments)#Debug( "$toolset_name(@::ScmPlatformArgs)" );foreach $_ ( @::ScmPlatformArgs ) {if (/^--product=(.*)/) { # GBE product} elsif (/^--Version=(.*)/) { # MS SDK Version$toolset_version = $1;} else {Message( "$toolset_name toolset: unknown platform argument $_ -- ignored\n" );}}#.. Validate SDK version# Currently only one version is supported# 1) PHARLAP.10.1 - As provided via Visual Studio and PharLap 10.1#$toolset_info = $ToolsetVersion{$toolset_version};Error( "toolset_name: Unknown version: $toolset_version" ) unless ( defined $toolset_info );#.. Standard.rul requirements#$::s = 'asm';$::o = 'obj';$::a = 'lib';$::so = 'dll';$::exe = '.exe';#.. Toolset configuration#$::ScmToolsetVersion = "1.0.0"; # our version$::ScmToolsetGenerate = 0; # generate optional$::ScmToolsetProgDependancies = 0; # handle Prog dependancies myself#.. define Visual C/C+ environmentInit( "visualc" );ToolsetDefines( $toolset_info->{'def'} );PlatformDefine ("VSCOMPILER\t= $toolset_info->{'VSCOMPILER'}" );ToolsetRequire( "exctags" ); # and Exuberant CtagsToolsetRules( "pharlap.rul" );ToolsetRules( "standard.rul" );#.. define PCLint envrionmentToolsetRequire( "pclint" ); # using pclintPlatformDefine ("LINT_COFILE\t= co-msc60.lnt");PlatformDefine ("LINT_PRJ_FILE\t=lint.visualc");#.. Cleanup rules#ToolsetGenerate( "\$(OBJDIR)/$toolset_info->{'tmp'}.idb" ); # vc60.idbToolsetGenerate( "\$(OBJDIR)/$toolset_info->{'tmp'}.pch" );ToolsetGenerate( "\$(OBJDIR)/$toolset_info->{'tmp'}.pdb" );#.. 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 =(## Control the thread model to use# This will affect the compiler options and the linker options#);## Set default options#}############################################################################### ToolsetPostprocess# Process collected data as the makefile is generated# This, optional, routine is called from within MakefileGenerate()# It allows the toolset to massage any of the collected data before# the makefile is finally closed created###############################################################################sub ToolsetPostprocess{MakeHeader('Toolset Postprocessed Information');## Add values to the perl environment# May be used by post processing tools to create Visual Studio Projects#$::TS_sbr_support = 1;## Prioritorise target: EXE, DLL, LIB#for my $tgt ( $target_file_exe, $target_file_dll, $target_file_lib ){if ( $tgt ){$::TS_target_file = $tgt;last;}}}################################################################################ 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{ToolsetCC_common( "CC", @_ );}sub ToolsetCC_common{my( $name, $source, $obj, $pArgs ) = @_;my( $cflags );foreach $_ ( @$pArgs ) {if (/--Shared$/) { # Building a 'shared' object$cflags = "$cflags \$(SHCFLAGS)";} else {Message( "$toolset_name $name: unknown option $_ -- ignored\n" );}}MakePrint( "\n\t\$($name)\n" );MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tCFLAGS +=$cflags\n" )if ( $cflags ); # object specific CFLAGS## Remove possible Source Browser Files and source file#ToolsetGenerate( "\$(OBJDIR)/$obj.sbr" );ToolsetGenerate( "\$(OBJDIR)/$obj.src" );MakePrint( "\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{ToolsetCC_common( "CXX", @_ );}################################################################################ 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{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:# --Def=name Library definition module## Output:# [ $(LIBDIR)/name$.${a}: .... ]# $(AR)################################################################################sub ToolsetAR{my( $name, $pArgs, $pObjs ) = @_;my( $def );my ( $res, @reslist );my $lib_base = "\$(LIBDIR)/${name}\$(GBE_TYPE)";my $lib_name = "$lib_base.${a}";#.. Parse arguments#$def = ""; # options$res = "";foreach $_ ( @$pArgs ) {if (/^--Def=(.*)/) { # library definition$def = "$1";} elsif (/^--Resource=(.*)/) { # Resource definition($res, @reslist) = ToolsetRClist( "$name", $1 );} else { # unknownMessage( "$toolset_name AR: unknown option $_ -- ignored\n" );}}#.. Resource Creation#MakePrint( "#.. Library Resource ($name)\n\n" );ToolsetRCrecipe( $res, @reslist )if ( $res );#.. Target#MakePrint( "#.. Library ($name)\n\n" ); # labelMakePrint( "$lib_name:\tLIBDEF=$def\n" ) if ($def);MakeEntry( "$lib_name:\t", "", "\\\n\t\t", ".$::o", @$pObjs );MakePrint( "\\\n\t\t$def" ) if ($def);MakePrint( "\\\n\t\t$res" ) if ($res);MakePrint( "\n\t\$(AR)" );## Track the name of the possible target file# Used when creating Visual Studio projects#$target_file_lib = $lib_name;}################################################################################ ToolsetARLINT( $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:# [ $(LIBDIR)/name$_lint: .... ]# $(ARLINT)################################################################################sub ToolsetARLINT{PCLintAR( @_ );}################################################################################ ToolsetARMerge( $name, \@args, \@libs )# This subroutine takes the user options and builds the rules# required to build the library 'name' by merging the specified# libaries## Arguments:# --xxx No arguments currently defined## Output:# [ $(LIBDIR)/name$.${a}: .... ]# ...################################################################################sub ToolsetARMerge{my ($name, $pArgs, $pLibs) = @_;MakePrint( "\n\t\$(ARMERGE)\n\n" );}################################################################################ Function : ToolsetLD## Description : Takes the user options and builds the rules required to# link the program 'name'.## Inputs : $name - base name of the program# $pArgs - Ref to program arguments# $pObjs - Ref to program objects# $pLibs - Ref to program library list## Returns : Nothing## Output: : Rules and recipes to create a program# Create program rules and recipes# Create linker input script# Create library dependency list# Include library dependency information#sub ToolsetLD{my ( $name, $pArgs, $pObjs, $pLibs ) = @_;my ( $res, @reslist );my @cmd_files;#.. Parse arguments#foreach ( @$pArgs ) {if (/^--Resource=(.*)/) { # Resource definition($res, @reslist) = ToolsetRClist( $name, $1 );} elsif (/^--CmdFile=(.+)/) {push @cmd_files, MakeSrcResolve($1);} else {Message( "$toolset_name LD: unknown option $_ -- ignored\n" );}}#.. Names of important files#my $base = "\$(BINDIR)/${name}";my $full = $base . $::exe;my $map = $base . '.map';#.. Cleanup rules## ld Linker command file# map Map file# ilk Microsoft Linker Database# res Compiled resource script#ToolsetGenerate( $map );ToolsetGenerate( $base . '.ld' );ToolsetGenerate( $base . '.ilk' );#.. Linker command#my ($io) = ToolsetPrinter::New();my $dep = $io->SetLdTarget( $name );$io->Prt( "$full : $dep " );$io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );$io->Prt( "\\\n\t$res " ) if ( $res );$io->Prt( "\n\t\$(LD)\n\n" );#.. Linker command file## Now piece together a variable $(name_ld) which ends up in# the command file linking the application.#$io->SetTag( "${name}_ld" ); # macro tag$io->Label( "Linker commands", $name ); # label$io->Cmd( "\@\$(subst /,\\\\,$_)" ) foreach (@cmd_files);$io->Cmd( "-exe \$(subst /,\\\\,$full)" );$io->Cmd( "-cvsymbols" );$io->Cmd( "-map \$(subst /,\\\\,$map)" );$io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );$io->ObjList( $name, $pObjs, \&ToolsetObjRecipe ); # object list$io->LibList( $name, $pLibs, \&ToolsetLibRecipe ); # library list$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, $full );$io->LDDEPEND();#.. Compile up the resource file#ToolsetRCrecipe( $res, @reslist )if ( $res );#.. Package up the program#PackageProgAddFiles ( $name, $full );## Track the name of the possible target file# Used when creating Visual Studio projects#$target_file_exe = $full;}################################################################################ ToolsetLD( $name, \@args, \@objs, \@libraries, \@csrc, \@cxxsrc )# This subroutine takes the user options and builds the rules# required to lint the program 'name'.## Arguments:# (none)## Output:# [ $(BINDIR)/$name_lint: .... ]# $(LDLINT)################################################################################sub ToolsetLDLINT{PCLintLD( @_ );}########################################################################## 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( "\$(subst /,\\\\,\$(strip $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$io->Cmd( "\$(subst /,\\\\,\$(strip $lib)).$::a" );} else { # depend$io->Cmd( "$dp:\t@(vlib2,$lib,LIB)" );}}########################################################################## Parse resource file data# This is a helper function used within this toolset## Arguments : $1 BaseName# $2 The users resource list# This is a list of comma seperated files# The first file is the main resource script## Returns : An array of resource files with full pathnames# [0] = The output file# [1] = The input file# [..] = Other input files#########################################################################sub ToolsetRClist{my ($name, $files) = @_;my @result;## Generate the name of the output file#push @result, "\$(OBJDIR)/$name.res";## Process each user file#for (split( '\s*,\s*', $files )){## Locate the 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#push @result, MakeSrcResolve($_);}## Return the array to the user#return @result;}########################################################################## Generate a resource file recipe# This is a helper function used within this tool## Arguments : $1 Output resource file# .. Input resource files#########################################################################sub ToolsetRCrecipe{my ($out, @in) = @_;## Cleanup#ToolsetGenerate( $out );## Recipe#MakePrint( "\n#.. Compile Resource file: $out\n\n" );MakePrint( "$out:\t\$(GBE_PLATFORM).mk\n" );MakeEntry( "$out:\t", "", "\\\n\t\t", " ", @in );MakePrint( "\n\t\$(RC)\n" );MakePrint( "\n" );}########################################################################## Generate a project from the provided project solution file# This is aimed at .NET work## Arguments : $name - Base name of the project# $solution - Path to the solutionn file# $pArgs - Project specific options#########################################################################my $project_defines_done = 0;sub ToolsetPROJECT{my( $name, $solution ,$pArgs ) = @_;my $buildcmd = $toolset_info->{'buildcmd'};my $cleancmd = $toolset_info->{'cleancmd'};my $release = 'RELEASE';my $debug = 'DEBUG';## Process options#foreach ( @$pArgs ) {if ( m/^--TargetProd*=(.+)/ ) {$release = $1;} elsif ( m/^--TargetDebug=(.+)/ ) {$debug = $1;} else {Message( "$toolset_name PROJECT: unknown option $_ -- ignored\n" );}}my ($io) = ToolsetPrinter::New();## Setup toolset pecific difinitions. Once#unless( $project_defines_done ){$project_defines_done = 1;$io->PrtLn( 'project_target = $(if $(findstring 1,$(DEBUG)),$2,$1)' );$io->Newline();}## Process the build and clean commands# Substitute arguments# =TYPE=# =LOG=# =DSW=#$buildcmd =~ s~=TYPE=~"\$(call project_target,$release,$debug)"~g;$buildcmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;$buildcmd =~ s~=DSW=~$solution~g;$cleancmd =~ s~=TYPE=~"\$(call project_target,$release,$debug)"~g;$cleancmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;$cleancmd =~ s~=DSW=~$solution~g;## Generate the recipe to create the project# Use the set_<PLATFORM>.sh file to extend the DLL search path#$io->Label( "Build project", $name );$io->PrtLn( "Project_$name: $solution \$(INTERFACEDIR)/set_$::ScmPlatform.sh" );$io->PrtLn( "\t\$(XX_PRE)( \$(rm) -f $name\$(GBE_TYPE).log; \\" );$io->PrtLn( "\t. \$(INTERFACEDIR)/set_$::ScmPlatform.sh; \\" );$io->PrtLn( "\t\$(show_environment); \\" );$io->PrtLn( "\t$buildcmd; \\" );$io->PrtLn( "\tret=\$\$?; \\" );$io->PrtLn( "\t\$(GBE_BIN)/cat $name\$(GBE_TYPE).log; \\" );$io->PrtLn( "\texit \$\$ret )" );$io->Newline();## Generate the recipe to clean the project#$io->Label( "Clean project", $name );$io->PrtLn( "ProjectClean_$name: $solution" );$io->PrtLn( "\t-\$(XX_PRE)$cleancmd" );$io->PrtLn( "\t-\$(XX_PRE)\$(rm) -f $name\$(GBE_TYPE).log" );$io->Newline();}#.. Successful termination1;