Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7307 dpurdie 1
########################################################################
2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
3
#
4
# Module name   : jats_runtime_gcc.pm
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Description   : JATS Make Time Support for the GCC toolchain
8
#
9
#                 This package contains functions that are invoked by the JATS
10
#                 generated makefiles to perform complicated operations at Make Time
11
#
12
#                 The functions are designed to be invoked as:
13
#                   $(GBE_PERL) -Mjats_runtime_gcc -e <function> -- <args>+
14
#
15
#                 The functions in this packages are designed to take parameters
16
#                 from @ARVG as this makes the interface easier to read.
17
#
18
#                 This package is used to speedup and simplify the JATS builds
19
#                 Some things are easier to do in Perl than shell hidden inside
20
#                 a makefile
21
#
22
#......................................................................#
23
 
24
require 5.006_001;
25
use strict;
26
use warnings;
27
 
28
package jats_runtime_gcc;
29
 
30
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
31
use Exporter;
32
use JatsError qw(:name=GCC);
33
 
34
$VERSION = 1.00;
35
@ISA = qw(Exporter);
36
 
37
# Symbols to autoexport (:DEFAULT tag)
38
@EXPORT = qw( splitscript
39
              printenv
40
            );
41
 
42
#
43
#   Parsed options are stored globally
44
#
45
our %opts;
46
 
47
#BEGIN
48
#{
49
#    print "-------jats_runtime_gcc initiated\n";
50
#}
51
 
52
#-------------------------------------------------------------------------------
53
# Function        : process_options
54
#
55
# Description     : Extract options from the front of the command stream
56
#
57
#                   Options of the form --Opt=Val are split out
58
#                   Options of the form --Opt will set (or increment a value)
59
#
60
# Inputs          : None: Uses global ARGV
61
#
62
# Returns         : None: Resets global argv
63
#                         Populates the %opts hash
64
#
65
sub process_options
66
{
67
    while ( my $entry = shift @ARGV ) {
68
        if ( $entry =~  m/^--(.*)/  ) {
69
            if ( $1 =~ m/(.*)=(.*)/ ) {
70
                $opts{$1} = $2;
71
            } else {
72
                $opts{$1}++;
73
            }
74
        } else {
75
            unshift @ARGV, $entry;
76
            last;
77
        }
78
    }
79
    #
80
    #   Process some known options
81
    #   These are the same as those provided by 'jats_runtime'
82
    #
83
    $opts{'Progress'} = $opts{'Verbose'}    if ( $opts{'Verbose'} );
84
    ErrorConfig( 'name', $opts{Name})       if ( $opts{'Name'} );
85
    ErrorConfig( 'verbose', $opts{Verbose}) if ( $opts{'Verbose'} );
86
    DebugDumpData("RunTime Opts", \%opts )  if ( $opts{'ShowOpts'} );;
87
    Message ("RunTime args: @ARGV")         if ( $opts{'ShowArgs'} );
88
    printenv()                              if ( $opts{'ShowEnv'} );
89
    Message ($opts{'Message'})              if ( $opts{'Message'} );
90
}
91
 
92
#-------------------------------------------------------------------------------
93
# Function        : printenv
94
#
95
# Description     : Display all EnvVars
96
#
97
# Inputs          : None
98
#
99
# Returns         :
100
#
101
sub printenv
102
{
103
    foreach my $entry ( sort keys %ENV ) {
104
        print "    $entry=$ENV{$entry}\n";
105
    }
106
}
107
 
108
#-------------------------------------------------------------------------------
109
# Function        : splitscript
110
#
111
# Description     : Workaround broken linker (ld) that cannot handle a linkerscript
112
#                   correctly.
113
#                   
114
#                   The linker cannot handle a linkerscript with a 'VERSION" section
115
#                   The linker can handle a linker script with an EXTERN section
116
#                   and a --version-script
117
#                   
118
#                   This workaround will take the linker script and break it into two
119
#                   parts. This must be done at make-time in case the linker script is
120
#                   generated.
121
#
122
# Inputs          : @ARGV
123
#                       -src=Input              - Original LinkerScript
124
#                       -vs=VersionScript       - Name of version script to generate
125
#                       -ls=LinkerScript        - Name of the (simple) Linker Script to generate
126
#
127
# Returns         : 
128
#
129
sub splitscript
130
{
131
    process_options();
132
    Message ("Split Linker Script");
133
    Error ("No Source Script") unless ( defined $opts{'src'} );
134
    Error ("No Version Script Name") unless ( defined $opts{'vs'} );
135
    Error ("No Linker Script Name") unless ( defined $opts{'ls'} );
136
 
137
    #
138
    #   Open the file and slurp in all the data
139
    #   Remove returnss and leave newline characters
140
    #
141
    open (my $fh, '<' , $opts{'src'} ) || Error ("Cannot open: $opts{'src'}", "Reason:$!");
142
    $/ = undef;
143
    my $data = <$fh>;
144
    close $fh;
145
    $data =~ s~\r~~g;
146
    #print $data;
147
 
148
    #
149
    #   Process the contents character by character
150
    #   Expecting
151
    #       EXTERN (.... )
152
    #       VERSION { { .... } }
153
    #
154
    my @items;
155
    my $item;
156
 
157
    my $omatch;
158
    my $cmatch;
159
    my $mode = 0;
160
    my $depth;
161
    foreach my $char (split //, $data)
162
    {
163
    #print("-----$char, $mode, $depth\n");
164
        $item .= $char;
165
        if ($mode == 0) {
166
            if ($char =~ m~[({[<]~) {
167
                $mode = 1;
168
                $omatch = $char;
169
                $cmatch = $char;
170
                $cmatch =~ tr~({[<~)}]>~;
171
                $depth=1;
172
            }
173
 
174
        } elsif ($mode == 1 ) {
175
            if ($char eq $omatch) {
176
                $depth++;
177
            }
178
            if ($char eq $cmatch) {
179
                $depth--;
180
                if ($depth == 0 ) {
181
                    $mode = 0;
182
                    $item =~ s~^\s+~~;
183
                    push @items, $item;
184
                    $item = '';
185
                }
186
            }
187
        }
188
    }
189
 
190
    #
191
    #   Generate simple LinkerScript and VersionScript
192
    #   Must generate one of each - even if its a dummy
193
    #
194
    my $versionSeen,
195
    my $externSeen;
196
    foreach $item ( @items) {
197
        my $name = 'UNKNOWN SECTION:';
198
        if ($item =~ m~^VERSION~i) {
199
            $versionSeen = 1;
200
            $item =~ s~.*VERSION.*{~JATS_VERSION {~si;
201
            $item =~ s~};.*~};~si;
202
            FileWrite(  $opts{'vs'}, $item);
203
 
204
        } elsif ($item =~ m~^EXTERN~i) {
205
            $externSeen = 1;
206
            FileWrite(  $opts{'ls'}, $item);
207
        } else {
208
            Warning ("Unknown section in linker script - ignored", $data);
209
        }
210
    }
211
 
212
    #
213
    #   Generate dummy sections if required
214
    #
215
    unless ($versionSeen) {
216
        FileWrite(  $opts{'vs'}, 'VX {};');
217
    }
218
 
219
    unless ($externSeen) {
220
        FileWrite(  $opts{'ls'}, 'jats_dummy = 1;');
221
    }
222
 
223
}
224
 
225
#-------------------------------------------------------------------------------
226
# Function        : FileWrite 
227
#
228
# Description     : Simple file writer
229
#
230
# Inputs          : $fname  - Path to file to create
231
#                   $data   - Data to write to the file
232
#
233
# Returns         : 
234
#
235
 
236
sub FileWrite
237
{
238
    my ($fname, $data) = @_;
239
    Message ("Generate: $fname");
240
    open  (my $fh, '>', $fname ) || Error( "Cannot create file: $fname", "Reason: $!" );
241
    print $fh $data . "\n";
242
    close $fh;
243
}
244
 
245
 
246
1;