Subversion Repositories DevTools

Rev

Blame | Last modification | View Log | RSS feed

########################################################################
# Copyright (C) 1998-2013 Vix Technology, All rights reserved
#
# Module name   : MakePax.pm
# Module type   : Jats Plugin
# Compiler(s)   : Perl
# Environment(s): jats
#
# Description   : This package extends the JATS toolset at build time
#                 It provides additional directives to the JATS makefiles
#                 to simplify the directives.
#
#                 The directive matches up with a run-time tool to
#                 do the bulk of the work.
#
# Operation     : This package adds the JATS directive MakePax
#                 When used the directive will use GenerateFiles to invoke
#                 a shell program at make-time to actually do the hard work.
#
# Directives    : MakePax (platform, ... )
#
#
#......................................................................#

use strict;
use warnings;
use JatsError;
use FileUtils;

#
#   Jats Globals
#
our $ScmPlatform;

#
#   Imported environment varibles
#   These MUST exist. Existence will be tested
#
our $MRI_INTELLECT;
our $MKS6_1A;
our $JAVA_HOME_1_6;
our $USER;

#-------------------------------------------------------------------------------
# Function        : WinPath
#
# Description     : Simple function to convert a relative JATS path into
#                   a windows freindly full path
#
# Inputs          : path            - Relative path
#                   noQuote         - True - No quoting
#
# Returns         : Absolute Windows Path
#                   Quoted so that it can be used in a 'set'
#
sub WinPath
{
    my ($path, $noQuote) = @_;
    $path = FullPath($path);
    $path =~ s~/~\\~g;
    if ( $path =~ m~\s~ && ! $noQuote) {
        $path = '"' . $path . '"';
    }
    return $path;
}


#-------------------------------------------------------------------------------
# Function        : MakePax
#
# Description     : Invoke the PAx builder to build the package
#
# Inputs          : platform          - Standard Platform Specifier
#                   Options
#                       --Application=path              - path to app base
#                       --Component=name                - Created component name
#                       --Platform=name                 - Target platform. Default=ALL
#                       --Pkg=VarName::Component        - Use external component
#                       --Verbose                       - Enable Make Verbosity
#
# Returns         : Nothing
#
sub MakePax
{
    my ($platforms, @uargs) = @_;
    my $appRoot;
    my $appPlatform;
    my $appComponent;
    my $appVerbose= '';
    my %pkgList;
    my %pkgData;

    return if ( ! ActivePlatform($platforms) );
    foreach ( @uargs )
    {
        #
        #   Specify the base of the application to build
        #       Only one allowed
        #       Must be a directory
        #       Must contain a 'makefile'
        #
        if ( m~--Application=(.+)~i ) {
            Error ("MakePax: Application Root specified multiple times")
                if ( defined $appRoot );
            $appRoot = $1;
            Error ("MakePax: Application root not a directory")
                unless ( -d $appRoot );
            Error ("MakePax: Application root does not contain a 'makefile'")
                unless ( -f join('/', $appRoot, 'makefile') );

        #
        #   Specify a platform to build
        #       Only one allowed
        #       Default - all
        #
        } elsif ( m~--Platform=(.+)~i ) {
            Error ("MakePax: Target platform specified multiple times")
                if ( defined $appPlatform );
            $appPlatform = $1;

        #
        #   Specify the component that is built
        #       Only one allowed
        #
        } elsif ( m~--Component=(.+)~i ) {
            Error ("MakePax: Target component specified multiple times")
                if ( defined $appComponent );
            $appComponent = $1;

        #
        #   Specify packages to be used - and definition to create
        #       Multiple allowed
        #
        #
        } elsif ( m~--Pkg=(.+)~i ) {
            my $parg = $1;
            Error ("MakePax: Bad Pkg specification: $parg")
                unless ( $parg =~ m~(\w+):(.*)~ );
            my $pvar = $1;
            my $pcomp = $2;
            Error ("MakePax: Multiple definition of Package Root variable: $pvar")
                if ( exists $pkgList{$pvar} );
            $pkgList{$pvar}{pcomp} = $pcomp;

        #
        #   Enable PAX Build Verbosity
        #
        } elsif ( m~--Verbose~i ) {
            $appVerbose = '1';

        } else {
            Error ("MakePax: Unknown option: $_");
        }
    }

    #
    #   Detect missing options and insert defaults
    #
    Error ("MakePax: No application base has been specified")
        unless ( defined $appRoot );
    Error ("MakePax: No target component name been specified")
        unless ( defined $appComponent );
    $appPlatform = '' unless ( defined $appPlatform );

    #
    #   Process dependent packages
    #
    foreach my $entry ( getPackageList() )
    {
        my $base = $entry->getBase(2);
        next unless ( defined $base );

        #
        #   Scan for package componets
        #       Locate Pax portion within the package
        #
        foreach ( keys %pkgList )
        {
            my $ventry = $pkgList{$_};
            next if ( exists $ventry->{path} );

            my $path = join ('/', $base, 'pkg', $ventry->{pcomp} );
            if ( -d $path )
            {
                $ventry->{path} = $path;
                $ventry->{pname} = $entry->{NAME};
                my $tpath = join ('/', $path, 'tools'  );
                $ventry->{tool} = $tpath
                    if ( -d $tpath );
            }
        }
    }

    #
    #   Report missing components
    #
    my @elist;
    foreach ( keys %pkgList )
    {
        my $ventry = $pkgList{$_};
        next if ( exists $ventry->{path} );

        push @elist, $ventry->{pcomp};
    }
    Error("MakePax: Pax components not found within dependent packages", @elist)
        if ( @elist );

    #
    #   Need a temp work area
    #       Place it in the interface directory
    #       Must be absolute path in windows format - done later
    #
    my $tmpDir = join('/', $::ScmRoot, $::ScmInterface);

    #
    #   Ensure mandatory envVars are available
    #
    EnvImport('MRI_INTELLECT');
    EnvImport('MKS6_1A');
    EnvImport('JAVA_HOME_1_6');
    EnvImport('USER');

    #
    #   Create a Windows Batch file
    #   The file will
    #       Define the PAX EnvVars required to drive the PAx Builder
    #       Allow command to be processed with the batch file
    #
    my $fname = "intellect.bat";
    my $fh = ::ConfigurationFile::New( $fname, '--NoEof', '--Type=bat' );
    $fh->WriteLn ( "\@echo off");
    $fh->Header( "MakePax","Set Intellect specific environment variables" );

    #
    #   Guard the batch file
    #   Prevent the path being extended forever
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Only do once\n" );
    $fh->WriteLn ( "if defined PAXVARS goto PaxSet");
    $fh->WriteLn ( "set PAXVARS=1" );

    #
    #   Export Package Name and Version
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Package Version Information\n" );
    $fh->WriteLn ( "set GBE_BUILDPKG=$::ScmBuildPackage" );
    $fh->WriteLn ( "set GBE_BUILDVER=$::ScmBuildVersionFull" );
    $fh->WriteLn ( "set GBE_BUILDVERNUM=$::ScmBuildVersion" );
    $fh->WriteLn ( "set GBE_BUILDPRJ=$::ScmBuildProject" );

    #
    #   Define the components discovered
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Pax Components\n" );
    foreach my $vname ( keys %pkgList )
    {
        my $ventry = $pkgList{$vname};
        $fh->WriteLn ( "set $vname=" . $ventry->{path} );
    }

    #
    #   Define MRI Compiler location
    #   Note: It doesn't like to be installed in a location with a long pathname
    #         Normally install on c:\...
    #         Location is exported as a part of the JATS environment
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "MRI Compiler section\n" );
    $fh->WriteLn ( "set MRIROOT=" . WinPath($MRI_INTELLECT));
    
    #
    #   MKS Toolkit
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "MKS section\n" );
    $fh->WriteLn ( "set ROOTDIR=" . WinPath($MKS6_1A) );
    $fh->WriteLn ( "set MKSBIN_PATH=%ROOTDIR%\\mksnt" );
    $fh->WriteLn ( "set SHELL=%ROOTDIR%/mksnt/sh.exe" );
    $fh->WriteLn ( "set HOME=%ROOTDIR%" );
    $fh->WriteLn ( "set LOGNAME=" . $USER );

    #
    #   Java Section
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Java Section\n" );
    $fh->WriteLn ( "set JAVAROOT=" . WinPath($JAVA_HOME_1_6)  );
    
    #
    #   Misc
    #   Don't know what __COMPAT_LAYER does. Was in sample file
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Misc section\n" );
    $fh->WriteLn ( "set TMPDIR=" . WinPath($tmpDir) );
    $fh->WriteLn ( "set __COMPAT_LAYER=" );

    #
    #   Extend the PATH
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Extend Path\n" );
    $fh->WriteLn ( 'if not "%1"=="" setlocal' );
    $fh->WriteLn ( "path=%MKSBIN_PATH%;%path%" );

    foreach my $vname ( keys %pkgList )
    {
        my $ventry = $pkgList{$vname};
        next unless ( $ventry->{tool} );
        $fh->WriteLn ( 'path=%path%;' . WinPath($ventry->{tool},1) );
    }

    #
    #   Remove some JATS Make EnvVars that will upset the MKSToolkit
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Remove JATS Make EnvVars\n" );
    $fh->WriteLn ( ":PaxSet" );
    $fh->WriteLn ( "set MAKE=");
    $fh->WriteLn ( "set MAKEFLAGS=");
    $fh->WriteLn ( "set MAKELEVEL=");
    $fh->WriteLn ( "set MAKEOVERRIDES=");


    # Allow a command to be executed
    #
    $fh->WriteLn ( "" );
    $fh->Comment ( "Execute command within context of this batch file\n" );
    $fh->WriteLn ( 'if not "%1"=="" echo Cmd:intellect.bat %*' );
    $fh->WriteLn ( "%*" );
    $fh->WriteLn ( "" );
    $fh->Comment ( "Force process exist code, not just batch exit code\n" );
    $fh->WriteLn ( "%COMSPEC% /C exit %ERRORLEVEL% >nul");
    $fh->Close();

    #
    #   Generate a jats GenerateFiles directive to do the hard work
    #   Pass the bulk of the work off to a perl script run at make-time
    #   Done in a script so that we can wrap in several operations
    #   and a bit of sanity testing
    #
    GenerateFiles ('*', "--Tool=MakePax.pl",                      # Associated tool
                        "--NoGenerate",                           # Build During Generate Phase
                        "--UnknownPreq",                          # Always build
                        "--Clean",                                # Script supports jats clean
                        "--Text=PaxMake",                         # Display when building
                        
                        '--Var(BuildName)',                       # Target Package
                        '--Var(BuildVersion)',                    # Target Version

                        '--Var(InterfaceDir)',                    # Interface Directory
                        '--Var(PackageDir)',                      # My Package

                        "--Platform=$appPlatform",                # Target platform
                        "--Verbose=$appVerbose",                  # Build Verbosely
                        "--Component=$appComponent",              # My Packages component
                        "--Src=$appRoot"                          # Application Root
                        );

}

1;