| 227 |
dpurdie |
1 |
#! /usr/bin/perl
|
|
|
2 |
########################################################################
|
|
|
3 |
# Copyright (C) 1998-2004 ERG Limited, All rights reserved
|
|
|
4 |
#
|
|
|
5 |
# Module name : jats_builder.pl
|
|
|
6 |
# Module type : Makefile system
|
|
|
7 |
# Compiler(s) : n/a
|
|
|
8 |
# Environment(s):
|
|
|
9 |
#
|
|
|
10 |
# Description : A script to build an entire systems
|
|
|
11 |
# The script will:
|
|
|
12 |
# Build a tree of related modules in the correct order
|
|
|
13 |
#
|
|
|
14 |
# Rewrite build.pl files with correct version information
|
|
|
15 |
#
|
|
|
16 |
# Maintain the pkg_archive cache
|
|
|
17 |
#
|
|
|
18 |
# Display interanal and external dependencies
|
|
|
19 |
#
|
|
|
20 |
#
|
|
|
21 |
# Version Who Date Description
|
|
|
22 |
# 1.0.0 DDP 8-Jun-04 Created
|
|
|
23 |
#
|
|
|
24 |
#......................................................................#
|
|
|
25 |
|
|
|
26 |
use strict;
|
|
|
27 |
use JatsError;
|
|
|
28 |
|
|
|
29 |
use Data::Dumper; # Debug only
|
|
|
30 |
use Pod::Usage; # required for help support
|
|
|
31 |
use Getopt::Long;
|
|
|
32 |
use Cwd;
|
|
|
33 |
use File::Path;
|
|
|
34 |
|
|
|
35 |
my $VERSION = "2.0.0"; # Update this
|
|
|
36 |
|
|
|
37 |
#
|
|
|
38 |
# Options
|
|
|
39 |
#
|
|
|
40 |
my $opt_debug = $ENV{'GBE_DEBUG'}; # Allow global debug
|
|
|
41 |
my $opt_verbose = $ENV{'GBE_VERBOSE'}; # Allow global verbose
|
|
|
42 |
my $opt_help;
|
|
|
43 |
my $opt_manual;
|
|
|
44 |
my $opt_clean;
|
|
|
45 |
my $opt_expert = 1;
|
|
|
46 |
my $opt_uselog = 1;
|
|
|
47 |
my $opt_resetlog;
|
|
|
48 |
my $opt_skip = 2;
|
|
|
49 |
my $opt_quick = 0;
|
|
|
50 |
my $opt_build = 1;
|
|
|
51 |
my $opt_build_all;
|
|
|
52 |
my $opt_update_cache;
|
|
|
53 |
my @opt_only;
|
|
|
54 |
my $opt_only_prereq = 2;
|
|
|
55 |
my $opt_dump;
|
|
|
56 |
my $opt_dump_all;
|
|
|
57 |
my $opt_show;
|
|
|
58 |
my $opt_show_rule;
|
|
|
59 |
my $opt_show_pkg;
|
|
|
60 |
my $opt_label_all;
|
|
|
61 |
my $opt_audit;
|
|
|
62 |
my $opt_audit_entry;
|
|
|
63 |
|
|
|
64 |
my $opt_buildfiles;
|
|
|
65 |
my $opt_buildfiles_rewrite;
|
|
|
66 |
my $opt_buildfiles_checkout;
|
|
|
67 |
my $opt_buildfiles_label;
|
|
|
68 |
my $opt_buildfiles_labelall;
|
|
|
69 |
my $opt_buildfiles_labelrule;
|
|
|
70 |
my $opt_config = "build.cfg";
|
|
|
71 |
my $opt_script;
|
|
|
72 |
my $opt_gen_pathlist;
|
|
|
73 |
my $opt_create_dpkg;
|
|
|
74 |
|
|
|
75 |
#
|
|
|
76 |
# Globals
|
|
|
77 |
#
|
|
|
78 |
my $GBE_PERL = $ENV{'GBE_PERL'}; # Essential ENV variables
|
|
|
79 |
my $GBE_CORE = $ENV{'GBE_CORE'};
|
|
|
80 |
|
|
|
81 |
my $root_dir; # Root of the project
|
|
|
82 |
my $cwd; # The current directory
|
|
|
83 |
my @modules; # List of modules to process
|
|
|
84 |
my %dir_to_name; # path -> component name
|
|
|
85 |
my %internal; # Internal components -> path
|
|
|
86 |
|
|
|
87 |
my $build_label;
|
|
|
88 |
my $label;
|
|
|
89 |
my $logfile;
|
|
|
90 |
my $logfile_dir;
|
|
|
91 |
my $logfile_name;
|
|
|
92 |
my $logfile_base;
|
|
|
93 |
my $audit_logfile;
|
|
|
94 |
my $datafile;
|
|
|
95 |
my $build_this;
|
|
|
96 |
my @audit_args;
|
|
|
97 |
my $logfile_inuse = 0;
|
|
|
98 |
|
|
|
99 |
|
|
|
100 |
#
|
|
|
101 |
# Fixed config strings
|
|
|
102 |
#
|
|
|
103 |
my $BUILDFILE = "build.pl"; # Basic build file
|
|
|
104 |
my $BUILDUSE = "build.use.pl"; # Massaged build file
|
|
|
105 |
my $AUDIT_DO = "build.audit.do"; # Audit derived object
|
|
|
106 |
my $AUDIT_LOG = "build.audit.log"; # Post audit log
|
|
|
107 |
my $LOGFILE_EXT = "builder.log"; # Builder logfile extension
|
|
|
108 |
my $AUDITFILE_EXT = "audit.log"; # Post audit logfile
|
|
|
109 |
|
|
|
110 |
################################################################################
|
|
|
111 |
# Data used in the file rewrite process
|
|
|
112 |
#
|
|
|
113 |
#
|
|
|
114 |
my $project; # The project name (short form)
|
|
|
115 |
|
|
|
116 |
#
|
|
|
117 |
# A Hash of external components and version numbers
|
|
|
118 |
#
|
|
|
119 |
my %external_component = ();
|
|
|
120 |
|
|
|
121 |
#
|
|
|
122 |
# A hash of components that have MULTIPLE version numbers
|
|
|
123 |
#
|
|
|
124 |
my %kludge_component = ();
|
|
|
125 |
|
|
|
126 |
#
|
|
|
127 |
# A hash of project extensions that should not be massaged
|
|
|
128 |
#
|
|
|
129 |
my %project_keep = (
|
|
|
130 |
'mas' => 'mas',
|
|
|
131 |
'cr' => 'cr',
|
|
|
132 |
'cots' => 'cots',
|
|
|
133 |
);
|
|
|
134 |
|
|
|
135 |
#-------------------------------------------------------------------------------
|
|
|
136 |
# Function : Mainline Entry Point
|
|
|
137 |
#
|
|
|
138 |
# Description :
|
|
|
139 |
#
|
|
|
140 |
# Inputs :
|
|
|
141 |
#
|
|
|
142 |
@audit_args = @ARGV;
|
|
|
143 |
my $result = GetOptions (
|
|
|
144 |
"help+" => \$opt_help, # flag, multiple use allowed
|
|
|
145 |
"manual" => \$opt_manual, # flag, multiple use allowed
|
|
|
146 |
"verbose+" => \$opt_verbose, # flag, multiple use allowed
|
|
|
147 |
"clean" => \$opt_clean, # flag
|
|
|
148 |
"clear" => \$opt_clean, # flag
|
|
|
149 |
"log!" => \$opt_uselog, # flag with [no] option
|
|
|
150 |
"resetlog" => \$opt_resetlog, # flag
|
|
|
151 |
"expert!" => \$opt_expert, # flag with [no] option
|
|
|
152 |
"skip!" => \$opt_skip, # flag with [no] option
|
|
|
153 |
"quick!" => \$opt_quick, # flag with [no] option
|
|
|
154 |
"build!" => \$opt_build, # flag with [no] option
|
|
|
155 |
"all!" => \$opt_build_all, # flag with [no] option
|
|
|
156 |
"updatecache+" => \$opt_update_cache, # flag, multiple use allowed
|
|
|
157 |
"only=s" => \@opt_only, # String
|
|
|
158 |
"prereq!" => \$opt_only_prereq, # flag with [no] option
|
|
|
159 |
"dump+" => \$opt_dump, # flag
|
|
|
160 |
"dumpall" => \$opt_dump_all, # flag
|
|
|
161 |
"show" => \$opt_show, # flag
|
|
|
162 |
"showrule" => \$opt_show_rule, # flag
|
|
|
163 |
"showpkg" => \$opt_show_pkg, # flag
|
|
|
164 |
"labelall" => \$opt_label_all, # flag
|
|
|
165 |
"config:s" => \$opt_config, # String
|
|
|
166 |
"audit" => \$opt_audit, # flag
|
|
|
167 |
"AUDITMODE:s" => \$opt_audit_entry, # String
|
|
|
168 |
"script:s" => \$opt_script, # String
|
|
|
169 |
|
|
|
170 |
"buildfiles" => \$opt_buildfiles, # flag
|
|
|
171 |
"buildfiles_rewrite!" => \$opt_buildfiles_rewrite, # flag
|
|
|
172 |
"buildfiles_checkout!" => \$opt_buildfiles_checkout, # flag
|
|
|
173 |
"buildfiles_label!" => \$opt_buildfiles_label, # flag
|
|
|
174 |
"buildfiles_labelall!" => \$opt_buildfiles_labelall, # flag
|
|
|
175 |
"buildfiles_labelrule!" => \$opt_buildfiles_labelrule, # flag
|
|
|
176 |
|
|
|
177 |
"pathlist" => \$opt_gen_pathlist,
|
|
|
178 |
"create_dpkg" => \$opt_create_dpkg,
|
|
|
179 |
);
|
|
|
180 |
|
|
|
181 |
#
|
|
|
182 |
# UPDATE THE DOCUMENTATION AT THE END OF THIS FILE !!!
|
|
|
183 |
#
|
|
|
184 |
|
|
|
185 |
#
|
|
|
186 |
# Process help and manual options
|
|
|
187 |
#
|
|
|
188 |
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
|
|
|
189 |
pod2usage(-verbose => 1) if ($opt_help == 2 );
|
|
|
190 |
pod2usage(-verbose => 2) if ($opt_manual || $opt_help > 2);
|
|
|
191 |
|
|
|
192 |
ErrorConfig( 'name' =>'JBUILDER',
|
|
|
193 |
'verbose' => $opt_verbose );
|
|
|
194 |
|
|
|
195 |
#
|
|
|
196 |
# Validate user options
|
|
|
197 |
# Not expecting any user arguments, other than options, so spit if any are found
|
|
|
198 |
#
|
|
|
199 |
Error ("Unexpected command line arguments present" )
|
|
|
200 |
if ( $#ARGV >= 0 );
|
|
|
201 |
|
|
|
202 |
#
|
|
|
203 |
# Determine the current working directory
|
|
|
204 |
#
|
|
|
205 |
$cwd = getcwd();
|
|
|
206 |
Verbose ("Current Working Directory: " . $cwd );
|
|
|
207 |
|
|
|
208 |
#
|
|
|
209 |
# Locate the base config file
|
|
|
210 |
# This will be located with in the root directory and this will be where
|
|
|
211 |
# the build log file will be created
|
|
|
212 |
#
|
|
|
213 |
my $test_dir = $cwd;
|
|
|
214 |
LOOP: {
|
|
|
215 |
do
|
|
|
216 |
{
|
|
|
217 |
Verbose2 ("Testing: $test_dir");
|
|
|
218 |
my $win_test_file = "$test_dir/$opt_config" ;
|
|
|
219 |
if ( -f $win_test_file )
|
|
|
220 |
{
|
|
|
221 |
Verbose ("Found build config file: $win_test_file");
|
|
|
222 |
$root_dir = $test_dir;
|
|
|
223 |
last;
|
|
|
224 |
}
|
|
|
225 |
#
|
|
|
226 |
# Remove one directory
|
|
|
227 |
# Terminate the loop when no more can be removed
|
|
|
228 |
#
|
|
|
229 |
} while ( $test_dir =~ s~[/][^/]*$~~ );
|
|
|
230 |
}
|
|
|
231 |
|
|
|
232 |
$datafile = "$root_dir/$opt_config";
|
|
|
233 |
Error ("Cannot locate config file: $opt_config")
|
|
|
234 |
unless ( -f $datafile );
|
|
|
235 |
|
|
|
236 |
#
|
|
|
237 |
# Intercept AUDITMODE operation
|
|
|
238 |
# ClearCase audit requires a program shell to be audited. It can't simply
|
|
|
239 |
# be turned on and off. This is achived by using a special invocation of
|
|
|
240 |
# this program to provide the auditable suite of functions
|
|
|
241 |
#
|
|
|
242 |
audit_operation()
|
|
|
243 |
if ( $opt_audit_entry );
|
|
|
244 |
|
|
|
245 |
if ( $opt_audit )
|
|
|
246 |
{
|
|
|
247 |
Error ("Cannot audit a non-dynamic clearcase view")
|
|
|
248 |
unless ( is_dynamic_view() );
|
|
|
249 |
}
|
|
|
250 |
|
|
|
251 |
|
|
|
252 |
#
|
|
|
253 |
# Read in the build config file
|
|
|
254 |
# There are a few directives that are parsed as we go
|
|
|
255 |
# The root directory may be redefined
|
|
|
256 |
#
|
|
|
257 |
read_config_file( $datafile );
|
|
|
258 |
Error ("No LABEL found in config file")
|
|
|
259 |
unless ( $label );
|
|
|
260 |
Error ("No components to build in the config file")
|
|
|
261 |
unless ( $#modules >= 0 );
|
|
|
262 |
|
|
|
263 |
#
|
|
|
264 |
# Generate the name of the logfile
|
|
|
265 |
#
|
|
|
266 |
( $logfile_base = $opt_config ) =~ s~\.\w*$~~;
|
|
|
267 |
$logfile_dir = $root_dir;
|
|
|
268 |
|
|
|
269 |
#
|
|
|
270 |
# Determine default operation (no local build.pl file)
|
|
|
271 |
# If we are in the root directory, then, by default, build ALL modules
|
|
|
272 |
# otherwise, by default, build the current one
|
|
|
273 |
#
|
|
|
274 |
unless ( $opt_build_all || ( $#opt_only >= 0 ) )
|
|
|
275 |
{
|
|
|
276 |
#
|
|
|
277 |
# If a local build file is found, then just build it
|
|
|
278 |
# Set default operation to skip and nopreq
|
|
|
279 |
#
|
|
|
280 |
if ( -f $BUILDFILE )
|
|
|
281 |
{
|
|
|
282 |
$build_this = 1;
|
|
|
283 |
}
|
|
|
284 |
else
|
|
|
285 |
{
|
|
|
286 |
#
|
|
|
287 |
# No user specified modules to build
|
|
|
288 |
# If we are not in the root directory, then die
|
|
|
289 |
#
|
|
|
290 |
Error ("Cannot determine what to do from this directory\n")
|
|
|
291 |
unless ( -f $opt_config );
|
|
|
292 |
}
|
|
|
293 |
}
|
|
|
294 |
|
|
|
295 |
#
|
|
|
296 |
# Determine the "here" component
|
|
|
297 |
# Ensure that the component is in the module list, even if its not in the config file
|
|
|
298 |
#
|
|
|
299 |
if ( $build_this )
|
|
|
300 |
{
|
|
|
301 |
$build_this = substr ( $cwd, 1 + length ( $root_dir ) );
|
|
|
302 |
Verbose2 ("Here: $build_this" );
|
|
|
303 |
my $file = "$root_dir/$build_this/$BUILDFILE" ;
|
|
|
304 |
Error ("Cannot determine component. Not Found: $file" )
|
|
|
305 |
unless ( -f $file );
|
|
|
306 |
push @modules, $build_this;
|
|
|
307 |
|
|
|
308 |
#
|
|
|
309 |
# Building the module in the current directory
|
|
|
310 |
# Set a few options - if they are still defaulted
|
|
|
311 |
# Force noskip to ensure the component is built
|
|
|
312 |
# Force nopreq to prevent prerequisites being built
|
|
|
313 |
# Generate a logfile in the current directory
|
|
|
314 |
#
|
|
|
315 |
# $opt_skip = 0
|
|
|
316 |
# if ( $opt_skip == 2 );
|
|
|
317 |
# $opt_only_prereq = 0
|
|
|
318 |
# if ( $opt_only_prereq == 2 );
|
|
|
319 |
|
|
|
320 |
$logfile_dir = ".";
|
|
|
321 |
$opt_resetlog = 1;
|
|
|
322 |
}
|
|
|
323 |
|
|
|
324 |
################################################################################
|
|
|
325 |
# Restart the log file
|
|
|
326 |
#
|
|
|
327 |
$audit_logfile = "$logfile_dir/$logfile_base.$AUDITFILE_EXT";
|
|
|
328 |
$logfile = "$logfile_dir/$logfile_base.$LOGFILE_EXT";
|
|
|
329 |
if ( $opt_resetlog || $opt_clean )
|
|
|
330 |
{
|
|
|
331 |
print "Delete logfile: $logfile\n";
|
|
|
332 |
System ("rm -f $logfile" );
|
|
|
333 |
|
|
|
334 |
print "Delete audit log: $logfile\n";
|
|
|
335 |
System ("rm -f $audit_logfile" );
|
|
|
336 |
}
|
|
|
337 |
|
|
|
338 |
################################################################################
|
|
|
339 |
#
|
|
|
340 |
# Label all files in the view
|
|
|
341 |
#
|
|
|
342 |
if ( $opt_label_all )
|
|
|
343 |
{
|
|
|
344 |
label_all_files();
|
|
|
345 |
exit 0;
|
|
|
346 |
}
|
|
|
347 |
|
|
|
348 |
################################################################################
|
|
|
349 |
#
|
|
|
350 |
# Update the local dpkg_archive cache - if required
|
|
|
351 |
# This does not require processing of the external packages
|
|
|
352 |
#
|
|
|
353 |
if ( $opt_update_cache )
|
|
|
354 |
{
|
|
|
355 |
my @cache_list;
|
|
|
356 |
my $mode;
|
|
|
357 |
|
|
|
358 |
$mode = "-refresh" if ( $opt_update_cache > 1 );
|
|
|
359 |
|
|
|
360 |
for my $file (sort keys %external_component)
|
|
|
361 |
{
|
|
|
362 |
if ( $kludge_component{$file} )
|
|
|
363 |
{
|
|
|
364 |
for my $fl (sort keys %{$kludge_component{$file}} )
|
|
|
365 |
{
|
|
|
366 |
push @cache_list, "$file/$kludge_component{$file}{$fl}.$fl";
|
|
|
367 |
}
|
|
|
368 |
}
|
|
|
369 |
else
|
|
|
370 |
{
|
|
|
371 |
push @cache_list, "$file/$external_component{$file}";
|
|
|
372 |
}
|
|
|
373 |
}
|
|
|
374 |
|
|
|
375 |
JatsCmd( "dpkg_cache $mode @cache_list" );
|
|
|
376 |
}
|
|
|
377 |
|
|
|
378 |
################################################################################
|
|
|
379 |
#
|
|
|
380 |
# Examine all named modules and determine the build order
|
|
|
381 |
# Limit the list of built modules if required
|
|
|
382 |
#
|
|
|
383 |
@modules = determine_build_order( @modules );
|
|
|
384 |
|
|
|
385 |
################################################################################
|
|
|
386 |
# Generate a directory list
|
|
|
387 |
#
|
|
|
388 |
if ( $opt_gen_pathlist )
|
|
|
389 |
{
|
|
|
390 |
generate_pathlist();
|
|
|
391 |
exit 0;
|
|
|
392 |
}
|
|
|
393 |
|
|
|
394 |
################################################################################
|
|
|
395 |
#
|
|
|
396 |
# External Script Interface
|
|
|
397 |
#
|
|
|
398 |
if ( $opt_script )
|
|
|
399 |
{
|
|
|
400 |
Verbose ("Script:perl $ENV{'GBE_TOOLS'}/$opt_script @modules");
|
|
|
401 |
System ("perl $ENV{'GBE_TOOLS'}/$opt_script @modules");
|
|
|
402 |
exit $result;
|
|
|
403 |
}
|
|
|
404 |
|
|
|
405 |
################################################################################
|
|
|
406 |
# Display the external packages as LinkPkgArchive statements
|
|
|
407 |
#
|
|
|
408 |
if ( $opt_show_pkg)
|
|
|
409 |
{
|
|
|
410 |
my $pkg;
|
|
|
411 |
my $ver;
|
|
|
412 |
|
|
|
413 |
for my $file (sort keys %external_component)
|
|
|
414 |
{
|
|
|
415 |
if ( $kludge_component{$file} )
|
|
|
416 |
{
|
|
|
417 |
for my $fl (sort keys %{$kludge_component{$file}} )
|
|
|
418 |
{
|
|
|
419 |
$pkg = $file;
|
|
|
420 |
$ver = "$kludge_component{$file}{$fl}.$fl";
|
|
|
421 |
print "LinkPkgArchive( '$pkg', '$ver' );\n";
|
|
|
422 |
}
|
|
|
423 |
}
|
|
|
424 |
else
|
|
|
425 |
{
|
|
|
426 |
$pkg = $file;
|
|
|
427 |
$ver = $external_component{$file};
|
|
|
428 |
print "LinkPkgArchive( '$pkg', '$ver' );\n";
|
|
|
429 |
}
|
|
|
430 |
}
|
|
|
431 |
exit 0;
|
|
|
432 |
}
|
|
|
433 |
|
|
|
434 |
################################################################################
|
|
|
435 |
# Display the external packages and the build order
|
|
|
436 |
#
|
|
|
437 |
if ( $opt_show || $opt_show_rule || $opt_show_pkg)
|
|
|
438 |
{
|
|
|
439 |
print "\nExternal packages (Alphabetic Order)\n";
|
|
|
440 |
for my $file (sort keys %external_component)
|
|
|
441 |
{
|
|
|
442 |
if ( $kludge_component{$file} )
|
|
|
443 |
{
|
|
|
444 |
for my $fl (sort keys %{$kludge_component{$file}} )
|
|
|
445 |
{
|
|
|
446 |
printf " %-20s %s.%s\n", $file,$kludge_component{$file}{$fl},$fl;
|
|
|
447 |
}
|
|
|
448 |
}
|
|
|
449 |
else
|
|
|
450 |
{
|
|
|
451 |
printf " %-20s %s\n", $file,$external_component{$file};
|
|
|
452 |
}
|
|
|
453 |
}
|
|
|
454 |
|
|
|
455 |
print "\nInternal Components (Build Order)\n";
|
|
|
456 |
for my $module ( @modules )
|
|
|
457 |
{
|
|
|
458 |
if ( $opt_show_rule )
|
|
|
459 |
{
|
|
|
460 |
printf " %-50s %-25s %s\n", $module, $dir_to_name{$module}, cleacase_rule($module);
|
|
|
461 |
}
|
|
|
462 |
else
|
|
|
463 |
{
|
|
|
464 |
printf " %-50s %s\n", $module, $dir_to_name{$module};
|
|
|
465 |
}
|
|
|
466 |
}
|
|
|
467 |
print "\n";
|
|
|
468 |
|
|
|
469 |
# print "\nBuildFiles\n";
|
|
|
470 |
# for my $module ( @modules )
|
|
|
471 |
# {
|
|
|
472 |
# printf " %s/build.pl\n", $module ;
|
|
|
473 |
# }
|
|
|
474 |
# print "\n";
|
|
|
475 |
|
|
|
476 |
}
|
|
|
477 |
|
|
|
478 |
################################################################################
|
|
|
479 |
#
|
|
|
480 |
# Setup STDOUT and STDERR to a logfile
|
|
|
481 |
# This will force all output to be directed to the logfile, by default
|
|
|
482 |
#
|
|
|
483 |
logfile_control(1);
|
|
|
484 |
|
|
|
485 |
################################################################################
|
|
|
486 |
#
|
|
|
487 |
# Start a clean build
|
|
|
488 |
# Delete the local package archive and then clean out all packages
|
|
|
489 |
#
|
|
|
490 |
if ( $opt_clean )
|
|
|
491 |
{
|
|
|
492 |
for my $module ( @modules )
|
|
|
493 |
{
|
|
|
494 |
my $dir = "$root_dir/$module";
|
|
|
495 |
print OLDOUT "Cleaning package: $module";
|
|
|
496 |
if ( -d $dir )
|
|
|
497 |
{
|
|
|
498 |
chdir ( $dir );
|
|
|
499 |
|
|
|
500 |
System ("rm -f $BUILDUSE $AUDIT_DO $AUDIT_LOG *$LOGFILE_EXT *$AUDITFILE_EXT" );
|
|
|
501 |
JatsCmd ( "clean" );
|
|
|
502 |
JatsCmd ( "clobber" );
|
|
|
503 |
rm_dir ( "pkg" ) if ( -d pkg );
|
|
|
504 |
}
|
|
|
505 |
print OLDOUT "\n";
|
|
|
506 |
}
|
|
|
507 |
|
|
|
508 |
#
|
|
|
509 |
# Remove local archive LAST to give the user a chance to control-C out
|
|
|
510 |
# of this massive delete - iff done in Error :(
|
|
|
511 |
#
|
|
|
512 |
print OLDOUT "Removing local_dpkg_archive";
|
|
|
513 |
rm_dir ( "$root_dir/local_dpkg_archive" );
|
|
|
514 |
print OLDOUT "\n";
|
|
|
515 |
}
|
|
|
516 |
|
|
|
517 |
################################################################################
|
|
|
518 |
#
|
|
|
519 |
# Ensure that the local dpkg_archive directory exists
|
|
|
520 |
#
|
|
|
521 |
System ("mkdir -p $root_dir/local_dpkg_archive" );
|
|
|
522 |
|
|
|
523 |
################################################################################
|
|
|
524 |
# Process build files only
|
|
|
525 |
#
|
|
|
526 |
# Ensure that the $BUILDFILE files are up to date
|
|
|
527 |
# If required the files will be checkedout and updated
|
|
|
528 |
# A label will be applied to all the build files ( + makefile.pl )
|
|
|
529 |
#
|
|
|
530 |
|
|
|
531 |
sub ed4w
|
|
|
532 |
{
|
|
|
533 |
my ($name) = @_;
|
|
|
534 |
system ( "c:/Progra~1/SAIG/ED4W/ED32.exe $name" );
|
|
|
535 |
}
|
|
|
536 |
|
|
|
537 |
if ( $opt_buildfiles )
|
|
|
538 |
{
|
|
|
539 |
my $same = 0;
|
|
|
540 |
my $not_same = 0;
|
|
|
541 |
my $ecount = 0;
|
|
|
542 |
|
|
|
543 |
for my $module ( @modules )
|
|
|
544 |
{
|
|
|
545 |
my $dir = "$root_dir/$module";
|
|
|
546 |
my $efound = 0;
|
|
|
547 |
printf OLDOUT "Processing %-50s", $module;
|
|
|
548 |
if ( -d $dir )
|
|
|
549 |
{
|
|
|
550 |
chdir ( $dir );
|
|
|
551 |
|
|
|
552 |
# if ( ! is_checked_out ("$BUILDFILE") )
|
|
|
553 |
# {
|
|
|
554 |
# print OLDOUT " Checkout";
|
|
|
555 |
# System ("cleartool co -nc $BUILDFILE" );
|
|
|
556 |
# print OLDOUT "\n";
|
|
|
557 |
# }
|
|
|
558 |
# ed4w( "$dir/build.pl" );
|
|
|
559 |
# next;
|
|
|
560 |
|
|
|
561 |
$result = rewrite_build_file ( $module );
|
|
|
562 |
Verbose ("rewrite build.pl result): $result");
|
|
|
563 |
if ( $result )
|
|
|
564 |
{
|
|
|
565 |
print OLDOUT "DIFFERENT";
|
|
|
566 |
$not_same++;
|
|
|
567 |
|
|
|
568 |
if ( $opt_buildfiles_checkout )
|
|
|
569 |
{
|
|
|
570 |
if ( ! is_checked_out ("$BUILDFILE") )
|
|
|
571 |
{
|
|
|
572 |
print OLDOUT " Checkout";
|
|
|
573 |
System ("cleartool co -nc $BUILDFILE" );
|
|
|
574 |
}
|
|
|
575 |
}
|
|
|
576 |
|
|
|
577 |
if ( $opt_buildfiles_rewrite || $opt_buildfiles_checkout )
|
|
|
578 |
{
|
|
|
579 |
System ("rm -f $BUILDFILE" );
|
|
|
580 |
if ( System ("mv -f $BUILDUSE $BUILDFILE" ) )
|
|
|
581 |
{
|
|
|
582 |
print OLDOUT " ERROR:ReWrite";
|
|
|
583 |
}
|
|
|
584 |
else
|
|
|
585 |
{
|
|
|
586 |
print OLDOUT " ReWrite";
|
|
|
587 |
}
|
|
|
588 |
}
|
|
|
589 |
|
|
|
590 |
|
|
|
591 |
}
|
|
|
592 |
elsif ( $result == 0 )
|
|
|
593 |
{
|
|
|
594 |
print OLDOUT "Same";
|
|
|
595 |
$same++;
|
|
|
596 |
}
|
|
|
597 |
else
|
|
|
598 |
{
|
|
|
599 |
print OLDOUT "Error";
|
|
|
600 |
$ecount++;
|
|
|
601 |
$efound = 1;
|
|
|
602 |
}
|
|
|
603 |
}
|
|
|
604 |
else
|
|
|
605 |
{
|
|
|
606 |
print OLDOUT "Not Found";
|
|
|
607 |
$ecount++;
|
|
|
608 |
$efound = 1;
|
|
|
609 |
}
|
|
|
610 |
|
|
|
611 |
if ( $opt_buildfiles_label || $opt_buildfiles_labelall || $opt_buildfiles_labelrule )
|
|
|
612 |
{
|
|
|
613 |
if ( ! $efound )
|
|
|
614 |
{
|
|
|
615 |
my @list;
|
|
|
616 |
my $label = $build_label;
|
|
|
617 |
|
|
|
618 |
if ( $opt_buildfiles_labelrule )
|
|
|
619 |
{
|
|
|
620 |
$label = cleacase_rule( $module );
|
|
|
621 |
}
|
|
|
622 |
|
|
|
623 |
#
|
|
|
624 |
# Determine files to label
|
|
|
625 |
#
|
|
|
626 |
unless ( $opt_buildfiles_labelall )
|
|
|
627 |
{
|
|
|
628 |
@list = qw ( build.pl );
|
|
|
629 |
}
|
|
|
630 |
else
|
|
|
631 |
{
|
|
|
632 |
@list = qw ( build.pl makefile.pl src/makefile.pl src . ..);
|
|
|
633 |
push @list, glob ("warnings.*" );
|
|
|
634 |
}
|
|
|
635 |
|
|
|
636 |
for my $file ( @list )
|
|
|
637 |
{
|
|
|
638 |
if ( ! has_label( $file, $label) )
|
|
|
639 |
{
|
|
|
640 |
print OLDOUT " Label:$file";
|
|
|
641 |
my $mode = "";
|
|
|
642 |
my $mode = "-replace" unless($file eq ".." );
|
|
|
643 |
Verbose ("cleartool mklabel -nc $mode $label $file" );
|
|
|
644 |
$result = System ("cleartool mklabel -nc $mode $label $file" );
|
|
|
645 |
print OLDOUT "-ERR"
|
|
|
646 |
if ( $result );
|
|
|
647 |
|
|
|
648 |
}
|
|
|
649 |
}
|
|
|
650 |
}
|
|
|
651 |
}
|
|
|
652 |
print OLDOUT "\n";
|
|
|
653 |
}
|
|
|
654 |
printf OLDOUT "Diffs: %d, Same: %d, Errors: %d\n", $not_same, $same, $ecount;
|
|
|
655 |
exit 0;
|
|
|
656 |
}
|
|
|
657 |
|
|
|
658 |
################################################################################
|
|
|
659 |
#
|
|
|
660 |
# Compile each module
|
|
|
661 |
#
|
|
|
662 |
$result = 0;
|
|
|
663 |
if ( $opt_build )
|
|
|
664 |
{
|
|
|
665 |
for my $module ( @modules )
|
|
|
666 |
{
|
|
|
667 |
if ( build_module ( $module ) > 0 )
|
|
|
668 |
{
|
|
|
669 |
$result = 1;
|
|
|
670 |
last;
|
|
|
671 |
}
|
|
|
672 |
}
|
|
|
673 |
|
|
|
674 |
#
|
|
|
675 |
# Install packages into dpkg_archive, but only if the packages built OK
|
|
|
676 |
# This is an interactive process, so disable the logfile
|
|
|
677 |
#
|
|
|
678 |
if ( ! $result and $opt_create_dpkg )
|
|
|
679 |
{
|
|
|
680 |
logfile_control ( 0 );
|
|
|
681 |
for my $module ( @modules )
|
|
|
682 |
{
|
|
|
683 |
if ( install_package ( $module ) > 0 )
|
|
|
684 |
{
|
|
|
685 |
$result = 1;
|
|
|
686 |
last;
|
|
|
687 |
}
|
|
|
688 |
}
|
|
|
689 |
}
|
|
|
690 |
}
|
|
|
691 |
|
|
|
692 |
logfile_control ( 0 );
|
|
|
693 |
exit $result;
|
|
|
694 |
|
|
|
695 |
|
|
|
696 |
#-------------------------------------------------------------------------------
|
|
|
697 |
# Function : logfile_control
|
|
|
698 |
#
|
|
|
699 |
# Description : Enable and disable the use of a logfile
|
|
|
700 |
#
|
|
|
701 |
# Inputs : $1 - True: Enable logfile
|
|
|
702 |
# False: Disable logfile
|
|
|
703 |
#
|
|
|
704 |
# Returns :
|
|
|
705 |
#
|
|
|
706 |
sub logfile_control
|
|
|
707 |
{
|
|
|
708 |
( my $enable ) = @_;
|
|
|
709 |
if ( $enable )
|
|
|
710 |
{
|
|
|
711 |
if ( ! $logfile_inuse )
|
|
|
712 |
{
|
|
|
713 |
open OLDOUT, ">&STDOUT" or Error ("Can't dup STDOUT: $!");
|
|
|
714 |
open OLDERR, ">&STDERR" or Error ("Can't dup STDERR: $!");
|
|
|
715 |
|
|
|
716 |
if ( $opt_uselog )
|
|
|
717 |
{
|
|
|
718 |
open STDOUT, '>>', $logfile or die "Can't redirect STDOUT: $!";
|
|
|
719 |
open STDERR, ">&STDOUT" or die "Can't dup STDOUT: $!";
|
|
|
720 |
|
|
|
721 |
|
|
|
722 |
select OLDERR; $| = 1; # make unbuffered
|
|
|
723 |
select OLDOUT; $| = 1; # make unbuffered
|
|
|
724 |
|
|
|
725 |
select STDERR; $| = 1; # make unbuffered
|
|
|
726 |
select STDOUT; $| = 1; # make unbuffered
|
|
|
727 |
}
|
|
|
728 |
$logfile_inuse = 1;
|
|
|
729 |
}
|
|
|
730 |
}
|
|
|
731 |
else
|
|
|
732 |
{
|
|
|
733 |
if ( $logfile_inuse )
|
|
|
734 |
{
|
|
|
735 |
#
|
|
|
736 |
# Restore redirection
|
|
|
737 |
#
|
|
|
738 |
close STDOUT;
|
|
|
739 |
close STDERR;
|
|
|
740 |
|
|
|
741 |
open STDOUT, ">&OLDOUT" or die "Can't dup OLDOUT: $!";
|
|
|
742 |
open STDERR, ">&OLDERR" or die "Can't dup OLDERR: $!";
|
|
|
743 |
|
|
|
744 |
select STDERR; $| = 1; # make unbuffered
|
|
|
745 |
select STDOUT; $| = 1; # make unbuffered
|
|
|
746 |
|
|
|
747 |
$logfile_inuse = 0;
|
|
|
748 |
}
|
|
|
749 |
}
|
|
|
750 |
}
|
|
|
751 |
|
|
|
752 |
#-------------------------------------------------------------------------------
|
|
|
753 |
# Function : audit_operation
|
|
|
754 |
#
|
|
|
755 |
# Description : Provide a basic set of functions to be used by the
|
|
|
756 |
# clearaudit operation.
|
|
|
757 |
#
|
|
|
758 |
# This mode should only be invoked by the program itself
|
|
|
759 |
#
|
|
|
760 |
#
|
|
|
761 |
# Inputs :
|
|
|
762 |
#
|
|
|
763 |
# Returns :
|
|
|
764 |
#
|
|
|
765 |
sub audit_operation
|
|
|
766 |
{
|
|
|
767 |
my $result;
|
|
|
768 |
Verbose ( "AUDIT Operation: $datafile, $opt_audit_entry" );
|
|
|
769 |
|
|
|
770 |
#
|
|
|
771 |
# Read in the config file(s)
|
|
|
772 |
# This will ensure that all the relevent config files are noted by audit
|
|
|
773 |
#
|
|
|
774 |
# Do not perform any sanity test. This will have been done by the wrapper
|
|
|
775 |
# invocation.
|
|
|
776 |
#
|
|
|
777 |
read_config_file( $datafile );
|
|
|
778 |
|
|
|
779 |
#
|
|
|
780 |
# Rewrite the build.pl file
|
|
|
781 |
#
|
|
|
782 |
rewrite_build_file( $opt_audit_entry );
|
|
|
783 |
|
|
|
784 |
my $mode = "";
|
|
|
785 |
$mode = "--expert" if ( $opt_expert );
|
|
|
786 |
|
|
|
787 |
$result = JatsCmd ( "-b $BUILDUSE build $mode" );
|
|
|
788 |
|
|
|
789 |
$mode = "all";
|
|
|
790 |
$mode = "debug package_debug" if ( $opt_quick );
|
|
|
791 |
$result = JatsCmd ( "-b $BUILDUSE make $mode" )
|
|
|
792 |
unless ( $result );
|
|
|
793 |
|
|
|
794 |
#
|
|
|
795 |
# Generate a "derived object" so that the audit has something to track
|
|
|
796 |
# This file is created last to ensure that ALL build activity is captured
|
|
|
797 |
#
|
|
|
798 |
open AUDO, ">$AUDIT_DO" or die "Cannot create audit derived object\n";
|
|
|
799 |
print AUDO "This file is used to create an audit trail - it can be deleted";
|
|
|
800 |
close AUDO;
|
|
|
801 |
|
|
|
802 |
Verbose ( "AUDIT Operation Result: $result" );
|
|
|
803 |
exit $result;
|
|
|
804 |
}
|
|
|
805 |
|
|
|
806 |
#-------------------------------------------------------------------------------
|
|
|
807 |
# Function : SystemLog
|
|
|
808 |
#
|
|
|
809 |
# Description : Similar to the System command, except that standard
|
|
|
810 |
# output and standard Error are appended to a log file
|
|
|
811 |
#
|
|
|
812 |
# Used since I was having problems with calling other programs
|
|
|
813 |
# and control-C. It could hang the terminal session.
|
|
|
814 |
#
|
|
|
815 |
# Inputs :
|
|
|
816 |
#
|
|
|
817 |
# Returns :
|
|
|
818 |
#
|
|
|
819 |
sub System
|
|
|
820 |
{
|
|
|
821 |
my( $cmd ) = @_;
|
|
|
822 |
|
|
|
823 |
Verbose2 "... $cmd";
|
|
|
824 |
|
|
|
825 |
if ( $logfile_inuse )
|
|
|
826 |
{
|
|
|
827 |
open(CMD, "$cmd |") || Error "can't run command: $!";
|
|
|
828 |
while (<CMD>)
|
|
|
829 |
{
|
|
|
830 |
print $_;
|
|
|
831 |
}
|
|
|
832 |
close(CMD);
|
|
|
833 |
}
|
|
|
834 |
else
|
|
|
835 |
{
|
|
|
836 |
system( "$cmd" );
|
|
|
837 |
}
|
|
|
838 |
|
|
|
839 |
return $? / 256;
|
|
|
840 |
}
|
|
|
841 |
|
|
|
842 |
#-------------------------------------------------------------------------------
|
|
|
843 |
# Function : JatsCmd
|
|
|
844 |
#
|
|
|
845 |
# Description : Issue a command to JATS.PL
|
|
|
846 |
#
|
|
|
847 |
# Inputs : Command line
|
|
|
848 |
#
|
|
|
849 |
# Returns : Error code
|
|
|
850 |
#
|
|
|
851 |
sub JatsCmd
|
|
|
852 |
{
|
|
|
853 |
Error ("Environment variable GBE_PERL not set") unless ( defined $GBE_PERL );
|
|
|
854 |
Error ("Environment variable GBE_CORE not set") unless ( defined $GBE_CORE );
|
|
|
855 |
|
|
|
856 |
System ( "$GBE_PERL $GBE_CORE/TOOLS/jats.pl @_" );
|
|
|
857 |
}
|
|
|
858 |
|
|
|
859 |
#-------------------------------------------------------------------------------
|
|
|
860 |
# Function : read_config_file
|
|
|
861 |
#
|
|
|
862 |
# Description : Read in the config file and build up data structures
|
|
|
863 |
# Format of the configuration file
|
|
|
864 |
#
|
|
|
865 |
# Comments begin with a # and go the end of the line
|
|
|
866 |
# There are three types of config line
|
|
|
867 |
# LABEL nn.nn.nn.prj
|
|
|
868 |
# Specifies the build label
|
|
|
869 |
# Specifies the 3 letter project name (Mandatory)
|
|
|
870 |
# This value is used to substitute xxx project names
|
|
|
871 |
#
|
|
|
872 |
# ROOTDIR name
|
|
|
873 |
#
|
|
|
874 |
# INLCUDE filename
|
|
|
875 |
#
|
|
|
876 |
# EXTERNAL package version [ALLOW_MULTI]
|
|
|
877 |
# Specifies the version of a package to use
|
|
|
878 |
# The version may be of the form:
|
|
|
879 |
# nn.nn.nn.aaa
|
|
|
880 |
# or
|
|
|
881 |
# nn.nn.nn
|
|
|
882 |
# A project specifier of .mas and .cr are not modified
|
|
|
883 |
# A project specifier of .xxx will be changed to the current project
|
|
|
884 |
#
|
|
|
885 |
# The "ALLOW_MULTI" tag handles the special case where
|
|
|
886 |
# a package may have a project specific version AND a
|
|
|
887 |
# generic MAS version - that are not the same.
|
|
|
888 |
#
|
|
|
889 |
# LinkPkgArchive ('package', 'version' ); [ALLOW_MULTI]
|
|
|
890 |
# BuildPkgArchive ('package', 'version' ); [ALLOW_MULTI]
|
|
|
891 |
# See EXTERNAL
|
|
|
892 |
#
|
|
|
893 |
# MESSAGE text
|
|
|
894 |
# Display the text
|
|
|
895 |
#
|
|
|
896 |
# EXCLUDED text
|
|
|
897 |
# Display the text
|
|
|
898 |
#
|
|
|
899 |
# Otherwise the line is taken to be the path to a
|
|
|
900 |
# $BUILDFILE file that will be part of the build.
|
|
|
901 |
#
|
|
|
902 |
# Inputs : Name of the config file
|
|
|
903 |
# Name of the current file handle - used for recusive calls
|
|
|
904 |
#
|
|
|
905 |
# Returns : Will terminate on error
|
|
|
906 |
#
|
|
|
907 |
sub read_config_file
|
|
|
908 |
{
|
|
|
909 |
my ($datafile, $fh) = @_;
|
|
|
910 |
my $root_found;
|
|
|
911 |
Verbose2 ("Read Config File: $datafile");
|
|
|
912 |
|
|
|
913 |
#
|
|
|
914 |
# Detect too many levels of inclusion
|
|
|
915 |
#
|
|
|
916 |
Error ("Too many levels of include file. Possible circular inclusion")
|
|
|
917 |
if ( $fh > 10 );
|
|
|
918 |
|
|
|
919 |
no strict 'refs';
|
|
|
920 |
$fh++;
|
|
|
921 |
open ( $fh, $datafile ) or Error ("Config file ($datafile) not found" );
|
|
|
922 |
use strict 'refs';
|
|
|
923 |
|
|
|
924 |
while ( <$fh> )
|
|
|
925 |
{
|
|
|
926 |
#
|
|
|
927 |
# Clean up lines
|
|
|
928 |
# Skip comments and blank lines
|
|
|
929 |
# Remove leading and training white space
|
|
|
930 |
#
|
|
|
931 |
chomp;
|
|
|
932 |
s~^\s*~~;
|
|
|
933 |
s~#.*$~~;
|
|
|
934 |
s~\s*$~~;
|
|
|
935 |
next if ( length( $_) <= 0 );
|
|
|
936 |
|
|
|
937 |
Verbose3 ("CFG: " . $_);
|
|
|
938 |
|
|
|
939 |
#
|
|
|
940 |
# LABEL nn.nn.nn.prj
|
|
|
941 |
# Required project label
|
|
|
942 |
# Extract the project suffix from the label
|
|
|
943 |
#
|
|
|
944 |
if ( m/LABEL/ )
|
|
|
945 |
{
|
|
|
946 |
my ($key, $ext) = split( ' ', $_, 2);
|
|
|
947 |
Error ("Multiple LABEL statements not allowed") if ( $build_label );
|
|
|
948 |
Error ("Missing label") unless ( $ext );
|
|
|
949 |
Error ("Bad label format") unless ( $ext =~ m~^\d+\.\d+\.\d+.(\w+)$~ );
|
|
|
950 |
|
|
|
951 |
$project = $1;
|
|
|
952 |
$project_keep{$project} = $project;
|
|
|
953 |
|
|
|
954 |
$label = $ext;
|
|
|
955 |
$build_label="daf_build_$label";
|
|
|
956 |
|
|
|
957 |
Verbose ("Label: $label, $build_label, Project: $project");
|
|
|
958 |
next;
|
|
|
959 |
}
|
|
|
960 |
|
|
|
961 |
#
|
|
|
962 |
# ROOTDIR name
|
|
|
963 |
# Specify the name of the project root directory
|
|
|
964 |
# This MUST be a parent directory
|
|
|
965 |
#
|
|
|
966 |
if ( m/^ROOTDIR/ )
|
|
|
967 |
{
|
|
|
968 |
my ($key, $dir_name) = split( ' ', $_, 2);
|
|
|
969 |
Error ("Multiple ROOTDIR statements not allowed") if ( $root_found );
|
|
|
970 |
Error ("Missing root directory name") unless ( $dir_name );
|
|
|
971 |
|
|
|
972 |
#
|
|
|
973 |
# Locate the root directory within the current file tree
|
|
|
974 |
#
|
|
|
975 |
Error ("ROOTDIR not in CWD. $dir_name not in $cwd") unless ( $cwd =~ m~/$dir_name~ );
|
|
|
976 |
|
|
|
977 |
$root_dir = substr( $cwd, 0, $+[0] );
|
|
|
978 |
$root_found = 1;
|
|
|
979 |
Verbose ("ROOTDIR: $root_dir");
|
|
|
980 |
next;
|
|
|
981 |
}
|
|
|
982 |
|
|
|
983 |
#
|
|
|
984 |
# INCLUDE config_file
|
|
|
985 |
# Include another configuration file
|
|
|
986 |
#
|
|
|
987 |
# The included confg file must reside in the same directory as the
|
|
|
988 |
# current config file
|
|
|
989 |
#
|
|
|
990 |
if ( m/^INCLUDE/ )
|
|
|
991 |
{
|
|
|
992 |
my ($key, $ifile) = split( ' ', $_, 2);
|
|
|
993 |
Error ("No include file specified") unless ( $ifile );
|
|
|
994 |
|
|
|
995 |
#
|
|
|
996 |
# Extract the path from the current config file
|
|
|
997 |
#
|
|
|
998 |
( my $path = $datafile ) =~ s~/[^/]+$~~;
|
|
|
999 |
my $cfile = $path . '/' . $ifile;
|
|
|
1000 |
|
|
|
1001 |
Error ("Include file not found: $cfile") unless ( -f $cfile );
|
|
|
1002 |
Verbose ("INCLUDE: $fh, $cfile");
|
|
|
1003 |
read_config_file ( $cfile, $fh );
|
|
|
1004 |
next;
|
|
|
1005 |
}
|
|
|
1006 |
|
|
|
1007 |
#
|
|
|
1008 |
# MESSAGE Text
|
|
|
1009 |
# Display message
|
|
|
1010 |
#
|
|
|
1011 |
if ( m/^MESSAGE/ )
|
|
|
1012 |
{
|
|
|
1013 |
my ($key, $ext) = split( ' ', $_, 2);
|
|
|
1014 |
print $ext . "\n";
|
|
|
1015 |
next;
|
|
|
1016 |
}
|
|
|
1017 |
|
|
|
1018 |
#
|
|
|
1019 |
# EXCLUDE dirname
|
|
|
1020 |
# Allows a config line to be ignored and displayed
|
|
|
1021 |
#
|
|
|
1022 |
if ( m/^EXCLUDE/ )
|
|
|
1023 |
{
|
|
|
1024 |
my ($key, $ext) = split( ' ', $_, 2);
|
|
|
1025 |
print "EXCLUDED: " . $ext . "\n";
|
|
|
1026 |
next;
|
|
|
1027 |
}
|
|
|
1028 |
|
|
|
1029 |
#
|
|
|
1030 |
# EXTERNAL
|
|
|
1031 |
# Defines external packages AND the version of such packages
|
|
|
1032 |
#
|
|
|
1033 |
if ( m/^EXTERNAL/ )
|
|
|
1034 |
{
|
|
|
1035 |
my ( $key, $comp, $ver, $opt ) = split( ' ', $_, 4);
|
|
|
1036 |
Error ("Version not specified for: $comp") unless ( $ver );
|
|
|
1037 |
Error ("Bad version format for: $comp ($ver)") unless ( $ver =~ m~^\d+\.\d+\.\d+.\w+$~ || $ver =~ m~^\d+\.\d+\.\d+$~ );
|
|
|
1038 |
Error ("Invalid options: $comp($opt)") if ( $opt && ($opt ne "ALLOW_MULTI" ));
|
|
|
1039 |
if ( $opt eq "ALLOW_MULTI" )
|
|
|
1040 |
{
|
|
|
1041 |
#
|
|
|
1042 |
# Some special components are allowed to have mutliple
|
|
|
1043 |
# versions. These are a gross kludge and are handled with great care
|
|
|
1044 |
#
|
|
|
1045 |
# Split out the vesrion into two parts
|
|
|
1046 |
#
|
|
|
1047 |
(my $suff = $ver) =~ s~^\d+\.\d+\.\d+.~~;
|
|
|
1048 |
(my $vnum = $ver) =~ s~.\w+$~~;
|
|
|
1049 |
Error ("Bad format for ALLOW_MULTI. Suffix($suff) must be present") unless ( length($suff) > 2 );
|
|
|
1050 |
|
|
|
1051 |
$kludge_component{$comp}{$suff} = $vnum;
|
|
|
1052 |
$external_component{$comp} = $ver;
|
|
|
1053 |
Verbose ("MULTI package: $comp, $vnum, $suff");
|
|
|
1054 |
next;
|
|
|
1055 |
}
|
|
|
1056 |
|
|
|
1057 |
Error ("Multiple definition of $comp") if defined $external_component{$comp};
|
|
|
1058 |
|
|
|
1059 |
#
|
|
|
1060 |
# Save the data
|
|
|
1061 |
#
|
|
|
1062 |
$external_component{$comp} = $ver;
|
|
|
1063 |
Verbose ("Package: $comp, $ver");
|
|
|
1064 |
next;
|
|
|
1065 |
}
|
|
|
1066 |
|
|
|
1067 |
#
|
|
|
1068 |
# Process LinkPkgArchive and BuildPkgArchive statements
|
|
|
1069 |
# These allow simple updating of the config file from Release manager
|
|
|
1070 |
#
|
|
|
1071 |
if ( m/LinkPkgArchive/ or m/BuildPkgArchive/ )
|
|
|
1072 |
{
|
|
|
1073 |
my $comp;
|
|
|
1074 |
my $ver;
|
|
|
1075 |
|
|
|
1076 |
m/'(.*)'[^']*'(.*)'/;
|
|
|
1077 |
|
|
|
1078 |
my $comp = $1;
|
|
|
1079 |
my $ver = $2;
|
|
|
1080 |
|
|
|
1081 |
m/;(.*)/;
|
|
|
1082 |
my $opt = $1;
|
|
|
1083 |
$opt =~ s~^\s*~~;
|
|
|
1084 |
$opt =~ s~\s*$~~;
|
|
|
1085 |
#print "Got Archive stuff: $_ : $comp, $ver : \"$opt\"\n";
|
|
|
1086 |
|
|
|
1087 |
Error ("Version not specified for: $comp") unless ( $ver );
|
|
|
1088 |
Error ("Bad version format for: $comp ($ver)") unless ( $ver =~ m~^\d+\.\d+\.\d+.\w+$~ || $ver =~ m~^\d+\.\d+\.\d+$~ );
|
|
|
1089 |
Error ("Invalid options: $comp($opt)") if ( $opt && ($opt ne "ALLOW_MULTI" ));
|
|
|
1090 |
if ( $opt eq "ALLOW_MULTI" )
|
|
|
1091 |
{
|
|
|
1092 |
#
|
|
|
1093 |
# Some special components are allowed to have mutliple
|
|
|
1094 |
# versions. These are a gross kludge and are handled
|
|
|
1095 |
# with great care
|
|
|
1096 |
#
|
|
|
1097 |
# Split out the vesrion into two parts
|
|
|
1098 |
#
|
|
|
1099 |
#print "Process MULTI\n";
|
|
|
1100 |
(my $suff = $ver) =~ s~^\d+\.\d+\.\d+.~~;
|
|
|
1101 |
(my $vnum = $ver) =~ s~.\w+$~~;
|
|
|
1102 |
Error "Bad format for ALLOW_MULTI. Suffix($suff) must be present" unless ( length($suff) > 2 );
|
|
|
1103 |
|
|
|
1104 |
$kludge_component{$comp}{$suff} = $vnum;
|
|
|
1105 |
$external_component{$comp} = $ver;
|
|
|
1106 |
Verbose "MULTI package: $comp, $vnum, $suff";
|
|
|
1107 |
next;
|
|
|
1108 |
}
|
|
|
1109 |
|
|
|
1110 |
|
|
|
1111 |
Error "Multiple definition of $comp" if defined $external_component{$comp};
|
|
|
1112 |
|
|
|
1113 |
#
|
|
|
1114 |
# Save the data
|
|
|
1115 |
#
|
|
|
1116 |
$external_component{$comp} = $ver;
|
|
|
1117 |
Verbose "Package: $comp, $ver";
|
|
|
1118 |
next;
|
|
|
1119 |
}
|
|
|
1120 |
|
|
|
1121 |
|
|
|
1122 |
#
|
|
|
1123 |
# SET var string
|
|
|
1124 |
# Set and export an environment variable
|
|
|
1125 |
# Primarilry used to setup GBE_PLATFORM and GBE_BUILDFILTER
|
|
|
1126 |
#
|
|
|
1127 |
if ( m/^SET/ )
|
|
|
1128 |
{
|
|
|
1129 |
my ($key, $var, $val) = split( ' ', $_, 3);
|
|
|
1130 |
Error ("SET has missing parameters") unless ( $var );
|
|
|
1131 |
|
|
|
1132 |
$ENV{$var} = $val;
|
|
|
1133 |
Verbose ("Set: $var, $val");
|
|
|
1134 |
next;
|
|
|
1135 |
}
|
|
|
1136 |
|
|
|
1137 |
#
|
|
|
1138 |
# Default
|
|
|
1139 |
# Save the line as the path to a $BUILDFILE file to be included
|
|
|
1140 |
#
|
|
|
1141 |
|
|
|
1142 |
push @modules, $_;
|
|
|
1143 |
}
|
|
|
1144 |
close ($fh);
|
|
|
1145 |
}
|
|
|
1146 |
|
|
|
1147 |
|
|
|
1148 |
#-------------------------------------------------------------------------------
|
|
|
1149 |
# Function : build_module
|
|
|
1150 |
#
|
|
|
1151 |
# Description : Build one module
|
|
|
1152 |
#
|
|
|
1153 |
# Inputs : The path to the module to build
|
|
|
1154 |
#
|
|
|
1155 |
sub build_module
|
|
|
1156 |
{
|
|
|
1157 |
my ($module) = @_;
|
|
|
1158 |
my $dir = "$root_dir/$module";
|
|
|
1159 |
my $exit_string;
|
|
|
1160 |
my $result = 0;
|
|
|
1161 |
|
|
|
1162 |
|
|
|
1163 |
#
|
|
|
1164 |
# A nice header in the log file
|
|
|
1165 |
#
|
|
|
1166 |
print "=" x 40 . " " . localtime() . " " . "=" x 40;
|
|
|
1167 |
print "\nModule: $module\n";
|
|
|
1168 |
|
|
|
1169 |
printf OLDOUT "%-50s %-30s", $module, $dir_to_name{$module};
|
|
|
1170 |
chdir ($dir);
|
|
|
1171 |
|
|
|
1172 |
#
|
|
|
1173 |
# If the module conatins a pkg directory and that directory is also
|
|
|
1174 |
# in the local dpkg_archive, then skip this module
|
|
|
1175 |
#
|
|
|
1176 |
# The following check assumes that the package name is the same
|
|
|
1177 |
# as the modules BuildName.
|
|
|
1178 |
#
|
|
|
1179 |
# It does not check the contents simply, that the target exists
|
|
|
1180 |
#
|
|
|
1181 |
if ( $opt_skip
|
|
|
1182 |
&& -d $root_dir ."/local_dpkg_archive/" . $dir_to_name{$module}
|
|
|
1183 |
&& $build_this ne "$module" )
|
|
|
1184 |
# if ( $opt_skip && -d "$dir/pkg" )
|
|
|
1185 |
{
|
|
|
1186 |
my $pkg_name = qx( ls $dir/pkg );
|
|
|
1187 |
chomp( $pkg_name );
|
|
|
1188 |
Verbose "pkg name: $pkg_name";
|
|
|
1189 |
$exit_string = "Skipped - Pkg Found"
|
|
|
1190 |
if ( -d "$root_dir/local_dpkg_archive/$pkg_name" );
|
|
|
1191 |
}
|
|
|
1192 |
|
|
|
1193 |
unless ( $exit_string )
|
|
|
1194 |
{
|
|
|
1195 |
rm_dir ("$dir/pkg" );
|
|
|
1196 |
rewrite_build_file( $module );
|
|
|
1197 |
|
|
|
1198 |
if ( $opt_audit )
|
|
|
1199 |
{
|
|
|
1200 |
#
|
|
|
1201 |
# Audit the build
|
|
|
1202 |
# Refer to comments in "audit_operation"
|
|
|
1203 |
#
|
|
|
1204 |
is_in_vob();
|
|
|
1205 |
$result = System ("clearaudit /c perl $0 -AUDITMODE=$module @audit_args" );
|
|
|
1206 |
System ("cleartool catcr -element -type fdl -long $AUDIT_DO > $AUDIT_LOG" );
|
|
|
1207 |
System ("cat $AUDIT_LOG" );
|
|
|
1208 |
System ("cat $AUDIT_LOG >> $audit_logfile" );
|
|
|
1209 |
System ("rm -f $AUDIT_DO");
|
|
|
1210 |
}
|
|
|
1211 |
else
|
|
|
1212 |
{
|
|
|
1213 |
#
|
|
|
1214 |
# Build the component
|
|
|
1215 |
#
|
|
|
1216 |
my $mode = "";
|
|
|
1217 |
$mode = "--expert" if ( $opt_expert );
|
|
|
1218 |
|
|
|
1219 |
$result = JatsCmd ( "-b $BUILDUSE build $mode" );
|
|
|
1220 |
|
|
|
1221 |
$mode = "all";
|
|
|
1222 |
$mode = "debug package_debug" if ( $opt_quick );
|
|
|
1223 |
$result = JatsCmd ( "-b $BUILDUSE make $mode" )
|
|
|
1224 |
unless ( $result );
|
|
|
1225 |
|
|
|
1226 |
}
|
|
|
1227 |
|
|
|
1228 |
$result = JatsCmd ( "-b $BUILDUSE install" )
|
|
|
1229 |
unless ( $result );
|
|
|
1230 |
|
|
|
1231 |
$exit_string = "Package did not build and compile"
|
|
|
1232 |
if ( $result );
|
|
|
1233 |
}
|
|
|
1234 |
|
|
|
1235 |
#
|
|
|
1236 |
# Double check that the package installed
|
|
|
1237 |
#
|
|
|
1238 |
unless ( $exit_string )
|
|
|
1239 |
{
|
|
|
1240 |
if ( -d "$dir/pkg" )
|
|
|
1241 |
{
|
|
|
1242 |
my $pkg_name = qx( ls $dir/pkg );
|
|
|
1243 |
chomp( $pkg_name );
|
|
|
1244 |
|
|
|
1245 |
unless ( -d "$root_dir/local_dpkg_archive/$pkg_name" )
|
|
|
1246 |
{
|
|
|
1247 |
$exit_string = "Package not transferred";
|
|
|
1248 |
$result = 1;
|
|
|
1249 |
}
|
|
|
1250 |
|
|
|
1251 |
unless ( $dir_to_name{$module} eq $pkg_name )
|
|
|
1252 |
{
|
|
|
1253 |
$exit_string = "OK, but package name should be:$dir_to_name{$module} ";
|
|
|
1254 |
}
|
|
|
1255 |
}
|
|
|
1256 |
else
|
|
|
1257 |
{
|
|
|
1258 |
$exit_string = "Package not found";
|
|
|
1259 |
$result = 1;
|
|
|
1260 |
}
|
|
|
1261 |
}
|
|
|
1262 |
|
|
|
1263 |
$exit_string = "OK" unless ( $exit_string );
|
|
|
1264 |
print OLDOUT "$exit_string\n";
|
|
|
1265 |
Verbose "build_module: Exit code: $result";
|
|
|
1266 |
|
|
|
1267 |
#
|
|
|
1268 |
# A nice footer in the log file
|
|
|
1269 |
#
|
|
|
1270 |
printf ("\nEnd Module: %s Name: %s\n", scalar( gmtime()), $module );
|
|
|
1271 |
|
|
|
1272 |
return $result;
|
|
|
1273 |
}
|
|
|
1274 |
|
|
|
1275 |
#-------------------------------------------------------------------------------
|
|
|
1276 |
# Function : install_package
|
|
|
1277 |
#
|
|
|
1278 |
# Description : Install packages into dpkg_archive
|
|
|
1279 |
# This should only be done IFF all modules have been built
|
|
|
1280 |
#
|
|
|
1281 |
# Inputs :
|
|
|
1282 |
#
|
|
|
1283 |
# Returns :
|
|
|
1284 |
#
|
|
|
1285 |
sub install_package
|
|
|
1286 |
{
|
|
|
1287 |
my ($module) = @_;
|
|
|
1288 |
my $dir = "$root_dir/$module";
|
|
|
1289 |
my $result = 0;
|
|
|
1290 |
|
|
|
1291 |
|
|
|
1292 |
printf "Install Package: %-50s %-30s\n", $module, $dir_to_name{$module};
|
|
|
1293 |
chdir ($dir);
|
|
|
1294 |
|
|
|
1295 |
$result = JatsCmd ( "-b $BUILDUSE create_dpkg -o" );
|
|
|
1296 |
|
|
|
1297 |
return $result;
|
|
|
1298 |
}
|
|
|
1299 |
|
|
|
1300 |
#-------------------------------------------------------------------------------
|
|
|
1301 |
# Function : has_label
|
|
|
1302 |
#
|
|
|
1303 |
# Description : Determine if a file has a clearcase label
|
|
|
1304 |
#
|
|
|
1305 |
# Inputs : Name of the file
|
|
|
1306 |
# Label
|
|
|
1307 |
#
|
|
|
1308 |
# Returns : True if it has the label
|
|
|
1309 |
#
|
|
|
1310 |
|
|
|
1311 |
sub has_label
|
|
|
1312 |
{
|
|
|
1313 |
my( $file, $label ) = @_;
|
|
|
1314 |
|
|
|
1315 |
my $data = qx( cleartool describe -fmt %Nl $file );
|
|
|
1316 |
for (split ' ', $data)
|
|
|
1317 |
{
|
|
|
1318 |
return 1
|
|
|
1319 |
if ( /$label/ );
|
|
|
1320 |
}
|
|
|
1321 |
return 0;
|
|
|
1322 |
}
|
|
|
1323 |
|
|
|
1324 |
#-------------------------------------------------------------------------------
|
|
|
1325 |
# Function : is_checked_out
|
|
|
1326 |
#
|
|
|
1327 |
# Description : Determine if a file has been checked out
|
|
|
1328 |
#
|
|
|
1329 |
# Inputs : $file
|
|
|
1330 |
#
|
|
|
1331 |
# Returns : True if checked out
|
|
|
1332 |
#
|
|
|
1333 |
sub is_checked_out
|
|
|
1334 |
{
|
|
|
1335 |
my( $file ) = @_;
|
|
|
1336 |
my $data = qx( cleartool describe -fmt %f $file );
|
|
|
1337 |
Verbose ("is_checked_out:$data\n");
|
|
|
1338 |
return 1
|
|
|
1339 |
if ( length ($data) > 0 );
|
|
|
1340 |
return 0;
|
|
|
1341 |
}
|
|
|
1342 |
|
|
|
1343 |
#-------------------------------------------------------------------------------
|
|
|
1344 |
# Function : is_dynamic_view
|
|
|
1345 |
#
|
|
|
1346 |
# Description : Determine if the current clearcase view is dynamic
|
|
|
1347 |
#
|
|
|
1348 |
# Inputs :
|
|
|
1349 |
#
|
|
|
1350 |
# Returns : True if it is a Dynamic View
|
|
|
1351 |
#
|
|
|
1352 |
sub is_dynamic_view
|
|
|
1353 |
{
|
|
|
1354 |
my $data = qx( cleartool lsview -cview );
|
|
|
1355 |
Verbose ("is_dynamic_view:$data\n");
|
|
|
1356 |
return 1
|
|
|
1357 |
if ( $data =~ m~^\*~ );
|
|
|
1358 |
return 0;
|
|
|
1359 |
}
|
|
|
1360 |
|
|
|
1361 |
#-------------------------------------------------------------------------------
|
|
|
1362 |
# Function : is_in_vob
|
|
|
1363 |
#
|
|
|
1364 |
# Description : Determine if the current directory is with a VOB
|
|
|
1365 |
# clearaudit will generate an error if the CWD is not within
|
|
|
1366 |
# a knwon VOB.
|
|
|
1367 |
#
|
|
|
1368 |
# This can be caused by the case of the name of the current
|
|
|
1369 |
# directory. Windows is not case sensitive, but clearaudit is.
|
|
|
1370 |
#
|
|
|
1371 |
# Inputs :
|
|
|
1372 |
#
|
|
|
1373 |
# Returns :
|
|
|
1374 |
#
|
|
|
1375 |
sub is_in_vob
|
|
|
1376 |
{
|
|
|
1377 |
my $data = qx( cleartool ls . );
|
|
|
1378 |
|
|
|
1379 |
if ( $? / 256 )
|
|
|
1380 |
{
|
|
|
1381 |
my $cwd = getcwd();
|
|
|
1382 |
Error ("Directory $cwd is not within a ClearCase VOB.\n",
|
|
|
1383 |
"Possible problems:\n",
|
|
|
1384 |
" The directory is under version control\n",
|
|
|
1385 |
" The case of the directory does not match that stored within the VOB\n",
|
|
|
1386 |
);
|
|
|
1387 |
}
|
|
|
1388 |
}
|
|
|
1389 |
|
|
|
1390 |
#-------------------------------------------------------------------------------
|
|
|
1391 |
# Function : clearcase_rule
|
|
|
1392 |
#
|
|
|
1393 |
# Description : Return a string that is the clearcase rule used to conatin
|
|
|
1394 |
# the component.
|
|
|
1395 |
#
|
|
|
1396 |
# Use the ../.. directory.
|
|
|
1397 |
#
|
|
|
1398 |
# Inputs : Directory
|
|
|
1399 |
#
|
|
|
1400 |
# Returns :
|
|
|
1401 |
#
|
|
|
1402 |
#
|
|
|
1403 |
sub cleacase_rule
|
|
|
1404 |
{
|
|
|
1405 |
(my $base) = @_;
|
|
|
1406 |
|
|
|
1407 |
$base =~ s~/[^/]+$~~;
|
|
|
1408 |
$base =~ s~/[^/]+$~~;
|
|
|
1409 |
$base = "$root_dir/$base";
|
|
|
1410 |
|
|
|
1411 |
my $data = qx(cleartool ls -d $base);
|
|
|
1412 |
|
|
|
1413 |
$data =~ m~([^\s]+$)~;
|
|
|
1414 |
my $rule = $1;
|
|
|
1415 |
|
|
|
1416 |
return $rule;
|
|
|
1417 |
}
|
|
|
1418 |
|
|
|
1419 |
|
|
|
1420 |
#-------------------------------------------------------------------------------
|
|
|
1421 |
# Function : determine_build_order
|
|
|
1422 |
#
|
|
|
1423 |
# Description : This function will determine the build order of all of
|
|
|
1424 |
# the component modules
|
|
|
1425 |
#
|
|
|
1426 |
# This routine also sets up some important data structures
|
|
|
1427 |
# and supports the creation of a subset of the modules.
|
|
|
1428 |
#
|
|
|
1429 |
# Inputs : None
|
|
|
1430 |
#
|
|
|
1431 |
# Returns :
|
|
|
1432 |
#
|
|
|
1433 |
sub determine_build_order
|
|
|
1434 |
{
|
|
|
1435 |
my %src;
|
|
|
1436 |
my @build_order;
|
|
|
1437 |
my %opt_list;
|
|
|
1438 |
my %component;
|
|
|
1439 |
|
|
|
1440 |
for my $module (@modules)
|
|
|
1441 |
{
|
|
|
1442 |
my $file = "$root_dir/$module/$BUILDFILE";
|
|
|
1443 |
Verbose2 "Now Processing File: $file";
|
|
|
1444 |
open (FILE, "<$file" ) or Error "Can't open the file: $file\n";
|
|
|
1445 |
while (<FILE>)
|
|
|
1446 |
{
|
|
|
1447 |
if ( m/^BuildName\s/)
|
|
|
1448 |
{
|
|
|
1449 |
|
|
|
1450 |
m/'([^\s]*)\s+(.*)'/;
|
|
|
1451 |
my $build_name = $1;
|
|
|
1452 |
$src{$module}{'name'} = $build_name;
|
|
|
1453 |
|
|
|
1454 |
$component{$build_name} = $module;
|
|
|
1455 |
$dir_to_name{$module} = $build_name;
|
|
|
1456 |
|
|
|
1457 |
$internal{$build_name} = $module
|
|
|
1458 |
unless ( defined $external_component{$build_name} );
|
|
|
1459 |
|
|
|
1460 |
Verbose2 " BuildName: $build_name";
|
|
|
1461 |
}
|
|
|
1462 |
|
|
|
1463 |
if ( m/^LinkPkgArchive/ || m/^BuildPkgArchive/ )
|
|
|
1464 |
{
|
|
|
1465 |
chomp;
|
|
|
1466 |
m/'(.*)'[^']*'(.*)'/;
|
|
|
1467 |
# print "$_ : $1 :: $2\n";
|
|
|
1468 |
|
|
|
1469 |
#
|
|
|
1470 |
# Only interested in the non-external components
|
|
|
1471 |
# These are components not encountered in the config file
|
|
|
1472 |
# We can't build external components, but should be able to build
|
|
|
1473 |
# all others.
|
|
|
1474 |
#
|
|
|
1475 |
my $comp = $1;
|
|
|
1476 |
my $ver = $2;
|
|
|
1477 |
if ( defined $external_component{$comp} )
|
|
|
1478 |
{
|
|
|
1479 |
$src{$module}{'external'}{$comp} = $ver;
|
|
|
1480 |
Verbose2 " External: $comp : $ver";
|
|
|
1481 |
next;
|
|
|
1482 |
}
|
|
|
1483 |
|
|
|
1484 |
$src{$module}{'depend'}{$comp} = $ver;
|
|
|
1485 |
# Stuffs %internal !! $internal{$comp} = $module;
|
|
|
1486 |
# Verbose2 " Internal: $comp : $module, $ver";
|
|
|
1487 |
}
|
|
|
1488 |
}
|
|
|
1489 |
close FILE;
|
|
|
1490 |
}
|
|
|
1491 |
|
|
|
1492 |
#
|
|
|
1493 |
# Build only the component in the current directory
|
|
|
1494 |
# Add the component to the list to build
|
|
|
1495 |
#
|
|
|
1496 |
if ( $build_this )
|
|
|
1497 |
{
|
|
|
1498 |
push @opt_only, $dir_to_name{$build_this};
|
|
|
1499 |
Verbose2 "Build this: $build_this\n";
|
|
|
1500 |
}
|
|
|
1501 |
|
|
|
1502 |
#
|
|
|
1503 |
# If the user has requested that a single package be built then
|
|
|
1504 |
# create a hash of the prerequiste packages to limit the
|
|
|
1505 |
# algorithm to these packages
|
|
|
1506 |
#
|
|
|
1507 |
if ( $#opt_only >= 0 )
|
|
|
1508 |
{
|
|
|
1509 |
my @examine;
|
|
|
1510 |
|
|
|
1511 |
for (@opt_only)
|
|
|
1512 |
{
|
|
|
1513 |
Error ("Specified package not found: $_")
|
|
|
1514 |
if ( ! defined $component{$_} );
|
|
|
1515 |
|
|
|
1516 |
#
|
|
|
1517 |
# Add user specified components to the list
|
|
|
1518 |
#
|
|
|
1519 |
Verbose2 "Specified user package: $_\n";
|
|
|
1520 |
$opt_list{$_} = 1;
|
|
|
1521 |
push @examine, keys (%{$src{$component{$_}}{'depend'}} )
|
|
|
1522 |
if ( $opt_only_prereq );
|
|
|
1523 |
}
|
|
|
1524 |
|
|
|
1525 |
while ( $#examine >= 0)
|
|
|
1526 |
{
|
|
|
1527 |
my $file = pop @examine;
|
|
|
1528 |
Verbose2 "NEED: $file ; $component{$file}\n";
|
|
|
1529 |
unless ( $opt_list{$file} )
|
|
|
1530 |
{
|
|
|
1531 |
$opt_list{$file} = 1;
|
|
|
1532 |
push @examine, keys %{$src{$component{$file}}{'depend'}};
|
|
|
1533 |
}
|
|
|
1534 |
}
|
|
|
1535 |
}
|
|
|
1536 |
|
|
|
1537 |
#
|
|
|
1538 |
# Dump all the modules dependency information
|
|
|
1539 |
#
|
|
|
1540 |
if ( $opt_dump_all || $opt_dump )
|
|
|
1541 |
{
|
|
|
1542 |
$opt_build = 0;
|
|
|
1543 |
|
|
|
1544 |
sub pscan
|
|
|
1545 |
{
|
|
|
1546 |
my ( $ptr, $ptrbase, $comp ) = @_;
|
|
|
1547 |
for ( sort keys %{$src{$internal{$comp}}{'depend'}} )
|
|
|
1548 |
{
|
|
|
1549 |
$ptr->{$_}++
|
|
|
1550 |
unless( $ptrbase->{$_} );
|
|
|
1551 |
pscan ($ptr, $ptrbase, $_ );
|
|
|
1552 |
}
|
|
|
1553 |
}
|
|
|
1554 |
|
|
|
1555 |
for my $file (sort keys %src)
|
|
|
1556 |
{
|
|
|
1557 |
my %base_dep;
|
|
|
1558 |
for ( sort keys %{$src{$file}{'depend'}} )
|
|
|
1559 |
{
|
|
|
1560 |
$base_dep{$_}++;
|
|
|
1561 |
}
|
|
|
1562 |
|
|
|
1563 |
#
|
|
|
1564 |
# Determine complete list of all dependants other than those in the
|
|
|
1565 |
# top level.
|
|
|
1566 |
#
|
|
|
1567 |
my %full_dep = ();
|
|
|
1568 |
for ( keys %base_dep )
|
|
|
1569 |
{
|
|
|
1570 |
pscan (\%full_dep, \%base_dep , $_ );
|
|
|
1571 |
}
|
|
|
1572 |
|
|
|
1573 |
#
|
|
|
1574 |
# Print it all out
|
|
|
1575 |
#
|
|
|
1576 |
print "Component: $src{$file}{'name'} in ${file} requires:\n";
|
|
|
1577 |
for ( sort keys %base_dep )
|
|
|
1578 |
{
|
|
|
1579 |
print " $_\n";
|
|
|
1580 |
}
|
|
|
1581 |
|
|
|
1582 |
if ( $opt_dump > 1 )
|
|
|
1583 |
{
|
|
|
1584 |
for ( sort keys %full_dep )
|
|
|
1585 |
{
|
|
|
1586 |
print " + $_\n";
|
|
|
1587 |
}
|
|
|
1588 |
}
|
|
|
1589 |
|
|
|
1590 |
|
|
|
1591 |
if ( $opt_dump_all )
|
|
|
1592 |
{
|
|
|
1593 |
for ( sort keys %{$src{$file}{'external'}} )
|
|
|
1594 |
{
|
|
|
1595 |
print " $_/$src{$file}{'external'}{$_}\n";
|
|
|
1596 |
}
|
|
|
1597 |
}
|
|
|
1598 |
}
|
|
|
1599 |
# print Dumper( \%src, \%internal );
|
|
|
1600 |
}
|
|
|
1601 |
|
|
|
1602 |
#
|
|
|
1603 |
# Determine the order in which modules must be built
|
|
|
1604 |
# This is done by:
|
|
|
1605 |
# Determine ALL modules that don't have a dependency
|
|
|
1606 |
# Remove all discovered dependencies from ALL modules
|
|
|
1607 |
# Repeat, until no more dependencies are discovered
|
|
|
1608 |
#
|
|
|
1609 |
|
|
|
1610 |
my $go = 1;
|
|
|
1611 |
while ( $go)
|
|
|
1612 |
{
|
|
|
1613 |
#
|
|
|
1614 |
# Append those entries that don't have any dependencies
|
|
|
1615 |
#
|
|
|
1616 |
my @dep_list;
|
|
|
1617 |
for my $file (sort keys %src)
|
|
|
1618 |
{
|
|
|
1619 |
next if ( $src{$file}{'done'} );
|
|
|
1620 |
|
|
|
1621 |
my $num_dep = keys %{$src{$file}{'depend'}};
|
|
|
1622 |
if ( ! $num_dep )
|
|
|
1623 |
{
|
|
|
1624 |
my $module = $src{$file}{'name'};
|
|
|
1625 |
Verbose3 "BuildOrder: $file : $module";
|
|
|
1626 |
push @dep_list, $module;
|
|
|
1627 |
$src{$file}{'done'} = 1;
|
|
|
1628 |
|
|
|
1629 |
push @build_order, $file
|
|
|
1630 |
unless ( ($#opt_only >= 0 ) && ! $opt_list{$module} );
|
|
|
1631 |
}
|
|
|
1632 |
}
|
|
|
1633 |
|
|
|
1634 |
#
|
|
|
1635 |
# Remove all of the discovered dependencies
|
|
|
1636 |
#
|
|
|
1637 |
my $mod;
|
|
|
1638 |
$go = 0;
|
|
|
1639 |
for my $file (sort keys %src)
|
|
|
1640 |
{
|
|
|
1641 |
for $mod (@dep_list)
|
|
|
1642 |
{
|
|
|
1643 |
$go =1;
|
|
|
1644 |
if ( exists ($src{$file}{'depend'}{$mod}) )
|
|
|
1645 |
{
|
|
|
1646 |
$src{$file}{'discovered'}{$mod} = $src{$file}{'depend'}{$mod};
|
|
|
1647 |
delete $src{$file}{'depend'}{$mod};
|
|
|
1648 |
}
|
|
|
1649 |
}
|
|
|
1650 |
}
|
|
|
1651 |
}
|
|
|
1652 |
|
|
|
1653 |
#
|
|
|
1654 |
# Ensure that there is nothing left to build
|
|
|
1655 |
#
|
|
|
1656 |
for my $file (sort keys %src)
|
|
|
1657 |
{
|
|
|
1658 |
my $num_dep = keys %{$src{$file}{'depend'}};
|
|
|
1659 |
if ( $num_dep )
|
|
|
1660 |
{
|
|
|
1661 |
printf "CANNOT BUILD: %s(%s). Missing: %s\n", $file, $src{$file}{'name'}, join ' ' ,sort (keys %{$src{$file}{'depend'}});
|
|
|
1662 |
}
|
|
|
1663 |
}
|
|
|
1664 |
|
|
|
1665 |
#
|
|
|
1666 |
# Return the ordered list of components to build
|
|
|
1667 |
#
|
|
|
1668 |
return @modules
|
|
|
1669 |
if ( $opt_buildfiles );
|
|
|
1670 |
|
|
|
1671 |
return @build_order;
|
|
|
1672 |
}
|
|
|
1673 |
|
|
|
1674 |
#-------------------------------------------------------------------------------
|
|
|
1675 |
# Function : label_all_files
|
|
|
1676 |
#
|
|
|
1677 |
# Description : Label all files in the view
|
|
|
1678 |
#
|
|
|
1679 |
# Inputs :
|
|
|
1680 |
#
|
|
|
1681 |
# Returns :
|
|
|
1682 |
#
|
|
|
1683 |
sub label_all_files
|
|
|
1684 |
{
|
|
|
1685 |
my $result;
|
|
|
1686 |
print "Label all files in the view with: $build_label\n";
|
|
|
1687 |
$result = System ("cleartool mklabel -rec $build_label $root_dir");
|
|
|
1688 |
if ( $result )
|
|
|
1689 |
{
|
|
|
1690 |
print "WARNING: Error reported by the labeling program";
|
|
|
1691 |
}
|
|
|
1692 |
}
|
|
|
1693 |
|
|
|
1694 |
|
|
|
1695 |
#-------------------------------------------------------------------------------
|
|
|
1696 |
# Function : rewrite_build_file
|
|
|
1697 |
#
|
|
|
1698 |
# Description : Use a set of re-write rules to update directives within
|
|
|
1699 |
# the $BUILDFILE file. Creates a $BUILDUSE file
|
|
|
1700 |
#
|
|
|
1701 |
# Inputs : Directory of the target $BUILDFILE file
|
|
|
1702 |
#
|
|
|
1703 |
# Returns : 0 - all is well, file not modified
|
|
|
1704 |
# 1 - all is well, file was modified
|
|
|
1705 |
#
|
|
|
1706 |
#
|
|
|
1707 |
sub rewrite_build_file
|
|
|
1708 |
{
|
|
|
1709 |
my ( $dir ) = @_;
|
|
|
1710 |
my $modified = 0;
|
|
|
1711 |
|
|
|
1712 |
my $infile = "$root_dir/$dir/$BUILDFILE";
|
|
|
1713 |
my $ofile = "$root_dir/$dir/$BUILDUSE";
|
|
|
1714 |
|
|
|
1715 |
#
|
|
|
1716 |
# Adutit mode is special
|
|
|
1717 |
# Ensure that ALL files read by this function are audited
|
|
|
1718 |
# Do not delete or re-write the output file as we don't have enough
|
|
|
1719 |
# information to do this
|
|
|
1720 |
#
|
|
|
1721 |
if ( $opt_audit_entry )
|
|
|
1722 |
{
|
|
|
1723 |
open ( INFILE, "<$infile" ) || Error "Rewrite: Cannot open $infile\n";
|
|
|
1724 |
my $dummy = readline( INFILE );
|
|
|
1725 |
close (INFILE );
|
|
|
1726 |
return;
|
|
|
1727 |
}
|
|
|
1728 |
|
|
|
1729 |
|
|
|
1730 |
#
|
|
|
1731 |
# Unlink any OLD output file
|
|
|
1732 |
#
|
|
|
1733 |
unlink $ofile;
|
|
|
1734 |
|
|
|
1735 |
#
|
|
|
1736 |
# Open the input and output files
|
|
|
1737 |
#
|
|
|
1738 |
open ( INFILE, "<$infile" ) || Error "Rewrite: Cannot open $infile\n";
|
|
|
1739 |
open ( OUTFILE, ">$ofile" ) || Error "Rewrite: Cannot open $ofile\n";
|
|
|
1740 |
|
|
|
1741 |
my $build_name = "UNKNOWN";
|
|
|
1742 |
my $build_version;
|
|
|
1743 |
|
|
|
1744 |
my $release_name;
|
|
|
1745 |
my $release_version;
|
|
|
1746 |
|
|
|
1747 |
print "\nRewrite: $infile\n";
|
|
|
1748 |
while ( <INFILE> )
|
|
|
1749 |
{
|
|
|
1750 |
next if ( m~^\s*#~ ); # Skip comments
|
|
|
1751 |
|
|
|
1752 |
#
|
|
|
1753 |
# Process BuildName
|
|
|
1754 |
#
|
|
|
1755 |
if ( m~\s*BuildName[\s\(]~ )
|
|
|
1756 |
{
|
|
|
1757 |
m/'([^\s]+)\s+(.*)'/;
|
|
|
1758 |
$build_name = $1;
|
|
|
1759 |
$build_version = $2;
|
|
|
1760 |
|
|
|
1761 |
#
|
|
|
1762 |
# Ensure that we have a valid name
|
|
|
1763 |
#
|
|
|
1764 |
my $new_ver;
|
|
|
1765 |
my $message;
|
|
|
1766 |
|
|
|
1767 |
unless (is_known($build_name))
|
|
|
1768 |
{
|
|
|
1769 |
$message = " Error: BuildName not known";
|
|
|
1770 |
$new_ver = $build_version;
|
|
|
1771 |
}
|
|
|
1772 |
else
|
|
|
1773 |
{
|
|
|
1774 |
#
|
|
|
1775 |
# Process the current line
|
|
|
1776 |
#
|
|
|
1777 |
$new_ver = version_to_project ( $build_name, "current" );
|
|
|
1778 |
|
|
|
1779 |
#
|
|
|
1780 |
# The version bit needs a space in it
|
|
|
1781 |
#
|
|
|
1782 |
$new_ver =~ s~\.(\w+)$~ $1~;
|
|
|
1783 |
|
|
|
1784 |
s/'(.*)\s+(.*)'/'$build_name $new_ver'/;
|
|
|
1785 |
}
|
|
|
1786 |
print_update( $build_name ,$build_version, $new_ver, $message );
|
|
|
1787 |
$modified = 1
|
|
|
1788 |
if ( $build_version ne $new_ver );
|
|
|
1789 |
|
|
|
1790 |
|
|
|
1791 |
}
|
|
|
1792 |
|
|
|
1793 |
#
|
|
|
1794 |
# Process BuildReleaseFile
|
|
|
1795 |
#
|
|
|
1796 |
if ( m~\s*BuildReleaseFile[\s\(]~ )
|
|
|
1797 |
{
|
|
|
1798 |
m/'(.*)\s(.*)'/;
|
|
|
1799 |
$release_name = $1;
|
|
|
1800 |
$release_version = $2;
|
|
|
1801 |
|
|
|
1802 |
my $new_ver;
|
|
|
1803 |
my $message;
|
|
|
1804 |
|
|
|
1805 |
unless (is_known($build_name))
|
|
|
1806 |
{
|
|
|
1807 |
$message = " Error: BuildName not known";
|
|
|
1808 |
$new_ver = $release_version;
|
|
|
1809 |
}
|
|
|
1810 |
else
|
|
|
1811 |
{
|
|
|
1812 |
|
|
|
1813 |
#
|
|
|
1814 |
# Process the current line
|
|
|
1815 |
#
|
|
|
1816 |
$new_ver = version_to_project ( $build_name, "current" );
|
|
|
1817 |
s/'(.*)\s(.*)'/'$build_name $new_ver'/;
|
|
|
1818 |
}
|
|
|
1819 |
|
|
|
1820 |
print_update ($release_name ,$release_version, $new_ver, $message );
|
|
|
1821 |
$modified = 1
|
|
|
1822 |
if ( $release_version ne $new_ver );
|
|
|
1823 |
}
|
|
|
1824 |
|
|
|
1825 |
#
|
|
|
1826 |
# Process BuildPkgArchive and LinkPkgArchive
|
|
|
1827 |
# Must take care to handle project and non-project extensions
|
|
|
1828 |
# ie: version 12.12.12.mas needs to be replaced with 13.13.13.mas
|
|
|
1829 |
# and 12.12.12.syd needs to be replaced with 13.13.13.syd
|
|
|
1830 |
# for the SAME component.
|
|
|
1831 |
#
|
|
|
1832 |
#
|
|
|
1833 |
if ( m/^LinkPkgArchive/ or m/^BuildPkgArchive/ )
|
|
|
1834 |
{
|
|
|
1835 |
my $comp;
|
|
|
1836 |
my $ver;
|
|
|
1837 |
my $new_ver;
|
|
|
1838 |
my $message;
|
|
|
1839 |
|
|
|
1840 |
m/'(.*)'[^']*'(.*)'/;
|
|
|
1841 |
|
|
|
1842 |
my $comp = $1;
|
|
|
1843 |
my $ver = $2;
|
|
|
1844 |
|
|
|
1845 |
#
|
|
|
1846 |
# Ensure that we have a valid name
|
|
|
1847 |
#
|
|
|
1848 |
unless (is_known($comp))
|
|
|
1849 |
{
|
|
|
1850 |
$message = " ERROR: Name not known: $comp";
|
|
|
1851 |
$new_ver = $ver;
|
|
|
1852 |
|
|
|
1853 |
}
|
|
|
1854 |
else
|
|
|
1855 |
{
|
|
|
1856 |
#
|
|
|
1857 |
# Examine the version part and determine if there is any project
|
|
|
1858 |
# specfic part
|
|
|
1859 |
#
|
|
|
1860 |
$new_ver = version_to_project ( $comp, $ver );
|
|
|
1861 |
|
|
|
1862 |
#
|
|
|
1863 |
# Process the current line
|
|
|
1864 |
#
|
|
|
1865 |
s/'(.*)'([^']*)'(.*)'/'$comp'$2'$new_ver'/;
|
|
|
1866 |
}
|
|
|
1867 |
|
|
|
1868 |
print_update ($comp ,$ver, $new_ver, $message );
|
|
|
1869 |
$modified = 1
|
|
|
1870 |
if ( $ver ne $new_ver );
|
|
|
1871 |
}
|
|
|
1872 |
|
|
|
1873 |
|
|
|
1874 |
}
|
|
|
1875 |
continue
|
|
|
1876 |
{
|
|
|
1877 |
#
|
|
|
1878 |
# Always output the resultant line
|
|
|
1879 |
#
|
|
|
1880 |
print OUTFILE $_;
|
|
|
1881 |
}
|
|
|
1882 |
|
|
|
1883 |
#
|
|
|
1884 |
# Cleanup
|
|
|
1885 |
#
|
|
|
1886 |
close INFILE;
|
|
|
1887 |
close OUTFILE;
|
|
|
1888 |
|
|
|
1889 |
return $modified;
|
|
|
1890 |
}
|
|
|
1891 |
|
|
|
1892 |
#-------------------------------------------------------------------------------
|
|
|
1893 |
# Function : is_known
|
|
|
1894 |
#
|
|
|
1895 |
# Description : Determine if this component is known to the program
|
|
|
1896 |
# Internal and external packages are KNOWN
|
|
|
1897 |
# Other packages need to be specified
|
|
|
1898 |
#
|
|
|
1899 |
# Inputs : Component
|
|
|
1900 |
#
|
|
|
1901 |
# Returns :
|
|
|
1902 |
#
|
|
|
1903 |
# is_known
|
|
|
1904 |
sub is_known
|
|
|
1905 |
{
|
|
|
1906 |
my ( $comp ) = @_;
|
|
|
1907 |
|
|
|
1908 |
return 1
|
|
|
1909 |
if ( (defined $external_component{$comp}) || ( defined $internal{$comp} ) );
|
|
|
1910 |
|
|
|
1911 |
return 0;
|
|
|
1912 |
}
|
|
|
1913 |
|
|
|
1914 |
|
|
|
1915 |
#-------------------------------------------------------------------------------
|
|
|
1916 |
# Function : version_to_project
|
|
|
1917 |
#
|
|
|
1918 |
# Description : Take a version string and return a project extension
|
|
|
1919 |
#
|
|
|
1920 |
# Inputs :
|
|
|
1921 |
#
|
|
|
1922 |
# Returns :
|
|
|
1923 |
#
|
|
|
1924 |
sub version_to_project
|
|
|
1925 |
{
|
|
|
1926 |
my ( $comp, $ver ) = @_;
|
|
|
1927 |
my $proj;
|
|
|
1928 |
|
|
|
1929 |
#
|
|
|
1930 |
# Replace Internal components with a single project wide build version
|
|
|
1931 |
#
|
|
|
1932 |
return $label
|
|
|
1933 |
unless ( $external_component{$comp} );
|
|
|
1934 |
|
|
|
1935 |
|
|
|
1936 |
#
|
|
|
1937 |
# The version string may have a trailing project specifier
|
|
|
1938 |
# ie: 12.12.12.mas
|
|
|
1939 |
# Determine the suffix
|
|
|
1940 |
#
|
|
|
1941 |
$proj = $1
|
|
|
1942 |
if ($ver =~ m/\.([^\d]+)$/);
|
|
|
1943 |
|
|
|
1944 |
|
|
|
1945 |
#print " Project: comp=$comp, ver=$ver, proj=$proj,\n";
|
|
|
1946 |
|
|
|
1947 |
#
|
|
|
1948 |
# Some extension need special treatment
|
|
|
1949 |
# "current" - Assume that the TAG is in the component HASH
|
|
|
1950 |
#
|
|
|
1951 |
if ( $ver =~ m/current/ )
|
|
|
1952 |
{
|
|
|
1953 |
$proj = "";
|
|
|
1954 |
}
|
|
|
1955 |
elsif ( $proj )
|
|
|
1956 |
{
|
|
|
1957 |
$proj = $project unless ( $project_keep{$proj} );
|
|
|
1958 |
}
|
|
|
1959 |
$proj = "." . $proj if ( $proj );
|
|
|
1960 |
|
|
|
1961 |
|
|
|
1962 |
my $new_comp;
|
|
|
1963 |
if ( $kludge_component{$comp} )
|
|
|
1964 |
{
|
|
|
1965 |
my $type = "xxx";
|
|
|
1966 |
$type = "mas"
|
|
|
1967 |
if ( $proj =~ m/mas/ );
|
|
|
1968 |
if ( $kludge_component{$comp}{$type} )
|
|
|
1969 |
{
|
|
|
1970 |
$new_comp = $kludge_component{$comp}{$type};
|
|
|
1971 |
}
|
|
|
1972 |
else
|
|
|
1973 |
{
|
|
|
1974 |
$new_comp = $kludge_component{$comp}{$project};
|
|
|
1975 |
}
|
|
|
1976 |
|
|
|
1977 |
}
|
|
|
1978 |
else
|
|
|
1979 |
{
|
|
|
1980 |
$new_comp = $external_component{$comp};
|
|
|
1981 |
}
|
|
|
1982 |
$new_comp =~ s~xxx~$project~;
|
|
|
1983 |
$proj = "" if ( $new_comp =~ m/\.([^\d]+)$/ );
|
|
|
1984 |
|
|
|
1985 |
|
|
|
1986 |
return $new_comp . $proj;
|
|
|
1987 |
|
|
|
1988 |
}
|
|
|
1989 |
|
|
|
1990 |
#-------------------------------------------------------------------------------
|
|
|
1991 |
# Function : print_update
|
|
|
1992 |
#
|
|
|
1993 |
# Description : Generate a display line tracking the changes made
|
|
|
1994 |
#
|
|
|
1995 |
# Inputs :
|
|
|
1996 |
#
|
|
|
1997 |
# Returns :
|
|
|
1998 |
#
|
|
|
1999 |
sub print_update
|
|
|
2000 |
{
|
|
|
2001 |
my ($name, $version, $new_version, $message ) = @_;
|
|
|
2002 |
my $diff = " ";
|
|
|
2003 |
$diff = "*"
|
|
|
2004 |
if ( $version ne $new_version );
|
|
|
2005 |
|
|
|
2006 |
printf "Name : %-25s, Version: %-12s %s-> %-12s %s\n", $name ,$version, $diff, $new_version,$message;
|
|
|
2007 |
}
|
|
|
2008 |
|
|
|
2009 |
#-------------------------------------------------------------------------------
|
|
|
2010 |
# Function : rm_directory
|
|
|
2011 |
#
|
|
|
2012 |
# Description : Cannot rely on the underlying 'rm' command. Many of them
|
|
|
2013 |
# are brain-dead. ie: The one in the JATS BIN.win32 directory
|
|
|
2014 |
#
|
|
|
2015 |
# Inputs :
|
|
|
2016 |
#
|
|
|
2017 |
# Returns :
|
|
|
2018 |
#
|
|
|
2019 |
sub rm_dir
|
|
|
2020 |
{
|
|
|
2021 |
print ("Remove Directory: @_\n");
|
|
|
2022 |
rmtree( @_ , $opt_verbose, 0);
|
|
|
2023 |
}
|
|
|
2024 |
|
|
|
2025 |
#-------------------------------------------------------------------------------
|
|
|
2026 |
# Function : generate_pathlist
|
|
|
2027 |
#
|
|
|
2028 |
# Description :
|
|
|
2029 |
#
|
|
|
2030 |
# Inputs :
|
|
|
2031 |
#
|
|
|
2032 |
# Returns :
|
|
|
2033 |
#
|
|
|
2034 |
sub generate_pathlist
|
|
|
2035 |
{
|
|
|
2036 |
our %cf_info; # Contains Makefile.cfg data
|
|
|
2037 |
our %cf_build_info; # Contains Buildfile.cfg
|
|
|
2038 |
our %cf_filelist; # Contains a hash of other makefiles
|
|
|
2039 |
|
|
|
2040 |
my %mdata; # Hash of collected data
|
|
|
2041 |
|
|
|
2042 |
#-------------------------------------------------------------------------------
|
|
|
2043 |
# Process each module specified and create a data structure that represents
|
|
|
2044 |
# all the relevent information
|
|
|
2045 |
#
|
|
|
2046 |
for my $module ( @modules )
|
|
|
2047 |
{
|
|
|
2048 |
Verbose( "Processing: $module" );
|
|
|
2049 |
|
|
|
2050 |
#
|
|
|
2051 |
# Locate the JATS generated data file
|
|
|
2052 |
# This will be in the "interface" directory, or if this directory does not
|
|
|
2053 |
# exist the file will be found in the current directory
|
|
|
2054 |
#
|
|
|
2055 |
# The data file can be "require"ed directly by Perl. The data will be
|
|
|
2056 |
# conatined with a few cf_xxxx hashes
|
|
|
2057 |
#
|
|
|
2058 |
for (qw(Makefile.cfg Buildfile.cfg))
|
|
|
2059 |
{
|
|
|
2060 |
Verbose( "generate_pathlist: $_" );
|
|
|
2061 |
my $fname = "$root_dir/$module/$_";
|
|
|
2062 |
$fname = "$root_dir/$module/interface/$_" unless ( -f $fname );
|
|
|
2063 |
Error ( "Cannot locate $fname") unless ( -f $fname );
|
|
|
2064 |
require $fname;
|
|
|
2065 |
}
|
|
|
2066 |
|
|
|
2067 |
Error ("Data in Makefile.cfg is not valid" )
|
|
|
2068 |
unless ( keys(%cf_filelist) > 0 );
|
|
|
2069 |
|
|
|
2070 |
#
|
|
|
2071 |
# Process all the Makefile_xx.cfg files
|
|
|
2072 |
#
|
|
|
2073 |
for my $cfg_file ( sort values(%cf_filelist))
|
|
|
2074 |
{
|
|
|
2075 |
Verbose( "generate_pathlist: Processing: $cfg_file" );
|
|
|
2076 |
my $fname = "$root_dir/$module/$cfg_file";
|
|
|
2077 |
$fname = "$root_dir/$module/interface/$cfg_file" unless ( -f $fname );
|
|
|
2078 |
|
|
|
2079 |
#
|
|
|
2080 |
# Simply ignore missing config files
|
|
|
2081 |
#
|
|
|
2082 |
next unless ( -f $fname );
|
|
|
2083 |
require $fname;
|
|
|
2084 |
Verbose( "generate_pathlist: Have data from: $cfg_file" );
|
|
|
2085 |
|
|
|
2086 |
#
|
|
|
2087 |
# All the data is held within %cf_info, which is hashed
|
|
|
2088 |
# by platform
|
|
|
2089 |
#
|
|
|
2090 |
foreach my $key ( sort keys(%cf_info) )
|
|
|
2091 |
{
|
|
|
2092 |
my %dirs;
|
|
|
2093 |
my $pData = \%{$mdata{$key}};
|
|
|
2094 |
|
|
|
2095 |
Verbose( "Processing $cfg_file, PLATFORM: $key" );
|
|
|
2096 |
|
|
|
2097 |
my $pInfo = \%{$cf_info{$key}};
|
|
|
2098 |
|
|
|
2099 |
$pData->{'Platform'} = $pInfo->{'$ScmPlatform'};
|
|
|
2100 |
$pData->{'Product'} = $pInfo->{'$ScmProduct'};
|
|
|
2101 |
$pData->{'Target'} = $pInfo->{'$ScmTarget'};
|
|
|
2102 |
|
|
|
2103 |
for ( @{$pInfo->{'@INCDIRS'}}, @{$pInfo->{'@SRCDIRS'}} )
|
|
|
2104 |
{
|
|
|
2105 |
$dirs{$_}++;
|
|
|
2106 |
}
|
|
|
2107 |
|
|
|
2108 |
push @{$pData->{'dirs'}}, keys (%dirs);
|
|
|
2109 |
}
|
|
|
2110 |
}
|
|
|
2111 |
|
|
|
2112 |
#
|
|
|
2113 |
# Release the memory used by the read data
|
|
|
2114 |
# This will also clear it for next iteration of the loop
|
|
|
2115 |
#
|
|
|
2116 |
%cf_info = ();
|
|
|
2117 |
%cf_build_info = ();
|
|
|
2118 |
}
|
|
|
2119 |
|
|
|
2120 |
#-------------------------------------------------------------------------------
|
|
|
2121 |
# Data has been collected, but it is a bit mixed up.
|
|
|
2122 |
# There are basically two types of modules encountered
|
|
|
2123 |
# 1) Platforms that have a PRODUCT and a TARGET
|
|
|
2124 |
# 2) Simple modules that have a TARGET
|
|
|
2125 |
# These are used by all many modules
|
|
|
2126 |
#
|
|
|
2127 |
# To add to the confusion, some PLATFORM are really simple TARGETS too.
|
|
|
2128 |
# The only difference is that they are not used by anything else
|
|
|
2129 |
#
|
|
|
2130 |
# Make a single pass over the data and MARK entries that are used as targets
|
|
|
2131 |
# Ignore entries where the target and the platform are the same as these are
|
|
|
2132 |
# simple
|
|
|
2133 |
#
|
|
|
2134 |
for my $key ( keys %mdata)
|
|
|
2135 |
{
|
|
|
2136 |
my $target = $mdata{$key}{'Target'};
|
|
|
2137 |
$mdata{$target}{'MARK'}++
|
|
|
2138 |
unless ( $key eq $target );
|
|
|
2139 |
}
|
|
|
2140 |
|
|
|
2141 |
#
|
|
|
2142 |
# Generate complete source directory lists for entries with NO mark
|
|
|
2143 |
# These are the platforms at the top of the food chain, not simply targets
|
|
|
2144 |
# for use by products and platforms.
|
|
|
2145 |
#
|
|
|
2146 |
for my $key ( keys %mdata)
|
|
|
2147 |
{
|
|
|
2148 |
my $pData = \%{$mdata{$key}};
|
|
|
2149 |
|
|
|
2150 |
next if ( $pData->{'MARK'} );
|
|
|
2151 |
Verbose ( "PLATFORM: $key" );
|
|
|
2152 |
|
|
|
2153 |
my $Platform = $pData->{'Platform'};
|
|
|
2154 |
my $Product = $pData->{'Product'};
|
|
|
2155 |
my $Target = $pData->{'Target'};
|
|
|
2156 |
|
|
|
2157 |
#
|
|
|
2158 |
# Generate a list of unique directories
|
|
|
2159 |
#
|
|
|
2160 |
my %dirs;
|
|
|
2161 |
for ( @{$pData->{'dirs'}} )
|
|
|
2162 |
{
|
|
|
2163 |
$dirs{$_}++;
|
|
|
2164 |
}
|
|
|
2165 |
#
|
|
|
2166 |
# Add in the Target directories too
|
|
|
2167 |
#
|
|
|
2168 |
unless ( $Platform eq $Target )
|
|
|
2169 |
{
|
|
|
2170 |
for ( @{$mdata{$Target}{'dirs'}} )
|
|
|
2171 |
{
|
|
|
2172 |
$dirs{$_}++;
|
|
|
2173 |
}
|
|
|
2174 |
}
|
|
|
2175 |
|
|
|
2176 |
#
|
|
|
2177 |
# Generate the output file
|
|
|
2178 |
#
|
|
|
2179 |
my $ofile = "$key.pathlist";
|
|
|
2180 |
my $localtime = localtime();
|
|
|
2181 |
print "Generate pathlist for: $key\n";
|
|
|
2182 |
open ( OFILE, ">$ofile" ) or Error ("Cannot create $ofile");
|
|
|
2183 |
select OFILE;
|
|
|
2184 |
|
|
|
2185 |
print <<EOF;
|
|
|
2186 |
# List of directories specified in the build
|
|
|
2187 |
#
|
|
|
2188 |
# Generated: $localtime
|
|
|
2189 |
#
|
|
|
2190 |
# Platform : $Platform
|
|
|
2191 |
# Product : $Product
|
|
|
2192 |
# Target : $Target
|
|
|
2193 |
#
|
|
|
2194 |
EOF
|
|
|
2195 |
for (sort keys %dirs )
|
|
|
2196 |
{
|
|
|
2197 |
#
|
|
|
2198 |
# Convert / -> \ for Windows
|
|
|
2199 |
# Remove paths with internal names, like: $(OBJDIR)
|
|
|
2200 |
#
|
|
|
2201 |
(my $dirs = $_) =~ s~/~\\~g;
|
|
|
2202 |
print $dirs . "\n"
|
|
|
2203 |
unless ( $dirs =~ m~\$\([A-Z]+\)~ );
|
|
|
2204 |
}
|
|
|
2205 |
|
|
|
2206 |
close OFILE;
|
|
|
2207 |
select STDOUT;
|
|
|
2208 |
}
|
|
|
2209 |
}
|
|
|
2210 |
|
|
|
2211 |
|
|
|
2212 |
#-------------------------------------------------------------------------------
|
|
|
2213 |
# Documentation
|
|
|
2214 |
#
|
|
|
2215 |
|
|
|
2216 |
=pod
|
|
|
2217 |
|
|
|
2218 |
=head1 NAME
|
|
|
2219 |
|
|
|
2220 |
jats_builder - Build a system with multiple build.pl files
|
|
|
2221 |
|
|
|
2222 |
=head1 SYNOPSIS
|
|
|
2223 |
|
|
|
2224 |
perl jats_builder.pl [options]
|
|
|
2225 |
|
|
|
2226 |
Options:
|
|
|
2227 |
-help - brief help message
|
|
|
2228 |
-help -help - Detailed help message
|
|
|
2229 |
-man - Full documentation
|
|
|
2230 |
-config=xxx - Specify config file. Default is build.cfg
|
|
|
2231 |
-clean - Clean out packages. Clean build
|
|
|
2232 |
-only pkg - Build a single package - and possibly all prerequisites.
|
|
|
2233 |
This option can be used multiple times.
|
|
|
2234 |
-resetlog - Restart the logfile
|
|
|
2235 |
-show - Display external modules and the build order
|
|
|
2236 |
-showrule - Display external modules, the build order, and clearcase rule
|
|
|
2237 |
-showpkg - Display external modules as LinkPkgArchive statements
|
|
|
2238 |
-verbose - Verbose operation
|
|
|
2239 |
-updatecache - Ensure all external packages are cached
|
|
|
2240 |
|
|
|
2241 |
-audit - Generate a clearaudit trail of the build
|
|
|
2242 |
-[no]build - Build (default is build)
|
|
|
2243 |
-[no]all - Build all components (default is noall)
|
|
|
2244 |
-[no]expert - Expert mode. Allows build to restart. (default is expert)
|
|
|
2245 |
-[no]log - Use a logfile (default is log)
|
|
|
2246 |
-[no]prereq - Build prerequisites to "only" components. Default
|
|
|
2247 |
-[no]quick - Build only debug packages (default is noquick)
|
|
|
2248 |
-[no]skip - Skip installed packages (default)
|
|
|
2249 |
-create_dpkg - Install packages into dpkg_archive, after all has built
|
|
|
2250 |
|
|
|
2251 |
The following options imply "nobuild"
|
|
|
2252 |
|
|
|
2253 |
-buildfiles - Enables operations only build.pl and build.use.pl
|
|
|
2254 |
-[no]buildfiles_rewrite - Rewrite build.pl (default is no)
|
|
|
2255 |
-[no]buildfiles_checkout - Checkout build.pl if required (default is no)
|
|
|
2256 |
-[no]buildfiles_label - Label build.pl (default is no)
|
|
|
2257 |
-[no]buildfiles_labelall - Label all builder files (default is no)
|
|
|
2258 |
-[no]buildfiles_labelrule - Label all builder files with a rule based label (default is no)
|
|
|
2259 |
|
|
|
2260 |
-dump - Dump component dependency info, except external packages
|
|
|
2261 |
-dump -dump - Dump component dependency info (with sub components), except external packages
|
|
|
2262 |
-dumpall - Dump all component dependency info
|
|
|
2263 |
-labelall - Label all files in the view
|
|
|
2264 |
-pathlist - Generate pathlists for all platforms
|
|
|
2265 |
|
|
|
2266 |
=head1 OPTIONS
|
|
|
2267 |
|
|
|
2268 |
=over 8
|
|
|
2269 |
|
|
|
2270 |
=item B<-help>
|
|
|
2271 |
|
|
|
2272 |
Print a brief help message and exits.
|
|
|
2273 |
|
|
|
2274 |
=item B<-help -help>
|
|
|
2275 |
|
|
|
2276 |
Print a detailed help message with an explanation for each option.
|
|
|
2277 |
|
|
|
2278 |
=item B<-man>
|
|
|
2279 |
|
|
|
2280 |
Prints the manual page and exits.
|
|
|
2281 |
|
|
|
2282 |
|
|
|
2283 |
=item B<-config=file>
|
|
|
2284 |
|
|
|
2285 |
Specify the name of a config file to use. If no configuration file is specified
|
|
|
2286 |
then the program will be use B<build.cfg>. The program will search for the specified
|
|
|
2287 |
config file upwards from the current directory.
|
|
|
2288 |
|
|
|
2289 |
The name of the config file will be used as the basis for the logfile name;
|
|
|
2290 |
any extension is removed and an extension of ".log" will be added.
|
|
|
2291 |
|
|
|
2292 |
The directory in which the config file is found will be used as the basis for
|
|
|
2293 |
the log file.
|
|
|
2294 |
|
|
|
2295 |
=item B<-clean>
|
|
|
2296 |
|
|
|
2297 |
Deletes the local_dpkg_archive directory contents and then cleans and clobbers
|
|
|
2298 |
all the configured components. The logfile is also deleted.
|
|
|
2299 |
|
|
|
2300 |
=item B<-only pkg>
|
|
|
2301 |
|
|
|
2302 |
Will build a single component. This option may be used multiple times to force
|
|
|
2303 |
multiple components to be built.
|
|
|
2304 |
|
|
|
2305 |
If the "-prereq" option is selected, then the prerequisites components will be
|
|
|
2306 |
determined and may be built.
|
|
|
2307 |
|
|
|
2308 |
=item B<-resetlog>
|
|
|
2309 |
|
|
|
2310 |
Deletes the build.log logfile.
|
|
|
2311 |
|
|
|
2312 |
In a full system build the logfile is not deleted be default. This allows the
|
|
|
2313 |
build to be stopped and restarted.
|
|
|
2314 |
|
|
|
2315 |
If a single ( or a list ) of components is being built, then the logfile will
|
|
|
2316 |
always be deleted.
|
|
|
2317 |
|
|
|
2318 |
=item B<-show>
|
|
|
2319 |
|
|
|
2320 |
Display the external and internal components.
|
|
|
2321 |
|
|
|
2322 |
The external components together with their version numbers, in alphabetic order.
|
|
|
2323 |
|
|
|
2324 |
The internal components are displayed in the required build order. When building
|
|
|
2325 |
a selected set of components only the selected components are displayed.
|
|
|
2326 |
|
|
|
2327 |
=item B<-showrule>
|
|
|
2328 |
|
|
|
2329 |
Display the external and internal components. The clearcase selection rule are
|
|
|
2330 |
also shown for the internal components.
|
|
|
2331 |
|
|
|
2332 |
The external components together with their version numbers, in alphabetic order.
|
|
|
2333 |
|
|
|
2334 |
The internal components are displayed in the required build order. When building
|
|
|
2335 |
a selected set of components only the selected components are displayed.
|
|
|
2336 |
|
|
|
2337 |
The clearcase selection rule is taken from the directory two above the build file.
|
|
|
2338 |
This ensures that the rule for the component is used.
|
|
|
2339 |
|
|
|
2340 |
=item B<-showpkg>
|
|
|
2341 |
|
|
|
2342 |
Display the external components as LinkPkgArchive statements.
|
|
|
2343 |
|
|
|
2344 |
This is intended to generate list of external components that can be copied
|
|
|
2345 |
directly into release manager.
|
|
|
2346 |
|
|
|
2347 |
This command will terminate the program. It implies B<-nobuild>.
|
|
|
2348 |
|
|
|
2349 |
=item B<-verbose>
|
|
|
2350 |
|
|
|
2351 |
Increase the level of debugging information displayed. This option may be used
|
|
|
2352 |
multiple times.
|
|
|
2353 |
|
|
|
2354 |
=item B<-updatecache>
|
|
|
2355 |
|
|
|
2356 |
Allows external components are determined and are copied into a local
|
|
|
2357 |
dpkg_archive cache, if present. This will significantly speed up operation if
|
|
|
2358 |
dpkg_archive is on a network drive.
|
|
|
2359 |
|
|
|
2360 |
The local dpkg_archive cache is located by examining the DPKG_ARCHIVE variable
|
|
|
2361 |
for an archive name that contains the word "cache".
|
|
|
2362 |
|
|
|
2363 |
If used once then, packages will be copied into the cache only if not already
|
|
|
2364 |
present. If used more than once, then packages will be refreshed - they
|
|
|
2365 |
will be deleted and copied again.
|
|
|
2366 |
|
|
|
2367 |
=item B<-[no]build>
|
|
|
2368 |
|
|
|
2369 |
The nobuild option will prevent the program from building components.
|
|
|
2370 |
The configuration file will be read and any errors will be reported.
|
|
|
2371 |
|
|
|
2372 |
The default is "build", which will determine the components to be built, the
|
|
|
2373 |
order in which the components should be built and then proceed to build the
|
|
|
2374 |
components.
|
|
|
2375 |
|
|
|
2376 |
=item B<-[no]all>
|
|
|
2377 |
|
|
|
2378 |
Normally the program will build B<all> components only if it is started in the same
|
|
|
2379 |
directory as the configuration file, otherwise it will build the named components
|
|
|
2380 |
or the component found in the current directory.
|
|
|
2381 |
|
|
|
2382 |
The B<all> option will force the program to build all components within
|
|
|
2383 |
the configuration file. The default is "noall".
|
|
|
2384 |
|
|
|
2385 |
=item B<-[no]expert>
|
|
|
2386 |
|
|
|
2387 |
The use of the -expert mode allows the build to be restarted at the point were
|
|
|
2388 |
item had been terminated. The components are not cleaned before being built.
|
|
|
2389 |
|
|
|
2390 |
The default mode is expert.
|
|
|
2391 |
|
|
|
2392 |
=item B<-[no]log>
|
|
|
2393 |
|
|
|
2394 |
Capture and log all the build information to a logfile.
|
|
|
2395 |
|
|
|
2396 |
With nolog the build information is displayed on the screen. This may be useful
|
|
|
2397 |
for debugging.
|
|
|
2398 |
|
|
|
2399 |
=item B<-[no]prereq>
|
|
|
2400 |
|
|
|
2401 |
When building one or more named components the complete list of prerequisites
|
|
|
2402 |
modules will be built.
|
|
|
2403 |
|
|
|
2404 |
The "noprereq" option allows one modules to be built without examination of the
|
|
|
2405 |
prerequisites. This may lead to a build problem unless all the prerequisites can
|
|
|
2406 |
be located.
|
|
|
2407 |
|
|
|
2408 |
=item B<-[no]quick>
|
|
|
2409 |
|
|
|
2410 |
The "quick" option only builds the "debug" version of all the components.
|
|
|
2411 |
|
|
|
2412 |
The, default, "noquick" option builds the "debug" and "production" version of components.
|
|
|
2413 |
|
|
|
2414 |
=item B<-[no]skip>
|
|
|
2415 |
|
|
|
2416 |
By default, a component will not be build if item looks as though item has been
|
|
|
2417 |
built. The "noskip" option suppresses this operation.
|
|
|
2418 |
|
|
|
2419 |
A component is deemed to have been built iff:
|
|
|
2420 |
|
|
|
2421 |
=over 8
|
|
|
2422 |
|
|
|
2423 |
=item 1
|
|
|
2424 |
|
|
|
2425 |
The components "pkg" directory exists
|
|
|
2426 |
|
|
|
2427 |
=item 2
|
|
|
2428 |
|
|
|
2429 |
The component is found in the local dpkg_archive
|
|
|
2430 |
|
|
|
2431 |
=back
|
|
|
2432 |
|
|
|
2433 |
=item B<-audit>
|
|
|
2434 |
|
|
|
2435 |
If B<audit> is enabled then the clearcase audit system will be invoked and an
|
|
|
2436 |
audit log of the files used in the build will be recorded.
|
|
|
2437 |
|
|
|
2438 |
The audit log will be recorded with each built component and a global audit logfile
|
|
|
2439 |
will be created in the root directory.
|
|
|
2440 |
|
|
|
2441 |
=item B<-create_dpkg>
|
|
|
2442 |
|
|
|
2443 |
Install built packages into the main dpkg_archive.
|
|
|
2444 |
|
|
|
2445 |
This operation is performed in conjunction with a build, but only after all the
|
|
|
2446 |
packages have been built sucessfully.
|
|
|
2447 |
|
|
|
2448 |
The installation process is interactive and the output is not logged to a logfile.
|
|
|
2449 |
|
|
|
2450 |
=item B<-buildfiles>
|
|
|
2451 |
|
|
|
2452 |
If this option is present, then the otherwise buildfile options are activated and
|
|
|
2453 |
will the build.pl and p=build.use.pl files may be modified.
|
|
|
2454 |
|
|
|
2455 |
In all cases a file called build.use.pl file will be created.
|
|
|
2456 |
|
|
|
2457 |
The use of this option prevents components being built.
|
|
|
2458 |
|
|
|
2459 |
=item B<-[no]buildfiles_rewrite>
|
|
|
2460 |
|
|
|
2461 |
If -buildfiles is present then this option will allows the build.pl file to be re-written.
|
|
|
2462 |
|
|
|
2463 |
The default operation is to NOT modify the build.pl file, only the build.use.pl.
|
|
|
2464 |
|
|
|
2465 |
=item B<-[no]buildfiles_checkout>
|
|
|
2466 |
|
|
|
2467 |
If -buildfiles is present then this option will instruct the program to checkout the
|
|
|
2468 |
build.pl file, before it is modified. The file is not checked in.
|
|
|
2469 |
|
|
|
2470 |
The default operation is to NOT checkout the build.pl file.
|
|
|
2471 |
|
|
|
2472 |
=item B<-[no]buildfiles_label>
|
|
|
2473 |
|
|
|
2474 |
If -buildfiles is present then this option instructs the program to label the
|
|
|
2475 |
build.pl file.
|
|
|
2476 |
|
|
|
2477 |
The default operation is to NOT label the files.
|
|
|
2478 |
|
|
|
2479 |
=item B<-[no]buildfiles_labelall>
|
|
|
2480 |
|
|
|
2481 |
If -buildfiles is present then this option instructs the program to label the
|
|
|
2482 |
build.pl file as well as : makefile.pl src/makefile.pl and the directories . and ..
|
|
|
2483 |
|
|
|
2484 |
The default operation is to use a label derived from the B<LABEL> directive
|
|
|
2485 |
in the builder configuration file. This is modified if the B<-[no]buildfiles_labelrule>
|
|
|
2486 |
option is specified.
|
|
|
2487 |
|
|
|
2488 |
The default operation is to NOT label the files.
|
|
|
2489 |
|
|
|
2490 |
=item B<-[no]buildfiles_labelrule>
|
|
|
2491 |
|
|
|
2492 |
If -buildfiles is present then this option instructs the program to label the
|
|
|
2493 |
build.pl file as well as : makefile.pl src/makefile.pl and the directories . and ..
|
|
|
2494 |
|
|
|
2495 |
The label that is used is derived from the clearcase rule that loads the parents
|
|
|
2496 |
parents directory. This is the label shown with the B<-showrule> option.
|
|
|
2497 |
|
|
|
2498 |
The default operation is to use a label derived from the B<LABEL> directive
|
|
|
2499 |
in the builder configuration file.
|
|
|
2500 |
|
|
|
2501 |
|
|
|
2502 |
=item B<-dump>
|
|
|
2503 |
|
|
|
2504 |
Dump the the dependency information for all internal components
|
|
|
2505 |
|
|
|
2506 |
When used twice the dump also includes all dependants of the dependants.
|
|
|
2507 |
|
|
|
2508 |
The use of this option prevents components being built.
|
|
|
2509 |
|
|
|
2510 |
=item B<-dumpall>
|
|
|
2511 |
|
|
|
2512 |
Dump the the dependency information for all external and internal components
|
|
|
2513 |
|
|
|
2514 |
The use of this option prevents components being built.
|
|
|
2515 |
|
|
|
2516 |
=item B<-labelall>
|
|
|
2517 |
|
|
|
2518 |
Label all files in the view
|
|
|
2519 |
|
|
|
2520 |
The use of this option prevents components being built.
|
|
|
2521 |
|
|
|
2522 |
=item B<-pathlist>
|
|
|
2523 |
|
|
|
2524 |
This option will generate files for each major platform that contain pathlists
|
|
|
2525 |
for all files used in the compilation. This file is intended to be used by
|
|
|
2526 |
source level debuggers.
|
|
|
2527 |
|
|
|
2528 |
The path information is extracted from information generated by the makefile build
|
|
|
2529 |
operation. The modules not need to be compiled. Conversely only
|
|
|
2530 |
information that is present to the build system will be in the pathlist file.
|
|
|
2531 |
|
|
|
2532 |
Pathlist files are named as F<xxxx.pathlist>.
|
|
|
2533 |
|
|
|
2534 |
=back
|
|
|
2535 |
|
|
|
2536 |
=head1 DESCRIPTION
|
|
|
2537 |
|
|
|
2538 |
B<This program> will build a system containing one or more inter-related build
|
|
|
2539 |
files using the JATS build tools.
|
|
|
2540 |
|
|
|
2541 |
The program also provides a numbers of ancillary function to assist in the
|
|
|
2542 |
maintenance of build systems.
|
|
|
2543 |
|
|
|
2544 |
In normal operation the program will:
|
|
|
2545 |
|
|
|
2546 |
=over 8
|
|
|
2547 |
|
|
|
2548 |
=item *
|
|
|
2549 |
|
|
|
2550 |
Locate a configuration file called F<build.cfg>
|
|
|
2551 |
|
|
|
2552 |
=item *
|
|
|
2553 |
|
|
|
2554 |
Determine the components in the build
|
|
|
2555 |
|
|
|
2556 |
=item *
|
|
|
2557 |
|
|
|
2558 |
Determine the build order of the components
|
|
|
2559 |
|
|
|
2560 |
=item *
|
|
|
2561 |
|
|
|
2562 |
Build and install the components
|
|
|
2563 |
|
|
|
2564 |
=back
|
|
|
2565 |
|
|
|
2566 |
=head1 THE CONFIGURATION FILE
|
|
|
2567 |
|
|
|
2568 |
The configuration provides information essential to the building process. It is
|
|
|
2569 |
located in the root of the build tree and as such determines the root directory
|
|
|
2570 |
for the build. The root directory is used to contain the local dpkg_archive
|
|
|
2571 |
directory and the logfile.
|
|
|
2572 |
|
|
|
2573 |
The configuration file is called F<build.cfg>. It is a simple text file.
|
|
|
2574 |
Comments begin with a "#" and continue to the end of the line. Blank line are
|
|
|
2575 |
ignored.
|
|
|
2576 |
|
|
|
2577 |
The file provides the following information:
|
|
|
2578 |
|
|
|
2579 |
=over 8
|
|
|
2580 |
|
|
|
2581 |
=item *
|
|
|
2582 |
|
|
|
2583 |
The project version number and name.
|
|
|
2584 |
|
|
|
2585 |
=item *
|
|
|
2586 |
|
|
|
2587 |
Location of the project root directory
|
|
|
2588 |
|
|
|
2589 |
=item *
|
|
|
2590 |
|
|
|
2591 |
Other configuration files
|
|
|
2592 |
|
|
|
2593 |
=item *
|
|
|
2594 |
|
|
|
2595 |
A list of external components and required versions
|
|
|
2596 |
|
|
|
2597 |
=item *
|
|
|
2598 |
|
|
|
2599 |
A list of internal components.
|
|
|
2600 |
|
|
|
2601 |
=back
|
|
|
2602 |
|
|
|
2603 |
=head2 Project Version number and name
|
|
|
2604 |
|
|
|
2605 |
A LABEL statement is used to specify the version number of the build as well as
|
|
|
2606 |
the project name. The project name is used to identify project specific options
|
|
|
2607 |
within the build, such as external packages. The label used as a basis for
|
|
|
2608 |
labeling the build files.
|
|
|
2609 |
|
|
|
2610 |
=head3 LABEL directive format
|
|
|
2611 |
|
|
|
2612 |
The format of the label directive is
|
|
|
2613 |
|
|
|
2614 |
=over 8
|
|
|
2615 |
|
|
|
2616 |
=item B<LABEL> C<nn.nn.nn.prj>
|
|
|
2617 |
|
|
|
2618 |
=back
|
|
|
2619 |
|
|
|
2620 |
=head2 Root Directory
|
|
|
2621 |
|
|
|
2622 |
A ROOTDIR statement is used to specify the root of all the internal components.
|
|
|
2623 |
If no ROOTDIR statement is encountered then the root directory is that in which
|
|
|
2624 |
the config file was found.
|
|
|
2625 |
|
|
|
2626 |
The ROOTDIR directory must be within the current path. The config file must be
|
|
|
2627 |
within the file tree at the same level, or below the root directory.
|
|
|
2628 |
|
|
|
2629 |
=head3 ROOTDIR directive format
|
|
|
2630 |
|
|
|
2631 |
The format of the ROOTDIR directive is
|
|
|
2632 |
|
|
|
2633 |
=over 8
|
|
|
2634 |
|
|
|
2635 |
=item B<ROOTDIR> C<dir_name>
|
|
|
2636 |
|
|
|
2637 |
Where C<dir_name> is a simple name. It cannot contain ".", ".." or "/" characters.
|
|
|
2638 |
|
|
|
2639 |
=back
|
|
|
2640 |
|
|
|
2641 |
=head2 Included configuration files
|
|
|
2642 |
|
|
|
2643 |
An INCLUDE statement is used to include another configuration file.
|
|
|
2644 |
|
|
|
2645 |
Configuration files may include a common component, perhaps tools define a core
|
|
|
2646 |
set of external components, or a common label or root directory.
|
|
|
2647 |
|
|
|
2648 |
Included Configuration files may be nested to a depth of 10.
|
|
|
2649 |
|
|
|
2650 |
=head3 INCLUDE directive format
|
|
|
2651 |
|
|
|
2652 |
The format of the INCLUDE directive is
|
|
|
2653 |
|
|
|
2654 |
=over 8
|
|
|
2655 |
|
|
|
2656 |
=item B<INCLUDE> C<file_name>
|
|
|
2657 |
|
|
|
2658 |
Where C<file_name> is the name of a configuration file to be included.
|
|
|
2659 |
|
|
|
2660 |
=back
|
|
|
2661 |
|
|
|
2662 |
|
|
|
2663 |
=head2 External components
|
|
|
2664 |
|
|
|
2665 |
An external component is a component that is not to be built by this program.
|
|
|
2666 |
The component is provided by a package to be found in dpkg_archive.
|
|
|
2667 |
|
|
|
2668 |
Several directives are available to specify external components. These include:
|
|
|
2669 |
|
|
|
2670 |
=over 8
|
|
|
2671 |
|
|
|
2672 |
=item *
|
|
|
2673 |
|
|
|
2674 |
EXTERNAL directive
|
|
|
2675 |
|
|
|
2676 |
=item *
|
|
|
2677 |
|
|
|
2678 |
LinkPkgArchive statements
|
|
|
2679 |
|
|
|
2680 |
=item *
|
|
|
2681 |
|
|
|
2682 |
BuildPkgArchive statements
|
|
|
2683 |
|
|
|
2684 |
=back
|
|
|
2685 |
|
|
|
2686 |
The LinkPkgArchive and BuildPkgArchive statements allows a simple interface to
|
|
|
2687 |
the B<Release Manager> and perform the same job as the EXTERNAL directive.
|
|
|
2688 |
|
|
|
2689 |
=head3 EXTERNAL directive
|
|
|
2690 |
|
|
|
2691 |
The format of the EXTERNAL directive is:
|
|
|
2692 |
|
|
|
2693 |
=over 8
|
|
|
2694 |
|
|
|
2695 |
=item B<EXTERNAL> I<name> I<version> [OPTIONS]
|
|
|
2696 |
|
|
|
2697 |
=back
|
|
|
2698 |
|
|
|
2699 |
Where B<name> is the name of the external package.
|
|
|
2700 |
B<version> is the version of the external package. This may contain a suffix.
|
|
|
2701 |
B<OPTIONS> is an optional option.
|
|
|
2702 |
|
|
|
2703 |
The version may contain a project specific suffix. If this is "xxx" then it will
|
|
|
2704 |
be replaced with the project suffix.
|
|
|
2705 |
|
|
|
2706 |
Available options include:
|
|
|
2707 |
|
|
|
2708 |
=over 8
|
|
|
2709 |
|
|
|
2710 |
=item B<ALLOW_MULTI>
|
|
|
2711 |
|
|
|
2712 |
This option allows multiple packages with the same name, but different version
|
|
|
2713 |
information. This is required to provide correct processing of packages that
|
|
|
2714 |
have a project independent part and a project dependent part, such a
|
|
|
2715 |
C<sysbasetypes>.
|
|
|
2716 |
|
|
|
2717 |
=back
|
|
|
2718 |
|
|
|
2719 |
=head4 EXTERNAL directive example
|
|
|
2720 |
|
|
|
2721 |
BuildPkgArchive ( 'solidbasetypes', '1.0.0.mas' );
|
|
|
2722 |
BuildPkgArchive ( 'sysbasetypes' , '20.0.0.mas' ); ALLOW_MULTI
|
|
|
2723 |
BuildPkgArchive ( 'sysbasetypes' , '20.0.0.syd' ); ALLOW_MULTI
|
|
|
2724 |
BuildPkgArchive ( 'sysswis' , '20.1.0.syd' );
|
|
|
2725 |
EXTERNAL crypta_dsi 20.0.0.cr
|
|
|
2726 |
EXTERNAL crc 1.0.2.cr
|
|
|
2727 |
|
|
|
2728 |
=head2 Internal components
|
|
|
2729 |
|
|
|
2730 |
Internal components are those that can be built by this program. Allows lines in
|
|
|
2731 |
the configuration file that are not another directive will be treated as the
|
|
|
2732 |
specification of an internal component.
|
|
|
2733 |
|
|
|
2734 |
Internal components are specified by the path, from the project root directory
|
|
|
2735 |
to the JATS build.pl file. The order in which the components is specified is
|
|
|
2736 |
B<not> important.
|
|
|
2737 |
|
|
|
2738 |
=head4 Internal component example
|
|
|
2739 |
|
|
|
2740 |
ar/build/jats
|
|
|
2741 |
br/enquiry/build/jats
|
|
|
2742 |
br/farepayment/build/jats
|
|
|
2743 |
br/framework/build/jats
|
|
|
2744 |
|
|
|
2745 |
=head2 Miscellaneous directives
|
|
|
2746 |
|
|
|
2747 |
The configuration file may contain a number of Miscellaneous directives.
|
|
|
2748 |
|
|
|
2749 |
=head3 MESSAGE
|
|
|
2750 |
|
|
|
2751 |
The MESSAGE directive simply displays the remainder of the line.
|
|
|
2752 |
|
|
|
2753 |
=head3 EXCLUDE
|
|
|
2754 |
|
|
|
2755 |
The EXCLUDE directive displays the remainder of the line with the prefix
|
|
|
2756 |
of B<EXCLUDED>. It may be used to indicate that a directive is being suppressed.
|
|
|
2757 |
|
|
|
2758 |
=head1 BUILD OPERATION
|
|
|
2759 |
|
|
|
2760 |
The steps in building a components are detailed in the following sections.
|
|
|
2761 |
|
|
|
2762 |
=head2 Determine if the component needs to be built
|
|
|
2763 |
|
|
|
2764 |
The program will not build a component if it has already been built and
|
|
|
2765 |
installed into the local dpkg_archive, unless the -noskip option is present.
|
|
|
2766 |
|
|
|
2767 |
=head2 Re-write the build.pl file
|
|
|
2768 |
|
|
|
2769 |
The components build.pl file is re-written as build.use.pl. The re-write process
|
|
|
2770 |
will massage the package versions found within the B<BuildName>,
|
|
|
2771 |
B<BuildRelease>, B<LnkPkgArchive> and B<BuildPkgArchive> directives. This file
|
|
|
2772 |
is then used in later operations and is available for manual use by JATS.
|
|
|
2773 |
|
|
|
2774 |
=head2 Generate the JATS makefiles
|
|
|
2775 |
|
|
|
2776 |
Use the re-written build.use.pl file to create the JATS build environment. This will
|
|
|
2777 |
copy into the user sandbox any external components specified with a B<BuildPkgArchive>
|
|
|
2778 |
as well as generate makefiles for (all the required targets.
|
|
|
2779 |
|
|
|
2780 |
=head2 Compile the component
|
|
|
2781 |
|
|
|
2782 |
JATS is used to "make" the component. The B<quick> option allows only the
|
|
|
2783 |
"debug" portions to be created, otherwise both the B<debug> and B<prod>unction portions
|
|
|
2784 |
are made.
|
|
|
2785 |
|
|
|
2786 |
=head2 Install the component
|
|
|
2787 |
|
|
|
2788 |
If the component is successfully built and made, then the resultant package
|
|
|
2789 |
will be installed into a local dpkg_archive for use by otherwise dependent
|
|
|
2790 |
components.
|
|
|
2791 |
|
|
|
2792 |
=cut
|
|
|
2793 |
|