Rev 295 | Blame | Compare with Previous | Last modification | View Log | RSS feed
## Module name : DELPHI7# Module type : Makefile system# Compiler(s) : Delphi Pascal# Environment(s): WIN32## Description:# Delphi7 for WIN32#............................................................................#use strict;use warnings;use FileUtils;################################################################################# Globals#my $toolset_version;my $implib_found;############################################################################### ToolsetInit()# Runtime initialisation###############################################################################ToolsetInit();sub ToolsetInit{#.. Parse arguments (Toolset arguments)#Debug( "Delphi7(@::ScmToolsetArgs)" );foreach $_ ( @::ScmToolsetArgs ) {if (/^--Version=(.*)/) { # MS SDK Version$toolset_version = $1;} else {Message( "Delphi7 toolset: unknown option $_ -- ignored\n" );}}#.. Parse arguments (platform arguments)#Debug( "Delphi7(@::ScmPlatformArgs)" );foreach $_ ( @::ScmPlatformArgs ) {if (/^--product=(.*)/) { # GBE product} elsif (/^--Version=(.*)/) { # MS SDK Version$toolset_version = $1;} else {Message( "Delphi7 toolset: unknown platform argument $_ -- ignored\n" );}}#.. Validate SDK version# Currently only one is supported# 1) Delphi7 installed#Error( "Unknown version: $toolset_version" ) if ( defined $toolset_version );#.. Standard.rul requirements#$::s = 'asm';$::o = '';$::a = 'dcu';$::so = 'dll';$::exe = '.exe';#.. Toolset configuration#$::ScmToolsetVersion = "1.0.0"; # our version$::ScmToolsetGenerate = 0; # generate optional$::ScmToolsetProgDependancies = 0; # handle Prog dependancies myself$::ScmToolsetSingleType = 1; # Cannot support debug and production builds$::ScmToolsetNillLibSrc = 1; # Libraries don't need source specified#.. define Delphi7 environmentInit( "delphi7" );ToolsetDefines( "delphi7.def" );ToolsetRequire( "exctags" ); # and Exuberant CtagsToolsetRules( "delphi7.rul" );ToolsetRules( "standard.rul" );#.. 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#'subsystem:windows' => { 'LDSUBSYSTEM' , '-CG' },'subsystem:console' => { 'LDSUBSYSTEM' , '-CC' },);## Set default options#$::ScmCompilerOpts{'LDSUBSYSTEM'} = '-CG';#.. Cleanup rules# None at the moment as we only build projects#return 1;}#-------------------------------------------------------------------------------# Function : ToolsetGenLibName## Description : Function to generate the names of static libraries# Will be used if it exists## Inputs : $name - Base Name of the library## Returns : Path to generated name#sub ToolsetGenLibName{my ($name) = @_;return "$name.$::a";}#-------------------------------------------------------------------------------# Function : ToolsetPreprocess## Description : Called once all the user directives have been parsed# In this toolset it is used as a hook to allow# the creation of a 'simple' target to perform some# level of dependency testing## Basically. Create a target that consists on ALL the# source files. This is then used as a prerequisite# for all Libs, SharedLibs and Progs## It is crude and ugly - but it does the job# Would be better to parse the Delphi project files# and determine the prerequisites ourselves, but ...## Inputs : None## Returns : Nothing directly#sub ToolsetPreprocess{my @dlist;foreach ( values %::SRCS ){## Strip out known project files# Must leave in .pas files#next if ( m~\.dpr$~i );next if ( m~\.dpk$~i );next if ( m~^descpkg$~ );push @dlist, $_;}if ( @dlist ){## Would like to use nice function that create nice text, but# at the moment the makefile is not yet being written## Trick: Create an in-memory filehandle and use it# The MAKEFILE handle is used by nice writers#my $data;local (*MAKEFILE);open(MAKEFILE, '>>', \$data) || Error ("Cannot open in-memory file");MakeHeader ( "All Delphi Sources");MakeDefEntry( "DELPHISRCS", "=", \@dlist );close MAKEFILE;## Add the generated data as a 'define'# This will be placed early in the makefile so that it can be used# by the rules that need it.#ToolsetDefine ($data);}}#-------------------------------------------------------------------------------# Function : ToolsetPostprocess## Description : Process any .RC files that have been specified# by the user## Inputs :## Returns :#sub ToolsetPostprocess{foreach my $rcfile ( @::RCSRCS ){my $name = StripDirExt($rcfile);my $base = StripDir($rcfile);my $res_name = '$(OBJDIR)/' . $name . '.res';## Create rules and recipes to build file#my $me = MakeEntry::New (*MAKEFILE, $res_name );$me->AddComment ("Create Resource File: $name" );$me->AddDependancy ( $rcfile );$me->AddDependancy ( '$(SCM_MAKEFILE)' );$me->AddDependancy ( '$(GBE_OBJDIR)' );$me->AddDependancy ( split( /$;/, $::SRC_DEPEND{$base} ) ) if exists($::SRC_DEPEND{$base});$me->AddRecipe ( '$(DRES)' );$me->Print();## Add the file to the list of generated files# This will ensure that its created early#GenerateSrcFile( 1, $res_name );}}#-------------------------------------------------------------------------------# Function : ToolsetAR## Description : Toolset processing to create a static library# In Delphi these are called a unit# In Delphi there are several restrictions# * Name of the library and the name of the source are# fixed - the user cannot provide a source name## * A library can contain only one element### Inputs : $name - Base name of the library# $pArgs - Ref to an array of arguments# $pObjs - Ref to an array of objects# $pLib - Ref to complete library entry## Returns :#sub ToolsetAR{my( $name, $pArgs, $pObjs, $pLib ) = @_;#.. Parse arguments#foreach $_ ( @$pArgs ){Message( "AR: unknown option $_ -- ignored" );}## Ensure that the user has not provided a source# The name of the source will be calculated from the target#Error( "Delphi7 toolset: User source file names not supported")if ( scalar @$pObjs );## Source the required source file# It must exist#my $sfile = MakeSrcResolve ( "$name.pas" );Error ("AR: Required source file not found: $sfile")unless ( -f $sfile );my $lib_name = $pLib->getPath();## Rule to create the target#my $me = MakeEntry::New (*MAKEFILE, $lib_name );$me->AddComment ("Build Unit: $name as a DCU" );$me->AddDependancy ( $sfile );$me->AddDependancy ( '$(SCM_MAKEFILE)' );$me->AddDependancy ( '$(DELPHISRCS)' );$me->AddRecipe ( '$(DCC_AR)' );$me->AddDefn ('PSOURCE', $sfile );$me->Print();}################################################################################ ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )# This subroutine takes the user options and builds the rules# required to link the shared library 'name'.## Arguments:# $name - Name of the target program# $pArgs - Ref to an array of argumennts# $pObjs - Ref to an array of object files# $pLibs - Ref to an array of libraries# $ver - Version String## Output:# Makefile recipes to create the Program## Notes:# This Program Builder will handle its own dependancies# It will also create rules and recipes to construct various# parts directly from source## In Delphi there are several restrictions# * Name of the program and the name of the source are# linked. The user can provide only one file## Options:# --NoImplib # Supress creation of Import Library# --Package # Force Package Mode# Source File # Dependency usage only#################################################################################sub ToolsetSHLD{my ( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;my @psource;my $no_implib = 0;my $auto_type = '';#.. Parse arguments#foreach ( @$pArgs ) {if (/^--NoImplib$/) {$no_implib = 1;} elsif ( /^--DCU/i ) {$auto_type = 'dcu';} elsif ( /^--Package/i ) {$auto_type = 'pkg';} elsif ( /^--NoPackage/i || /^--DLL/i ) {$auto_type = 'dll';} elsif ( !/^-/ ) {push @psource, MakeSrcResolve($_);} else {Message( "Delphi7 LD: unknown option $_ -- ignored\n" );}}## Objs are not supported in this toolset#Error( "Delphi7 toolset: User source file names not supported")if ( scalar @$pObjs );## Determine the source project name# Will have the same name as the EXE, but the suffix may be# .dpr or .pas#my $source;$::ScmQuiet = 3; # Can be done better !foreach my $suffix ( '.dpk', '.dpr', '.pas' ){$source = MakeSrcResolve ( "$name$suffix" );last if ( -f $source );$source = undef;}$::ScmQuiet = 0;Error ("Shared Library source not found","It must have the same name as the library: $name")unless ( $source );## Determine the type of SharedLib being created# Library that creates DLLs# Library that creates a Delphi Package## User can force the mode#unless ( $auto_type ){$auto_type = 'pkg' if ($source =~ m~\.dpk~);$auto_type = 'dcu' if ($source =~ m~\.pas~);}if ( $auto_type eq 'pkg' ){## Determine the target output name#my $base = $name;my $root = "\$(LIBDIR)/$base";my $bpl = $root . '.bpl';my $bcp = $root . '.dcp';## Create Rules and Recipes to create the Package#my $me = MakeEntry::New (*MAKEFILE, $bpl );$me->AddComment ("Build Delpi Package: $name" );$me->AddName ( $bcp );$me->AddDependancy ( $source );$me->AddDependancy ( '$(SCM_MAKEFILE)' );$me->AddDependancy ( '$(DELPHISRCS)' );$me->AddDependancy ( @psource );$me->AddRecipe ( '$(SHDCC)' );$me->AddDefn ('SHLIBBASE', $base );$me->AddDefn ('PSOURCE', $source );$me->AddDefn ('PFLAGS', '' );$me->AddDefn ('PACKAGES', join ' ', @$pLibs );$me->Print();## Files to clean up#ToolsetGenerate( "$root.map" );ToolsetGenerate( "$base.drc" ); # Created in CWD## Specify the files to be packaged as part of the shared library#PackageShlibAddFiles ( $name, $bpl );PackageShlibAddFiles ( $name, $bcp );PackageShlibAddFiles ( $name, "$root.map", "Class=map" );}elsif ( $auto_type eq 'dcu' ){## Really building a DCU# Done as a shared lib so that it can access other packages# with the -L option#my $base = $name;my $root = "\$(LIBDIR)/$base";my $dcu = $root . '.dcu';## Create Rules and Recipes to create the Package#my $me = MakeEntry::New (*MAKEFILE, $dcu );$me->AddComment ("Build Delpi Package: $name" );$me->AddDependancy ( $source );$me->AddDependancy ( '$(SCM_MAKEFILE)' );$me->AddDependancy ( '$(DELPHISRCS)' );$me->AddDependancy ( @psource );$me->AddRecipe ( '$(DCC_AR)' );$me->AddDefn ('PSOURCE', $source );$me->AddDefn ('PFLAGS', '' );$me->AddDefn ('PACKAGES', join ' ', @$pLibs );$me->Print();## Files to clean up#ToolsetGenerate( "$base.drc" ); # Created in CWD## Specify the files to be packaged as part of the shared library#PackageShlibAddFiles ( $name, $dcu );}else{## Determine the target output name#my $base = $name;my $root = "\$(LIBDIR)/$base";my $full = $root . '.' . $::so;my $stub = $root . '.lib';## Create Rules and Recipes to create the Shared Library#my $me = MakeEntry::New (*MAKEFILE, $full );$me->AddComment ("Build Shared Library: $name" );$me->AddDependancy ( $source );$me->AddDependancy ( '$(SCM_MAKEFILE)' );$me->AddDependancy ( '$(DELPHISRCS)' );$me->AddDependancy ( @psource );$me->AddRecipe ( '$(SHDCC)' );$me->AddDefn ('SHLIBBASE', $base );$me->AddDefn ('PSOURCE', $source );$me->AddDefn ('PFLAGS', '' );$me->AddDefn ('PACKAGES', join ' ', @$pLibs );$me->Print();## Files to clean up#ToolsetGenerate( "$root.map" );ToolsetGenerate( "$base.drc" ); # Created in CWD## Specify the files to be packaged as part of the shared library#PackageShlibAddFiles ( $name, $full );PackageShlibAddFiles ( $name, "$root.map", "Class=map" );## Shared libaries are really need an import library# Create an import library#unless ( $no_implib ){## Need:# impdef.exe from Borland Cbuilder builder# link.exe from MS VC6#my $me = MakeEntry::New (*MAKEFILE, $stub );$me->AddComment ("Build Import Library: $name" );$me->AddDependancy ( $full );$me->AddRecipe ( '$(IMPLIB)' );$me->AddDefn ('TMPFILE', "$root.tmp" );$me->Print();ToolsetGenerate( "$root.tmp" );ToolsetGenerate( "$root.exp" );PackageShlibAddFiles ( $name, $stub );}}}################################################################################ ToolsetLD( $name, \@args, \@objs, \@libraries )# This subroutine takes the user options and builds the rules# required to link the program 'name'.## Arguments:# $name - Name of the target program# $pArgs - Ref to an array of argumennts# $pObjs - Ref to an array of object files# $pLibs - Ref to an array of libraries## Output:# Makefile recipes to create the Program## Notes:# This Program Builder will handle its own dependancies# It will also create rules and recipes to construct various# parts directly from source## In Delphi there are several restrictions# * Name of the program and the name of the source are# linked. The user can provide only one file## Options:# --Console # Console app# --Windows # Windows app (default)# Source File # Dependency usage only#################################################################################sub ToolsetLD{my ( $name, $pArgs, $pObjs, $pLibs ) = @_;my @psource;my $link_target = $::ScmCompilerOpts{'LDSUBSYSTEM'};#.. Parse arguments#foreach ( @$pArgs ) {if (/^--Windows/) {$link_target = '-CC';} elsif (/^--Console/) {$link_target = '-CG';} elsif ( !/^-/ ) {push @psource, MakeSrcResolve($_);} else {Message( "Delphi7 LD: unknown option $_ -- ignored\n" );}}## Objs are not supported in this toolset#Error( "Delphi7 toolset: User source file names not supported")if ( scalar @$pObjs );## Determine the target output name#my $base = $name;my $root = "\$(BINDIR)/$base";my $full = $root . $::exe;## Determine the source project name# Will have the same name as the EXE, but the suffix may be# .dpr or .pas#my $source;$::ScmQuiet = 3; # Can be done better !foreach my $suffix ( '.dpr', '.pas' ){$source = MakeSrcResolve ( "$name$suffix" );last if ( -f $source );$source = undef;}$::ScmQuiet = 0;Error ("Program source not found","It must have the same name as the program: $name")unless ( $source );## Create Rules and Recipes to create the Program# This will be a combination of source#my $me = MakeEntry::New (*MAKEFILE, $full );$me->AddComment ("Build Program: $name" );$me->AddDependancy ( $source );$me->AddDependancy ( '$(SCM_MAKEFILE)' );$me->AddDependancy ( '$(DELPHISRCS)' );$me->AddDependancy ( @psource );$me->AddRecipe ( '$(DCC)' );$me->AddDefn ('PSOURCE', $source );$me->AddDefn ('PFLAGS', $link_target );$me->AddDefn ('PACKAGES', join ' ', @$pLibs );$me->Print();## Files to clean up#ToolsetGenerate( "$root.map" );ToolsetGenerate( "$base.drc" ); # Created in CWD#.. Package up files that are a part of the program#PackageProgAddFiles ( $name, $full );PackageProgAddFiles ( $name, "$root.map", "Class=map" );}#.. Successful termination1;