Rev 7018 | Blame | Compare with Previous | Last modification | View Log | RSS feed
## Module name : vcwin32# Module type : Makefile system# Compiler(s) : ANSI C# Environment(s): WIN32## Description:# Visual C/C++ for WIN32##............................................................................#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;my $toolset_name = 'vcwin32'; # Toolset name : Error reporting############################################################################### Version information#my $toolset_info;my $toolset_version = 'MSVC6';my %ToolsetVersion =('MSVC6' => { 'def' => 'vcwin32.def' ,'buildcmd' => 'msdev =DSW= /make "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'msdev =DSW= /make "=TYPE=" /clean /useenv' ,'tmp' => 'vc60','VSCOMPILER' => '1','def_targets' => [ 'ALL - RELEASE','ALL - DEBUG' ],},'MS.NET2003' => { 'def' => 'vcwin32_net2003.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=" /useenv' ,'tmp' => 'vc70','VSCOMPILER' => '2',},'MS.NET2005' => { 'def' => 'vcwin32_net2005.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=" /useenv' ,'tmp' => 'vc80','VSCOMPILER' => '3','GenManifest' => '1',},'MS.NET2008' => { 'def' => 'vcwin32_net2008.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=" /useenv' ,'tmp' => 'vc90','VSCOMPILER' => '3','GenManifest' => '1',},'MS.NET2010' => { 'def' => 'vcwin32_net2010.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=" /useenv' ,'tmp' => 'vc100','VSCOMPILER' => '3','GenManifest' => '1',},'MS.NET2012' => { 'def' => 'vcwin32_net2012.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=" /useenv' ,'tmp' => 'vc110','VSCOMPILER' => '3','GenManifest' => '1',},'MS.NET2015' => { 'def' => 'vs2015.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=|x86" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=|x86" /useenv' ,'tmp' => 'vc110','VSCOMPILER' => '3','GenManifest' => '1',},'VS2012_X64' => { 'def' => 'vs2012_x64.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=" /useenv' ,'tmp' => 'vc110','VSCOMPILER' => '3','GenManifest' => '1','Machine' => 'X64','Rules' => 'vcwin64.rul','NoKludges' => 1,},'VS2015_X64' => { 'def' => 'vs2015_x64.def' ,'buildcmd' => 'devenv =DSW= /build "=TYPE=|x64" /useenv /out =LOG=' ,'cleancmd' => 'devenv =DSW= /clean "=TYPE=|x64" /useenv' ,'tmp' => 'vc110','VSCOMPILER' => '3','GenManifest' => '1','Machine' => 'X64','Rules' => 'vcwin64.rul','NoKludges' => 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;} elsif (/^--NoDinkumware/) { # Dinkumware package test} else {Message( "$toolset_name toolset: unknown platform argument $_ -- ignored\n" );}}#.. Validate SDK version# Currently six versions are supported# 1) MSVC6 - As provided via Visual Studio# 2) MSVS.net 2003 - Used to create .NET applications# 3) MSVS.net 2005 - Used to create .NET applications# 4) MSVS.net 2008 - Used to create .NET applications# 5) MSVS.net 2010 - Used to create .NET applications# 6) MSVS.net 2012 - Used to create .NET applications#$toolset_info = $ToolsetVersion{$toolset_version};Error( "Unknown version: $toolset_version" ) unless ( defined $toolset_info );## Insert defaults#$toolset_info->{'Machine'} = 'X86' unless defined $toolset_info->{'Machine'};$toolset_info->{'Rules'} = 'vcwin32.rul' unless defined $toolset_info->{'Rules'};#.. 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$::ScmToolsetProperties{'LdFlagSpace'} = 1; # LdFlags support embedded spaces##.. define Visual C/C+ environmentInit( "visualc" );ToolsetDefines( $toolset_info->{'def'} );PlatformDefine ("VSCOMPILER\t= $toolset_info->{'VSCOMPILER'}" );ToolsetRequire( "exctags" ); # and Exuberant CtagsToolsetRules( $toolset_info->{'Rules'} );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" );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 =(## Control the thread model to use# This will affect the compiler options and the linker options#'multithread_static' => { 'THREADMODE' , 'T' }, # -MT'multithread_dll' => { 'THREADMODE' , 'D' }, # -MD Default'multithread_none' => { 'THREADMODE' , 'L' }, # -ML'subsystem:windows' => { 'LDSUBSYSTEM' , 'windows' },'subsystem:console' => { 'LDSUBSYSTEM' , 'console' },'rtti' => { 'USE_RTTI', 1 },'nopdb' => { 'PDB_NONE', 1 },'pdb' => { 'PDB_NONE', undef },'noaddlibs' => { 'ADDLINKLIBS' , undef }, # Don't add link libs'addlibs' => { 'ADDLINKLIBS' , '1' }, # default'noprecompilehdrs' => { 'PRECOMPILEHDRS' , undef }, # Don't precompile headers'precompilehdrs' => { 'PRECOMPILEHDRS' , '1' }, # default## Mimic some of the behavior of version-1 JATS#'jats_v1' => { 'USE_JATS_V1' => '1' },);## Set default options#$::ScmCompilerOpts{'THREADMODE'} = 'D';$::ScmCompilerOpts{'ADDLINKLIBS'} = '1';$::ScmCompilerOpts{'PRECOMPILEHDRS'} = '1';## Some defaults#if ($toolset_info->{'VSCOMPILER'} >= 3) {push @::LDFLAGS, 'ignore:4099'; # Ignore PDB file missing}}############################################################################### 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{MakeHeader('Toolset Postprocessed Information');## Attempt to fix bugs in Microsofts mspdbsrv in a multi-build environment# Export EnvVar _MSPDBSRV_ENDPOINT_ with a unique text string# Thus instances of mspdbsrv started by the build will be able to find there# own instance.## _MSPDBSRV_ENDPOINT_ needs to be unique within the machine# Its not intended to be globally unique - just not to generate two# of them.#MakePrint("## Define endpoint to instantiate seperate instances of mspdbsrv#_MSPDBSRV_ENDPOINT_ = $::ScmBuildUuidexport _MSPDBSRV_ENDPOINT_");## 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("## 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;}}}################################################################################ 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, $pdb );foreach $_ ( @$pArgs ) {if (/--Shared$/) { # Building a 'shared' object$cflags = "$cflags \$(SHCFLAGS)";$pdb = $::SHOBJ_LIB{$obj}if (exists $::SHOBJ_LIB{$obj} );} 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 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{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;## 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, $_ver )# 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# --Node # Node library for Electron# Fixed extension. No versioned dll, no .lib file## 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, $_ver ) = @_;our( $def, $mutual_dll, $res, @reslist, $doimplib, $stub_only );our( $no_implib, $no_pdb, $resource_only );our( $entry, $noaddlibs );our( $isNodeFile );#.. Parse arguments#$def = ""; # options$doimplib = 0;$res = "";$no_pdb = $pdb_none;$isNodeFile = 0;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( "$toolset_name 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;} elsif (/^--Node$/i) {$isNodeFile = 1;} else { # unknownMessage( "$toolset_name SHLD: unknown option $_ -- ignored\n" );}}## Sanity test#Error ("$toolset_name SHLD:Stubonly option requires --Def=file ")if ( $stub_only && ! $def );Error ("$toolset_name 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 $ext = $isNodeFile ? '.node' : ".$::so";my $full = $lib.$ext;my $link_with_def;#.. Cleanup rules## ld Linker command file# map Map file# pdb Microsoft C/C++ program database# ilk Microsoft Linker Database#ToolsetGenerate( "\$(LIBDIR)/${lib}.ld" );ToolsetGenerate( "\$(LIBDIR)/${lib}.map" );ToolsetGenerate( "\$(LIBDIR)/${lib}.exp" );ToolsetGenerate( "\$(LIBDIR)/${lib}.ilk" );ToolsetGenerate( "\$(LIBDIR)/${full}" );ToolsetGenerate( "\$(LIBDIR)/${full}.manifest" ) if $toolset_info->{'GenManifest'};#.. 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', "NoTarget=1" ) unless $no_pdb ;PackageShlibAddFiles( $base, "\$(LIBDIR)/${full}.manifest", 'Exists=1', "NoTarget=1" ) if ( $toolset_info->{'GenManifest'} );PackageShlibAddFiles( $base, "\$(LIBDIR)/${full}" );## Generate Shared Library dependency information#my $dep = $io->SetShldTarget( $lib );## 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}: $dep \\\n\t\t\$(OBJDIR)/${base}","", " \\\n\t\t", ".$::o", @$pObjs );$io->Prt( " \\\n\t\t$def" ) if ( $link_with_def );$io->Prt( "\n\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( "-machine:" . $toolset_info->{'Machine'} );$io->Cmd( "-base:0x10000000" );$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( "-nodefaultlib:LIBC" );$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,# 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, "\$(LIBDIR)/${full}" );$io->SHLDDEPEND( $name, $lib );} # End BuildSHLDToolsetLibStd( $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).$_ver.$::so";BuildSHLD("$name", # Base Name"$name\$(GBE_TYPE)", # Name of Export Lib"$name\$(GBE_TYPE).$_ver"); # Name of the DLL + PDB} elsif ($isNodeFile) {## A 'node' file is a specific shared library for Electron applications# They have a fixed file extension of .node on all platforms# Do not generate a Versioned DLL# Do not generate an export library# --Node flavor will create# a) Unversioned DLL $name$(GBE_TYPE).node#$target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).node";BuildSHLD( "$name", "" , "$name\$(GBE_TYPE)" )} 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).$_ver.$::so:\t"."\$(LIBDIR)/${name}\$(GBE_TYPE).$::so\n"."\n" );$target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::so";BuildSHLD( "$name", "" , "$name\$(GBE_TYPE).$_ver" );BuildSHLD( "$name", "$name\$(GBE_TYPE)" , "$name\$(GBE_TYPE)" );}#.. 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( @_ );}################################################################################ 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 $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( "$toolset_name LD: unknown option $_ -- ignored\n" );}}#.. Names of important files#my $base = "\$(BINDIR)/${name}";my $full = $base . $::exe;my $map = $base . '.map';my $pdb = $base . '.pdb';my $manifest = $full . '.manifest';#.. Cleanup rules## ld Linker command file# map Map file# pdb Microsoft C/C++ program database# ilk Microsoft Linker Database# res Compiled resource script# exe.manifest Manifest file (VS2005 and above)#ToolsetGenerate( $map );ToolsetGenerate( $pdb );ToolsetGenerate( $base . '.ld' );ToolsetGenerate( $base . '.ilk' );ToolsetGenerate( $manifest ) if $toolset_info->{'GenManifest'};## Under some conditions the creation of a program will also create# an exp and lib files. May be related to an attempt to create a prog# and a dll from the same code#ToolsetGenerate( $base . '.exp' );ToolsetGenerate( $base . '.lib' );#.. Toolset Printer#my ($io) = ToolsetPrinter::New();my $dep = $io->SetLdTarget( $name );#.. Linker command#$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( "-out:\$(subst /,\\\\,$full)" );$io->Cmd( "-pdb:\$(subst /,\\\\,$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 /,\\\\,$map)" );$io->Cmd( "-nodefaultlib:LIBC" );$io->Cmd( "-machine:" . $toolset_info->{'Machine'} );$io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );ToolsetLibStd( $pLibs ) unless ( $noaddlibs ); # push standard libraries$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 PDB file with the program#PackageProgAddFiles ( $name, $full );PackageProgAddFiles ( $name, $manifest, 'Exists=1' ) if ( $toolset_info->{'GenManifest'} );PackageProgAddFiles ( $name, $pdb, "Class=debug" ) unless ( $no_pdb );## 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( @_ );}########################################################################## 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'} );## Appears to be a kludge that no one is happy to remove# If we are inluding cs or csx libraries then add some more#unless ($toolset_info->{'NoKludges'}) {foreach (@$plib) {if ( $_ eq 'csx$(GBE_TYPE)' || $_ eq 'cs$(GBE_TYPE)' ){ # .. core servicesUniquePush( $plib, "KERNEL32" );UniquePush( $plib, "WINUX32\$(GBE_TYPE)" );UniquePush( $plib, "WS2_32" );last;}}}## Multithreaded DLL#push @$plib, "--ifeq=THREADMODE:D";push @$plib, "--ifdebug";push @$plib, "MSVCRTD";push @$plib, "--ifeq=THREADMODE:D";push @$plib, "--ifprod";push @$plib, "MSVCRT";## Static Multithread library#push @$plib, "--ifeq=THREADMODE:T";push @$plib, "--ifdebug";push @$plib, "LIBCMTD";push @$plib, "--ifeq=THREADMODE:T";push @$plib, "--ifprod";push @$plib, "LIBCMT";## User library#push @$plib, "USER32";}########################################################################## 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,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 = ${$toolset_info->{'def_targets'}}[0] || 'RELEASE';my $debug = ${$toolset_info->{'def_targets'}}[1] || '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 specific 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;