Rev 255 | Blame | Last modification | View Log | RSS feed
# -*- mode: perl; indent-width: 4; show-tabs: yes; -*-## Module name : vcwce# Module type : Makefile system# Compiler(s) : ANSI C# Environment(s): WCE## Description:# Visual C/C++ for WCE##............................................................................#use strict;use warnings;## Global data#my $pdb_file = "\$(GBE_PBASE)";my $pdb_first_lib;my $target_file_lib;my $target_file_dll;my $target_file_exe;my $pdb_none;############################################################################### ToolsetInit()# Runtime initialisation###############################################################################my( $WCEVersion ) = "";my( $WCESubsystem ) = "";my( $WCEPlatform ) = "";my( $WCEPlatformDefine ) = "";my( $WCEPlatformClean ) = "";my( $WCETargetCPU ) = "";my( $WCEHostCPU ) = "";my( $WCEToolchain ) = "";ToolsetInit();sub ToolsetInit{my( $wceroot, $sdkroot );my( $compiler, $linker );my( @defines ) = ();my( @cflags, @cflags_debug, @cflags_prod ) = ();my( @libflags, @ldflags, @ldflags_debug, @ldflags_prod ) = ();#.. 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#.. Parse arguments#Debug( "vcwce(ToolsetArgs=@::ScmToolsetArgs)" );foreach ( @::ScmToolsetArgs ) {Message( "vcwce toolset: unknown option $_ -- ignored\n" );}Debug( "vcwce(PlatformArgs=@::ScmPlatformArgs)" );foreach ( @::ScmPlatformArgs ) {if (/^--Version=(.*)/) { # OS Version$WCEVersion = "$1";} elsif (/^--SDK=(.*)/) { # SDK$WCEPlatform = "$1";} elsif (/^--Target=(.*)/) { # CPU$WCETargetCPU = "$1";} elsif (/^--Host=(.*)/) { # Emulator host CPU$WCEHostCPU = "$1";} elsif (/^--Toolchain=(.*)/) { # Toolchain$WCEToolchain = "$1";} elsif (/^--product=(.*)/) { # GBE product} elsif (/^--NoDinkumware/) { # Deprecated switch} else {Message( "vcwce toolset: unknown platform argument $_ -- ignored\n" );}}#.. Select toolchain, based on targetCPU### The following table shows the processors that eMbedded Visual C++# currently supports.## ARM ARMV4, ARMV4I, ARMV4T# MIPS MIPSII, MIPSII_FP, MIPSIV, MIPSIV_FP, MIPS16# Hitachi SH3, SH4# x86 x86, x86 emulation#..Error ("TOOLSET/vcwce - Version undefined")if ($WCEVersion eq "");Error ("TOOLSET/vcwce - SDK undefined")if ($WCEPlatform eq "");Error ("TOOLSET/vcwce - TargetCPU undefined")if ($WCETargetCPU eq "");Error ("TOOLSET/vcwce - HostCPU undefined")if ($WCEPlatform eq "emulator" && $WCEHostCPU eq "");# .. Generate CE Platform definition based on the selected SDK# The following is a list of known defintions for some SDKs# In the EVC studio these are $(CePlatform)#..my %PlatformSDKDefinitions =('H/PC 2000' => 'WIN32_PLATFORM_HPC2000','H/PC Pro 2.11' => 'WIN32_PLATFORM_HPCPRO','Pocket PC' => 'WIN32_PLATFORM_PSPC','Pocket PC 2002' => 'WIN32_PLATFORM_PSPC=310','POCKET PC 2003' => 'WIN32_PLATFORM_PSPC=400','Smartphone 2002' => 'WIN32_PLATFORM_WFSP=100','IT-3000' => 'WCE_PLATFORM_PX780J_ARMV4I','PCM7220' => 'WCE_PLATFORM_SOCERXS','ADVANTECH_X86_420' => 'WCE_PLATFORM_ADVANTECH_X86_420','SOM_4450_2' => 'WCE_PLATFORM_SOM_4450_2','adv_som_4455_wlan' => 'WCE_PLATFORM_adv_som_4455_wlan','PsionTeklogixCE420'=> 'WCE_PLATFORM_STANDARDSDK','PsionTeklogixCE500'=> 'WCE_PLATFORM_STANDARDSDK','PA961' => 'WCE_PLATFORM_PA961','PA962' => 'WCE_PLATFORM_PA962','PA962 WINCE 500' => 'WCE_PLATFORM_PA962',);$WCEPlatformDefine = $PlatformSDKDefinitions{$WCEPlatform};Error ("TOOLSET/vcwce - SDK not defined. Extend table","SDK: $WCEPlatform" )unless ( defined $WCEPlatformDefine );$WCEPlatformClean = $WCEPlatform;$WCEPlatformClean =~ s/\s/_/g;$WCESubsystem = "windowsce," . int($WCEVersion/100) . "." . $WCEVersion%100if ( !defined($WCESubsystem) || $WCESubsystem eq "" );if ( $WCETargetCPU eq "armv4" ) {$compiler = "clarm";$linker = "link";@defines = ( '-DARM', '-D_ARM_', '-DARMV4' );@cflags = ( '-QRarch4', '-GX' );@cflags_debug = ( '-M$(CECrtDebug)' );@cflags_prod = ( '-M$(CECrtMT)' );push( @ldflags, '-base:0x00010000' );push( @ldflags, '-stack:0x10000,0x1000' );push( @ldflags, '-entry:WinMainCRTStartup' );push( @ldflags, '$(CENoDefaultLib)' );push( @ldflags, '-Subsystem:$(CESubsystem)' );push( @ldflags, '-align:4096' );push( @ldflags, '-MACHINE:ARM' );push( @ldflags, 'commctrl.lib' );push( @ldflags, 'coredll.lib' );push( @ldflags, 'aygshell.lib' );push( @libflags, '-MACHINE:ARM' );} elsif ( $WCETargetCPU eq "armv4i" ) {$compiler = "clarm";$linker = "link";@defines = ( '-DARM', '-D_ARM_', '-DARMV4I' );@cflags = ( '/QRarch4T' );@cflags = ( '/QRinterwork-return' );@cflags_debug = ( '-M$(CECrtDebug)' );@cflags_prod = ( '-M$(CECrtMT)' );push( @ldflags, '-base:0x00010000' );push( @ldflags, '-stack:0x10000,0x1000' );push( @ldflags, '-entry:WinMainCRTStartup' );push( @ldflags, '$(CENoDefaultLib)' );push( @ldflags, '-Subsystem:$(CESubsystem)' );push( @ldflags, '-MACHINE:THUMB' );push( @ldflags, 'commctrl.lib' );push( @ldflags, 'coredll.lib' );push( @libflags, '-MACHINE:THUMB' );} elsif ( $WCETargetCPU eq "armv4t" ) {$compiler = "clthumb";$linker = "link";@cflags = ( '/QRarch4t' );@defines = ( '-DARM', '-D_ARM_', '-DARMV4T' );} elsif ( $WCETargetCPU eq "mips16" ) {$compiler = "clmips";$linker = "link";@cflags = ( '/QMmips16' );@defines = ( '-DMIPS', '-D_MIPS_' );} elsif ( $WCETargetCPU eq "mips16ii" ) {$compiler = "clmips";$linker = "link";@cflags = ( '/QMmips16' );@defines = ( '-DMIPS', '-D_MIPS_' );} elsif ( $WCETargetCPU eq "mipsii_fp" ) {$compiler = "clmips";$linker = "link";@cflags = ( '/QMFWCE' );@defines = ( '-DMIPS', '-D_MIPS_' );} elsif ( $WCETargetCPU eq "mipsiv" ) {$compiler = "clmips";$linker = "link";@defines = ( '-DMIPS', '-D_MIPS_' );} elsif ( $WCETargetCPU eq "mipsiv_fp" ) {$compiler = "clmips";$linker = "link";@cflags = ( '/QMFWCE' );@defines = ( '-DMIPS', '-D_MIPS_' );} elsif ( $WCETargetCPU eq "sh3" ) {if ( $WCEVersion >= 400 ) { # SDK specific$compiler = "clsh";} else {$compiler = "shcl";}$linker = "link";@cflags = ( '-Qsh3' );@defines = ( '-DSHx', '-DSH3', '-D_SH3_' );} elsif ( $WCETargetCPU eq "sh4" ) {if ( $WCEVersion >= 400 ) { # SDK specific$compiler = "clsh";} else {$compiler = "shcl";}$linker = "link";@cflags = ( '-Qsh4' );@defines = ( '-DSHx', '-DSH4', '-D_SH4_' );} elsif ( $WCETargetCPU eq "x86" ) {$compiler = "cl";$linker = "link";@cflags = ( '-Gs8192', '-GF' );@defines = ( '-D_X86_', '-Dx86', '-D_i386_' );push( @ldflags, '-section:.shared,rws' );push( @ldflags, '-base:0x00100000' );push( @ldflags, '-stack:0x10000,0x1000' );push( @ldflags, '-entry:WinMainCRTStartup' );push( @ldflags, '-Subsystem:$(CESubsystem)' );push( @ldflags, '-MACHINE:IX86' );push( @ldflags, '$(CENoDefaultLib)' );push( @ldflags, '-nodefaultlib:oldnames.lib' );push( @ldflags, '$(CEx86Corelibc)' );push( @ldflags, 'coredll.lib' );push( @ldflags, 'commctrl.lib' );push( @ldflags, 'aygshell.lib' );push( @libflags,'-MACHINE:IX86' );} elsif ( $WCETargetCPU eq "emulator" ) {if ( $WCEHostCPU eq "x86" ) {$compiler = "cl";$linker = "link";@defines = ( '-D_X86_', '-Dx86', '-D_i386_' );@cflags = ( '-Gs8192', '-GF', '-GX' );push( @ldflags, '-base:0x00010000' );push( @ldflags, '-stack:0x10000,0x1000' );push( @ldflags, '-entry:WinMainCRTStartup' );push( @ldflags, '-Subsystem:$(CESubsystem)' );push( @ldflags, '-MACHINE:IX86' );push( @ldflags, '$(CENoDefaultLib)' );push( @ldflags, '-nodefaultlib:oldnames.lib' );push( @ldflags, '$(CEx86Corelibc)' );push( @ldflags, 'commctrl.lib' );push( @ldflags, 'coredll.lib' );push( @ldflags, 'aygshell.lib' );push( @libflags,'-MACHINE:IX86' );} else {Error ("TOOLSET/vcwce - unknown HostCPU '$WCEHostCPU'");}} else {Error ("TOOLSET/vcwce - unknown TargetCPU '$WCETargetCPU'");}#.. Define eMebbed C/C+ environment#Init( "vcembedded" );if ( $WCEVersion >= 400 ) { # SDK specific$wceroot = '\\Microsoft eMbedded C++ 4.0';$sdkroot = '\\Windows CE Tools'.'\\wce'.$WCEVersion.'\\'.$WCEPlatform;} else {$wceroot = '\\Microsoft eMbedded Tools';$sdkroot = '\\Windows CE Tools'.'\\wce'.$WCEVersion.'\\'.$WCEPlatform;}Debug( "\twceroot = $wceroot" );Debug( "\tsdkroot = $sdkroot" );Debug( "\tWCEVersion = $WCEVersion" );Debug( "\tWCESubsystem = $WCESubsystem" );Debug( "\tWCEPlatform = $WCEPlatform" );Debug( "\tWCEPlatformDefine = $WCEPlatformDefine" );Debug( "\tWCEPlatformClean = $WCEPlatformClean" );Debug( "\tWCETargetCPU = $WCETargetCPU" );Debug( "\tWCEHostCPU = $WCEHostCPU" );PlatformDefine( "################################################## Default paths, toolchain and flags##..PROGRAMFILES ?= C:\\Program Filesifndef WCEROOTWCEROOT := \$(PROGRAMFILES)\\" . $wceroot ."export WCEROOTendififndef SDKROOTSDKROOT := \$(PROGRAMFILES)\\" . $sdkroot ."export SDKROOTendifWCE_VERSION := $WCEVersionWCE_SUBSYSTEM := $WCESubsystemWCE_PLATFORM := $WCEPlatformWCE_PLATFORM_SDK_DEF := $WCEPlatformDefineWCE_PLATFORM2 := $WCEPlatformCleanWCE_TARGETCPU := $WCETargetCPUWCE_HOSTCPU := $WCEHostCPU");PlatformDefine( "CESubsystem := \$(WCE_SUBSYSTEM)CEVersion := \$(WCE_VERSION)CEPlatform := \$(WCE_PLATFORM)");if ( $WCEVersion < 201 ) {PlatformDefine( 'CECrt := LCECrtDebug := LdCECrtMT := TCENoDefaultLib := \-nodefaultlib:corelibc.libCEx86Corelibc :=');} else {PlatformDefine( 'CECrt := CCECrtDebug := CCECrtMT := CCENoDefaultLib := \\-nodefaultlib:libc.lib\-nodefaultlib:libcd.lib\-nodefaultlib:libcmt.lib\-nodefaultlib:libcmtd.lib\-nodefaultlib:msvcrt.lib\-nodefaultlib:msvcrtd.libCEx86Corelibc := corelibc.lib' );}PlatformDefine( "WCE_EMULATOR\t". ":= 1" )if ( $WCETargetCPU eq "emulator" );PlatformEntry( "WCE_DEFINES\t=", "\n", "\\\n\t", "", @defines )if ( scalar @defines );PlatformEntry( "WCE_CFLAGS\t=", "\n", "\\\n\t", "", @cflags )if ( scalar @cflags );PlatformEntry( "WCE_CFLAGSD\t=", "\n", "\\\n\t", "", @cflags_debug )if ( scalar @cflags_debug );PlatformEntry( "WCE_CFLAGSP\t=", "\n", "\\\n\t", "", @cflags_prod )if ( scalar @cflags_prod );PlatformEntry( "WCE_LDFLAGS\t=", "\n", "\\\n\t", "", @ldflags )if ( scalar @ldflags );PlatformEntry( "WCE_LIBFLAGS\t=", "\n", "\\\n\t", "", @libflags )if ( scalar @libflags );PlatformEntry( "WCE_LDFLAGSD\t=", "\n", "\\\n\t", "", @ldflags_debug )if ( scalar @ldflags_debug );PlatformEntry( "WCE_LDFLAGSP\t=", "\n", "\\\n\t", "", @ldflags_prod )if ( scalar @ldflags_prod );PlatformDefine( "WCE_CC := $compilerWCE_LINK := $linker" );ToolsetDefines( "vcwce.def" );ToolsetRules( "vcwce.rul" );ToolsetRules( "standard.rul" );#.. define PCLint envrionmentToolsetRequire( "pclint" ); # using pclintPlatformDefine ("LINT_COFILE\t= co-msc60.lnt");PlatformDefine ("LINT_PRJ_FILE\t=lint.vcembedded");#.. Cleanup rules#ToolsetGenerate( "\$(OBJDIR)/vc60.idb" );ToolsetGenerate( "\$(OBJDIR)/vc60.pch" );ToolsetGenerate( "\$(OBJDIR)/vc60.pdb" );ToolsetGenerate( "\$(PDB)" );ToolsetGenerate( "\$(PDB).tmp" );## The PDB files need to be compiled up with absolute paths to the source files# The easiest way to do this is with the makefile rules created with absolute# paths. Set a global flag to enable this option#$::UseAbsObjects = 1;#.. 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 =('rtti' => { 'USE_RTTI', 1 },'nopdb' => { 'PDB_NONE', 1 },'pdb' => { 'PDB_NONE', undef },);## Set default options## $::ScmCompilerOpts{'THREADMODE'} = 'D';}############################################################################### ToolsetPreprocess()# Process collected data before 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 created###############################################################################sub ToolsetPreprocess{## Extract the current state of PDB_NONE# Are PDB files to be constructed.#$pdb_none = $::ScmCompilerOpts{'PDB_NONE'};}############################################################################### 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{## Specify the name of the global PDB file. This is used for all# compiles other than those associated with building a DLL## The name of the PDB will be based on either# The name of base package# The name of the first static library created#MakePrint("#--------- Toolset Postprocessed Information --------------------------------## Export the name of the common PDB file# All compiler information will be placed in this file# The name of the file MUST be the same as the name of the output library#PDB = \$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb" );## Add values to the perl environment# May be used by post processing tools to create Visual Studio Projects#$::TS_pdb_file = "\$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb" unless( $pdb_none );$::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;}}}################################################################################ 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, $pdb );foreach $_ ( @$pArgs ) {if (/--Shared$/) { # Building a 'shared' object$cflags = "$cflags \$(SHCFLAGS)";$pdb = $::SHOBJ_LIB{$obj}if (exists $::SHOBJ_LIB{$obj} );} else {Message( "vcwce $name: unknown option $_ -- ignored\n" );}}MakePrint( "\n\t\$($name)\n" );MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tCFLAGS +=$cflags\n" )if ( $cflags ); # object specific CFLAGSif ( $pdb && !$pdb_none ){## Determine the name of the PDB file# If we are building a shared library then the name of the PDB# MUST NOT be the same as the name of the library as there is# some stange interaction with the linker ( 50% of the time )# This is OK as the file will not be published## If building a static library then create a PDB of the same# name as it may be published directly.#my $pdb_file;if ($cflags ){$pdb_file = "\$(OBJDIR)/${pdb}\$(GBE_TYPE)_shlib.pdb";}else{$pdb_file = "\$(OBJDIR)/${pdb}\$(GBE_TYPE).pdb";}MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tPDB = $pdb_file\n" );ToolsetGenerate( $pdb_file );ToolsetGenerate( $pdb_file . ".tmp" );}## Remove possible Source Browser Files#ToolsetGenerate( "\$(OBJDIR)/$obj.sbr" );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{MakePrint( "\t\$(CCDEPEND)\n" );}################################################################################ 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( "vcwce 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;## To assist in debugging the static library it is nice to# keep the PDB file used to build the library, with the library.## If the library is being packaged or installed then add the PDB# file to the package / installation## NOTE: Due to the limitations of JATS/MicroSoft only one static# library can be built with a PDB file. The name of the PDB file# will be taken from the first static library encountered#unless ( $pdb_first_lib ){$pdb_first_lib = $name;$pdb_file = $name;}else{Warning( "Multiple static libraries created with a common PDB file: $pdb_file, $name" )unless( $pdb_none );}PackageLibAddFiles( $name, "\$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb", "Class=debug" )unless( $pdb_none );}################################################################################ 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" );## Package up the PDB's with the library# Note: The PDBs will be found in the OBJDIR#unless( $pdb_none ){for ( @{$pLibs} ){s~\$\(LIBDIR\)~\$(OBJDIR)~;PackageLibAddFiles( $name, "$_\$(GBE_TYPE).pdb", "Class=debug" );}}}################################################################################ ToolsetSHLD $name, \@args, \@objs, \@libraries )# This subroutine takes the user options and builds the rules# required to link a shared library## Arguments:# --Def=xxxx.def[,opts] # Definition file# --MutualDll # SubOption: Generate a Mutual DLL# --MutualDll # Generate a Mutual DLL (requires --Def=xxx)# --StubOnly # Only generate the stub library (requires --Def=xxx)# --Resource=xxxx.rc # Resource file# --ResourceOnly # Only resources in this DLL# --Implib # Alternate ruleset# --NoPDB # Do not package the PDB file# --NoImplib # Do not package the import library# --Entry=xxxxx # Entry point# --NoAddLibs # Do not add libraries## Output:## There is two supported rule sets differentiated by --Implib# The two are very similar and generated exportable files of:## --Implib# ${name}.lib - Stub lib adresses the versioned DLL# ${name}.${ver}.dll## Default# ${name}.lib - Stub lib addresses UN-versioned DLL# ${name}.dll# ${name}.${ver}.dll## Note: Each DLL has an associated PDB file## Generation is identical for both rulesets. The default form does# not export any stub library associated with the versioned DLL.## Implementation notes# The process of creating a DLL and associated import library (LIB) is## ${name}.${ver}.dep# ${name}.${ver}.pdb - Exported# ${name}.${ver}.ilk# ${name}.${ver}.dll - Exported# ${name}.${ver}.map# ${name}.lib - Exported + Optional# ${name}.exp## Where: lib = name## #.. Rules ($lib)## $(LIBDIR)/${lib}.lib: $(LIBDIR)/${lib}.${ver}.dll# $(LIBDIR)/${lib}.pdb: $(LIBDIR)/${lib}.${ver}.dll# $(LIBDIR)/${lib}.${ver}.pdb: $(LIBDIR)/${lib}.${ver}.dll## $(LIBDIR)/${lib}.${ver}.dep: SHBASE=${name}# $(LIBDIR)/${lib}.${ver}.dep: SHNAME=${lib}.${ver}# $(LIBDIR)/${lib}.${ver}.dep: \$(LIBDIR)# $(LIBDIR)/${lib}.${ver}.dep: Makefile# $(SHLDDEPEND)## $(LIBDIR)/${lib}.${ver}.${so}: SHBASE=${name}# $(LIBDIR)/${lib}.${ver}.${so}: SHNAME=${lib}.${ver}# $(LIBDIR)/${lib}.${ver}.${so}: CFLAGS+=$(SHCFLAGS)# $(LIBDIR)/${lib}.${ver}.${so}: CXXLAGS+=$(SHCXXFLAGS)# $(LIBDIR)/${lib}.${ver}.${so}: ${def}# $(LIBDIR)/${lib}.${ver}.${so}: $(OBJDIR)/${name} \# object list ... \# $(LIBDIR)/${lib}.${ver}.dep# $(SHLD)# @$(cp) -f $(LIBDIR)/${lib}.${ver}.pdb $(LIBDIR)/${lib}.pdb## ifneq "$(findstring $(IFLAG),23)" ""# -include "$(LIBDIR)/${lib}.${ver}.dep"# endif## #.. Linker commands ($lib)## ${lib}_ld += ...# standard flags \# -implib:$${lib}.lib## #.. Linker commands ($lib)## ${lib}_shdp += ...################################################################################sub ToolsetSHLD{our( $name, $pArgs, $pObjs, $pLibs ) = @_;our( $def, $mutual_dll, $res, @reslist, $doimplib, $stub_only );our( $no_implib, $no_pdb, $resource_only );our( $entry, $noaddlibs );#.. Parse arguments#$def = ""; # options$doimplib = 0;$res = "";$no_pdb = $pdb_none;foreach $_ ( @$pArgs ) {if (/^--Def=(.*?)(\,(.*))?$/) { # Library definition## Locate the Def file.# If it is a generate file so it will be in the SRCS hash# Otherwise the user will have to use Src to locate the file#$def = MakeSrcResolve($1);## Process sub options to --Def#next unless ($2);if ( $3 =~ /^--MutualDll$/ ) {$mutual_dll = 1;} else {Message( "vcwce SHLD: unknown option $_ -- ignored\n" );}} elsif (/^--Resource=(.*)/) { # Resource definition($res, @reslist) = ToolsetRClist( "$name/$name", $1 );} elsif (/^--ResourceOnly/) { # Resource definition$resource_only = 1;} elsif (/^--Implib$/) {$doimplib = 1;} elsif (/^--NoImplib$/) {$no_implib = 1;} elsif (/^--NoPDB$/) {$no_pdb = 1;} elsif (/^--Entry=(.*)/) {$entry = $1;} elsif (/^--NoAddLib/) {$noaddlibs = 1;} elsif (/^--MutualDll$/) {$mutual_dll = 1;} elsif (/^--Stubonly/) {$stub_only = 1;} else { # unknownMessage( "vcwce SHLD: unknown option $_ -- ignored\n" );}}## Sanity test#Error ("vcwce SHLD:Stubonly option requires --Def=file ")if ( $stub_only && ! $def );Error ("vcwce SHLD:MutualDll option requires --Def=file ")if ( $mutual_dll && ! $def );#.. Build rules## base - Basic name of the DLL# name - Name of the Export library (Optional)# lib - Name of the DLL#sub BuildSHLD{my ($base, $name, $lib) = @_;my $full = $lib.".$::so";my $link_with_def;#.. Cleanup rules## dep Dependency file# ld Linker command file# map Map file# pdb Microsoft C/C++ program database# ilk Microsoft Linker Database#ToolsetGenerate( "\$(LIBDIR)/${lib}.ld" );ToolsetGenerate( "\$(LIBDIR)/${lib}.dep" );ToolsetGenerate( "\$(LIBDIR)/${lib}.map" );ToolsetGenerate( "\$(LIBDIR)/${lib}.exp" );ToolsetGenerate( "\$(LIBDIR)/${lib}.ilk" );ToolsetGenerate( "\$(LIBDIR)/${full}" );#.. Linker rules#my ($io) = ToolsetPrinter::New();my $import_lib;my $export_file;if ( $name && $def && ($mutual_dll || $stub_only ) ){## Creating an Export library from user .DEF file# It is possible to create the stub library in the LIB phase# which allows DLLs with mutual imports#$io->Label( "Import(stub) library for mutual exports", $name );$export_file = "\$(LIBDIR)/${name}.exp";## Rules and recipe to generate the stub library#$io->Prt( "\$(LIBDIR)/${name}.exp:\t\$(LIBDIR)/${name}.${a}\n" );$io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBDEF=$def\n" );$io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBNAME=$lib\n" );$io->Entry( "\$(LIBDIR)/${name}.${a}: \\\n\t\t\$(OBJDIR)/${base}","", " \\\n\t\t", ".$::o", @$pObjs );$io->Prt( " \\\n\t\t$def" );$io->Prt( "\n\t\t\$(AR)\n" );$io->Newline();## Files to be cleanup up#ToolsetGenerate( "\$(LIBDIR)/${name}.exp" );ToolsetGenerate( "\$(LIBDIR)/${name}.${a}" );## If the DLL is being packaged/installed then add the static# stub library to the packaging lists as a static library# This will allow the stub library to be installed with the# static libraries and thus allow DLL's with mutual imports#PackageShlibAddLibFiles ($base, "\$(LIBDIR)/${name}.${a}" )unless ($resource_only);## Add the stub library to the list of libraries being created# Note: Don't do if not created with .DEF file#push @::LIBS, $base;}else{## The stub library is created as part of the DLL generation# Whether we like it or not - so we need to control the name# and location#my $slname = ($name) ? $name : $lib;$import_lib = "\$(LIBDIR)/${slname}.${a}";$io->Label( "Import(stub) library", $slname );$io->Prt( "$import_lib:\t\$(LIBDIR)/${full}\n" );$io->Newline();ToolsetGenerate( $import_lib );ToolsetGenerate( "\$(LIBDIR)/${slname}.exp" );## Package the generated stub library, if it is being# created on request.## Package it with the shared libaries and not the static# libraries as it will be created with the shared library#PackageShlibAddFiles ($base, $import_lib, 'Class=lib' )if ($name && ! $no_implib && ! $resource_only);## Indicate that we will be linking with a DEF file#$link_with_def = 1 if ( $def );}## If we are only creating a stub library, then the hard work has been# done.#returnif ($stub_only);$io->Label( "Shared library", $name );## The process of creating a DLL will generate PDB file# Control the name of the PDB file#my $pdb_file = "\$(LIBDIR)/${lib}.pdb";unless( $no_pdb ){$io->Prt( "$pdb_file:\t\$(LIBDIR)/${full}\n" );ToolsetGenerate( $pdb_file );}## Package the PDB file up with the DLL# Package the DLL - now that we know its proper name#PackageShlibAddFiles( $base, $pdb_file, 'Class=debug' ) unless $no_pdb ;PackageShlibAddFiles( $base, "\$(LIBDIR)/${full}" );## Generate Shared Library dependency information#$io->SHLDDEPEND( $lib, $name, $lib ); # std SHLDDEPEND rules## Generate rules and recipes to create the body of the shared# library. Several build variables are overiden when creating# a shared library.#$io->Prt( "\$(LIBDIR)/${full}:\tSHBASE=${lib}\n" );$io->Prt( "\$(LIBDIR)/${full}:\tSHNAME=${lib}\n" );$io->Prt( "\$(LIBDIR)/${full}:\tCFLAGS+=\$(SHCFLAGS)\n" );$io->Prt( "\$(LIBDIR)/${full}:\tCXXLAGS+=\$(SHCXXFLAGS)\n" );$io->Prt( "\$(LIBDIR)/${full}:\t$export_file\n" ) if ($export_file );$io->Prt( "\$(LIBDIR)/${full}:\t$res\n" ) if ( $res );$io->Entry( "\$(LIBDIR)/${full}: \\\n\t\t\$(OBJDIR)/${base}","", " \\\n\t\t", ".$::o", @$pObjs );$io->Prt( " \\\n\t\t$def" ) if ( $link_with_def );$io->Prt( " \\\n\t\t\$(LIBDIR)/${lib}.dep\n" );$io->Prt( "\t\$(SHLD)\n" );$io->Newline();#.. Linker command file## Now the fun part... piecing together a variable ${name}_shld# which ends up in the command file.#$io->SetTag( "${lib}_shld" ); # command tag$io->Label( "Linker commands", $name ); # label$io->Cmd( "-dll" );$io->Cmd( "-noentry" )if ($resource_only);$io->Cmd( "-def:$def" ) if ($link_with_def);$io->Cmd( "-out:\$(subst /,\\\\,\$(LIBDIR)/${full})" );$io->Cmd( "-implib:\$(subst /,\\\\,$import_lib)" ) if ($import_lib);$io->Cmd( "-pdb:\$(subst /,\\\\,$pdb_file)" ) unless ( $no_pdb );$io->Cmd( "-debug:none" ) if ($no_pdb);$io->Cmd( "-pdb:none" ) if ($no_pdb);$io->Cmd( "-entry:$entry" ) if ($entry);$io->Cmd( "-map:\$(subst /,\\\\,\$(LIBDIR)/${lib}).map" );$io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );$io->Cmd( "\$(subst /,\\\\,$export_file)" ) if ( $export_file );# object list$io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );# library list$io->LibList( $name, $pLibs, \&ToolsetLibRecipe );$io->Newline();#.. Dependency link,## Now piece together a variable $(name_dp) which ends up in# the command file building the application dependency list.#$io->SetTag( "${lib}_shdp" ); # command tag$io->DepRules( $name, $pLibs, # library depends rules\&ToolsetLibRecipe, "\$(LIBDIR)/${full}" );$io->Newline();}ToolsetLibStd( $pLibs ) # push standard librariesunless ( $noaddlibs );if ( $doimplib ) {## --Implib flavor will create# a) Import library $name$(GBE_TYPE).lib# b) Versioned DLL $name$(GBE_TYPE).xx.xx.xx.dll#$target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::SHLIB_VER{ $name }.$::so";BuildSHLD("$name", # Base Name"$name\$(GBE_TYPE)", # Name of Export Lib"$name\$(GBE_TYPE).$::SHLIB_VER{ $name }"); # Name of the DLL + PDB} else {## Original flavor will create# a) Import library $name$(GBE_TYPE).lib ---+# b) Unversioned DLL $name$(GBE_TYPE).dll <--+# c) Versioned DLL $name$(GBE_TYPE).xx.xx.xx.dll#MakePrint("# .. Versioned image\n\n"."\$(LIBDIR)/${name}\$(GBE_TYPE).$::so:\t"."\$(LIBDIR)/${name}\$(GBE_TYPE).$::SHLIB_VER{ $name }.$::so\n"."\n" );$target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::so";BuildSHLD( "$name", "$name\$(GBE_TYPE)" , "$name\$(GBE_TYPE)" );BuildSHLD( "$name", "" , "$name\$(GBE_TYPE).$::SHLIB_VER{ $name }" );}#.. Resource File#ToolsetRCrecipe( $res, @reslist )if ( $res );}################################################################################ ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )# This subroutine takes the user options and builds the rules# required to lint the program 'name'.## Arguments:# (none)## Output:# [ $(LIBDIR)/$name_lint: .... ]# $(SHLIBLINT)################################################################################sub ToolsetSHLDLINT{PCLintSHLIB( @_ );}################################################################################ ToolsetLD( $name, \@args, \@objs, \@libraries )# This subroutine takes the user options and builds the rules# required to link the program 'name'.## Arguments:# (none)## Output:# $(BINDIR)/name: \# OBJS .... \# $(BINDIR)/name.dep# $(LD)## $(BINDIR)/name.dep: $(BINDIR)# $(BINDIR)/name.dep: $(GBE_PLATFORM).mk# $(LDDEPEND)## ifeq "$(IFLAG)" "3"# -include "$(BINDIR)/name.dep"# endif## name_ld += ...# :## name_dp += ...# :################################################################################sub ToolsetLD{my ( $name, $pArgs, $pObjs, $pLibs ) = @_;my ( $full ) = $name."$::exe";my ( $res, @reslist );my $no_pdb =$pdb_none;our( $entry, $noaddlibs );#.. Parse arguments#foreach ( @$pArgs ) {if (/^--Resource=(.*)/) { # Resource definition($res, @reslist) = ToolsetRClist( $name, $1 );} elsif (/^--NoPDB$/) {$no_pdb = 1;} elsif (/^--Entry=(.*)/) {$entry = $1;} elsif (/^--NoAddLib/) {$noaddlibs = 1;} else {Message( "vcwce LD: unknown option $_ -- ignored\n" );}}#.. Cleanup rules## dep Dependency file# ld Linker command file# map Map file# pdb Microsoft C/C++ program database# ilk Microsoft Linker Database# res Compiled resource script#ToolsetGenerate( "\$(BINDIR)/${name}.dep" );ToolsetGenerate( "\$(BINDIR)/${name}.ld" );ToolsetGenerate( "\$(BINDIR)/${name}.map" );ToolsetGenerate( "\$(BINDIR)/${name}.pdb" );ToolsetGenerate( "\$(BINDIR)/${name}.ilk" );#.. Linker command#my ($io) = ToolsetPrinter::New();$io->Prt( "\\\n\t\t$res " ) if ( $res );$io->Prt( "\\\n\t\t\$(BINDIR)/${name}.dep\n"."\t\$(LD)\n\n" );$io->LDDEPEND( $name ); # standard LDDEPEND rules#.. 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( "-out:\$(subst /,\\\\,\$(BINDIR)/${full})" );$io->Cmd( "-pdb:\$(subst /,\\\\,\$(BINDIR)/${name}).pdb" ) unless ($no_pdb);$io->Cmd( "-debug:none" ) if ($no_pdb);$io->Cmd( "-pdb:none" ) if ($no_pdb);$io->Cmd( "-entry:$entry" ) if ($entry);$io->Cmd( "-map:\$(subst /,\\\\,\$(BINDIR)/${name}).map" );$io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );ToolsetLibStd( $pLibs ) # push standard librariesunless ( $noaddlibs );# object list$io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );# library list$io->LibList( $name, $pLibs, \&ToolsetLibRecipe );$io->Newline();#.. Dependencies## Now piece together a variable $(name_dp) which ends up in# the command file building the application dependency list.#$io->SetTag( "${name}_dp" ); # macro tag$io->DepRules( $name, $pLibs, # library depends rules\&ToolsetLibRecipe, "\$(BINDIR)/${full}" );$io->Newline();#.. Compile up the resource file#ToolsetRCrecipe( $res, @reslist )if ( $res );#.. Package up the PDB file with the program#PackageProgAddFiles ( $name, "\$(BINDIR)/${name}.pdb", "Class=debug" ) unless ( $no_pdb );## Track the name of the possible target file# Used when creating Visual Studio projects#$target_file_exe = "\$(BINDIR)/${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( @_ );}########################################################################## Push standard "system" libraries. This is a helper function# used within this toolset.## Arguments:# $plib Reference to library array.#########################################################################sub ToolsetLibStd{my ($plib) = @_;## Only add libraries if required#return unless( $::ScmCompilerOpts{'ADDLINKLIBS'} );}########################################################################## 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) = @_;return # ignore (compat)if ( $lib eq "rt" || $lib eq "thread" ||$lib eq "pthread" || $lib eq "nsl" ||$lib eq "socket" );if ( !defined($dp) ) { # linker$io->Cmd( "\$(subst /,\\\\,\$(strip $lib)).$::a" );} else { # depend$io->Cmd( "$dp:\t@(vlib2,$lib,VC_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( ',', $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 file## Arguments : $name - Base name of the project# $project - Path to the project file# $pArgs - Project specific options#########################################################################my $project_defines_done = 0;sub ToolsetPROJECT{my( $name, $project, $pArgs ) = @_;## Process options#foreach ( @$pArgs ) {Message( "vcwce PROJECT: unknown option $_ -- ignored\n" );}my ($io) = ToolsetPrinter::New();## Setup toolset pecific difinitions. Once#unless( $project_defines_done ){$project_defines_done = 1;$io->PrtLn( "ifeq \"\$(DEBUG)\" \"1\"");$io->PrtLn( "PROJECT_CMD\t:= DEBUG");$io->PrtLn( "else");$io->PrtLn( "PROJECT_CMD\t:= RELEASE");$io->PrtLn( "endif");$io->Newline();}## Generate the recipe to create the project#$io->Label( "Build project", $name );$io->PrtLn( "Project_$name: $project" );$io->PrtLn( "\t\$(XX_PRE)( \$(show_environment); \\" );$io->PrtLn( "\tevc $project /make \"ALL - \$(PROJECT_CMD)\" /use_env /CEConfig=\"\$(WCE_PLATFORM)\" /out $name\$(GBE_TYPE).log; \\" );$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: $project" );$io->PrtLn( "\t-\$(XX_PRE)evc $project /make \"ALL - \$(PROJECT_CMD)\" /clean /use_env /CEConfig=\"\$(WCE_PLATFORM)\"" );$io->PrtLn( "\t-\$(XX_PRE)\$(rm) $name\$(GBE_TYPE).log" );$io->Newline();}#.. Successful termination1;