1*cdf0e10cSrcweir: 2*cdf0e10cSrcweireval 'exec perl -wS $0 ${1+"$@"}' 3*cdf0e10cSrcweir if 0; 4*cdf0e10cSrcweir#************************************************************************* 5*cdf0e10cSrcweir# 6*cdf0e10cSrcweir# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7*cdf0e10cSrcweir# 8*cdf0e10cSrcweir# Copyright 2000, 2010 Oracle and/or its affiliates. 9*cdf0e10cSrcweir# 10*cdf0e10cSrcweir# OpenOffice.org - a multi-platform office productivity suite 11*cdf0e10cSrcweir# 12*cdf0e10cSrcweir# This file is part of OpenOffice.org. 13*cdf0e10cSrcweir# 14*cdf0e10cSrcweir# OpenOffice.org is free software: you can redistribute it and/or modify 15*cdf0e10cSrcweir# it under the terms of the GNU Lesser General Public License version 3 16*cdf0e10cSrcweir# only, as published by the Free Software Foundation. 17*cdf0e10cSrcweir# 18*cdf0e10cSrcweir# OpenOffice.org is distributed in the hope that it will be useful, 19*cdf0e10cSrcweir# but WITHOUT ANY WARRANTY; without even the implied warranty of 20*cdf0e10cSrcweir# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21*cdf0e10cSrcweir# GNU Lesser General Public License version 3 for more details 22*cdf0e10cSrcweir# (a copy is included in the LICENSE file that accompanied this code). 23*cdf0e10cSrcweir# 24*cdf0e10cSrcweir# You should have received a copy of the GNU Lesser General Public License 25*cdf0e10cSrcweir# version 3 along with OpenOffice.org. If not, see 26*cdf0e10cSrcweir# <http://www.openoffice.org/license.html> 27*cdf0e10cSrcweir# for a copy of the LGPLv3 License. 28*cdf0e10cSrcweir# 29*cdf0e10cSrcweir#************************************************************************* 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir# 32*cdf0e10cSrcweir# deliver.pl - copy from module output tree to solver 33*cdf0e10cSrcweir# 34*cdf0e10cSrcweir 35*cdf0e10cSrcweiruse Cwd; 36*cdf0e10cSrcweiruse File::Basename; 37*cdf0e10cSrcweiruse File::Copy; 38*cdf0e10cSrcweiruse File::DosGlob 'glob'; 39*cdf0e10cSrcweiruse File::Path; 40*cdf0e10cSrcweiruse File::Spec; 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir#### script id ##### 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir( $script_name = $0 ) =~ s/^.*\b(\w+)\.pl$/$1/; 45*cdf0e10cSrcweir 46*cdf0e10cSrcweir$id_str = ' $Revision: 275594 $ '; 47*cdf0e10cSrcweir$id_str =~ /Revision:\s+(\S+)\s+\$/ 48*cdf0e10cSrcweir ? ($script_rev = $1) : ($script_rev = "-"); 49*cdf0e10cSrcweir 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir#### globals #### 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir### valid actions ### 54*cdf0e10cSrcweir# if you add a action 'foo', than add 'foo' to this list and 55*cdf0e10cSrcweir# implement 'do_foo()' in the implemented actions area 56*cdf0e10cSrcweir@action_list = ( # valid actions 57*cdf0e10cSrcweir 'copy', 58*cdf0e10cSrcweir 'dos', 59*cdf0e10cSrcweir 'addincpath', 60*cdf0e10cSrcweir 'linklib', 61*cdf0e10cSrcweir 'mkdir', 62*cdf0e10cSrcweir 'symlink', 63*cdf0e10cSrcweir 'touch' 64*cdf0e10cSrcweir ); 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir# copy filter: files matching these patterns won't be copied by 67*cdf0e10cSrcweir# the copy action 68*cdf0e10cSrcweir@copy_filter_patterns = ( 69*cdf0e10cSrcweir ); 70*cdf0e10cSrcweir 71*cdf0e10cSrcweir$strip = ''; 72*cdf0e10cSrcweir$is_debug = 0; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir$error = 0; 75*cdf0e10cSrcweir$module = 0; # module name 76*cdf0e10cSrcweir$repository = 0; # parent directory of this module 77*cdf0e10cSrcweir$base_dir = 0; # path to module base directory 78*cdf0e10cSrcweir$dlst_file = 0; # path to d.lst 79*cdf0e10cSrcweir$ilst_ext = 'ilst'; # extension of image lists 80*cdf0e10cSrcweir$umask = 22; # default file/directory creation mask 81*cdf0e10cSrcweir$dest = 0; # optional destination path 82*cdf0e10cSrcweir$common_build = 0; # do we have common trees? 83*cdf0e10cSrcweir$common_dest = 0; # common tree on solver 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir@action_data = (); # LoL with all action data 86*cdf0e10cSrcweir@macros = (); # d.lst macros 87*cdf0e10cSrcweir@addincpath_list = (); # files which have to be filtered through addincpath 88*cdf0e10cSrcweir@dirlist = (); # List of 'mkdir' targets 89*cdf0e10cSrcweir@zip_list = (); # files which have to be zipped 90*cdf0e10cSrcweir@common_zip_list = (); # common files which have to be zipped 91*cdf0e10cSrcweir@log_list = (); # LoL for logging all copy and link actions 92*cdf0e10cSrcweir@common_log_list = (); # LoL for logging all copy and link actions in common_dest 93*cdf0e10cSrcweir$logfiledate = 0; # Make log file as old as newest delivered file 94*cdf0e10cSrcweir$commonlogfiledate = 0; # Make log file as old as newest delivered file 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir$files_copied = 0; # statistics 97*cdf0e10cSrcweir$files_unchanged = 0; # statistics 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir$opt_force = 0; # option force copy 100*cdf0e10cSrcweir$opt_check = 0; # do actually execute any action 101*cdf0e10cSrcweir$opt_zip = 0; # create an additional zip file 102*cdf0e10cSrcweir$opt_silent = 0; # be silent, only report errors 103*cdf0e10cSrcweir$opt_verbose = 0; # be verbose (former default behaviour) 104*cdf0e10cSrcweir$opt_log = 1; # create an additional log file 105*cdf0e10cSrcweir$opt_link = 0; # hard link files into the solver to save disk space 106*cdf0e10cSrcweir$opt_deloutput = 0; # delete the output tree for the project once successfully delivered 107*cdf0e10cSrcweir$opt_checkdlst = 0; 108*cdf0e10cSrcweir$delete_common = 1; # for "-delete": if defined delete files from common tree also 109*cdf0e10cSrcweir 110*cdf0e10cSrcweirif ($^O ne 'cygwin') { # iz59477 - cygwin needes a dot "." at the end of filenames to disable 111*cdf0e10cSrcweir $maybedot = ''; # some .exe transformation magic. 112*cdf0e10cSrcweir} else { 113*cdf0e10cSrcweir my $cygvernum = `uname -r`; 114*cdf0e10cSrcweir my @cygvernum = split( /\./, $cygvernum); 115*cdf0e10cSrcweir $cygvernum = shift @cygvernum; 116*cdf0e10cSrcweir $cygvernum .= shift @cygvernum; 117*cdf0e10cSrcweir if ( $cygvernum < 17 ) { 118*cdf0e10cSrcweir $maybedot = '.'; 119*cdf0e10cSrcweir } else { 120*cdf0e10cSrcweir $maybedot = ''; # no longer works with cygwin 1.7. other magic below. 121*cdf0e10cSrcweir } 122*cdf0e10cSrcweir} 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir($gui = lc($ENV{GUI})) || die "Can't determine 'GUI'. Please set environment.\n"; 125*cdf0e10cSrcweir$tempcounter = 0; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir# zip is default for RE master builds 128*cdf0e10cSrcweir$opt_zip = 1 if ( defined($ENV{DELIVER_TO_ZIP}) && uc($ENV{DELIVER_TO_ZIP}) eq 'TRUE' && ! defined($ENV{CWS_WORK_STAMP})); 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir$has_symlinks = 0; # system supports symlinks 131*cdf0e10cSrcweir 132*cdf0e10cSrcweirfor (@action_list) { 133*cdf0e10cSrcweir $action_hash{$_}++; 134*cdf0e10cSrcweir} 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir# trap normal signals (HUP, INT, PIPE, TERM) 137*cdf0e10cSrcweir# for clean up on unexpected termination 138*cdf0e10cSrcweiruse sigtrap 'handler' => \&cleanup_and_die, 'normal-signals'; 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir#### main #### 141*cdf0e10cSrcweir 142*cdf0e10cSrcweirparse_options(); 143*cdf0e10cSrcweir 144*cdf0e10cSrcweirprint "$script_name -- version: $script_rev\n" if !$opt_silent; 145*cdf0e10cSrcweir 146*cdf0e10cSrcweirif ( ! $opt_delete ) { 147*cdf0e10cSrcweir if ( $ENV{GUI} eq 'WNT' ) { 148*cdf0e10cSrcweir if ($ENV{COM} eq 'GCC') { 149*cdf0e10cSrcweir initialize_strip() ; 150*cdf0e10cSrcweir }; 151*cdf0e10cSrcweir } else { 152*cdf0e10cSrcweir initialize_strip(); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir} 155*cdf0e10cSrcweir 156*cdf0e10cSrcweirinit_globals(); 157*cdf0e10cSrcweirpush_default_actions(); 158*cdf0e10cSrcweirparse_dlst(); 159*cdf0e10cSrcweircheck_dlst() if $opt_checkdlst; 160*cdf0e10cSrcweirwalk_action_data(); 161*cdf0e10cSrcweirwalk_addincpath_list(); 162*cdf0e10cSrcweirwrite_log() if $opt_log; 163*cdf0e10cSrcweirzip_files() if $opt_zip; 164*cdf0e10cSrcweircleanup() if $opt_delete; 165*cdf0e10cSrcweirdelete_output() if $opt_deloutput; 166*cdf0e10cSrcweirprint_stats(); 167*cdf0e10cSrcweir 168*cdf0e10cSrcweirexit($error); 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir#### implemented actions ##### 171*cdf0e10cSrcweir 172*cdf0e10cSrcweirsub do_copy 173*cdf0e10cSrcweir{ 174*cdf0e10cSrcweir # We need to copy two times: 175*cdf0e10cSrcweir # from the platform dependent output tree 176*cdf0e10cSrcweir # and from the common output tree 177*cdf0e10cSrcweir my ($dependent, $common, $from, $to, $file_list); 178*cdf0e10cSrcweir my $line = shift; 179*cdf0e10cSrcweir my $touch = 0; 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir $dependent = expand_macros($line); 182*cdf0e10cSrcweir ($from, $to) = split(' ', $dependent); 183*cdf0e10cSrcweir print "copy dependent: from: $from, to: $to\n" if $is_debug; 184*cdf0e10cSrcweir glob_and_copy($from, $to, $touch); 185*cdf0e10cSrcweir 186*cdf0e10cSrcweir if ($delete_common && $common_build && ( $line !~ /%COMMON_OUTDIR%/ ) ) { 187*cdf0e10cSrcweir $line =~ s/%__SRC%/%COMMON_OUTDIR%/ig; 188*cdf0e10cSrcweir if ( $line =~ /%COMMON_OUTDIR%/ ) { 189*cdf0e10cSrcweir $line =~ s/%_DEST%/%COMMON_DEST%/ig; 190*cdf0e10cSrcweir $common = expand_macros($line); 191*cdf0e10cSrcweir ($from, $to) = split(' ', $common); 192*cdf0e10cSrcweir print "copy common: from: $from, to: $to\n" if $is_debug; 193*cdf0e10cSrcweir glob_and_copy($from, $to, $touch); 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir} 197*cdf0e10cSrcweir 198*cdf0e10cSrcweirsub do_dos 199*cdf0e10cSrcweir{ 200*cdf0e10cSrcweir my $line = shift; 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir my $command = expand_macros($line); 203*cdf0e10cSrcweir if ( $opt_check ) { 204*cdf0e10cSrcweir print "DOS: $command\n"; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir else { 207*cdf0e10cSrcweir # HACK: remove MACOSX stuff which is wrongly labled with dos 208*cdf0e10cSrcweir # better: fix broken d.lst 209*cdf0e10cSrcweir return if ( $command =~ /MACOSX/ ); 210*cdf0e10cSrcweir $command =~ s#/#\\#g if $^O eq 'MSWin32'; 211*cdf0e10cSrcweir system($command); 212*cdf0e10cSrcweir } 213*cdf0e10cSrcweir} 214*cdf0e10cSrcweir 215*cdf0e10cSrcweirsub do_addincpath 216*cdf0e10cSrcweir{ 217*cdf0e10cSrcweir # just collect all addincpath files, actual filtering is done later 218*cdf0e10cSrcweir my $line = shift; 219*cdf0e10cSrcweir my ($from, $to); 220*cdf0e10cSrcweir my @globbed_files = (); 221*cdf0e10cSrcweir 222*cdf0e10cSrcweir $line = expand_macros($line); 223*cdf0e10cSrcweir ($from, $to) = split(' ', $line); 224*cdf0e10cSrcweir 225*cdf0e10cSrcweir push( @addincpath_list, @{glob_line($from, $to)}); 226*cdf0e10cSrcweir} 227*cdf0e10cSrcweir 228*cdf0e10cSrcweirsub do_linklib 229*cdf0e10cSrcweir{ 230*cdf0e10cSrcweir my ($lib_base, $lib_major,$from_dir, $to_dir); 231*cdf0e10cSrcweir my $lib = shift; 232*cdf0e10cSrcweir my @globbed_files = (); 233*cdf0e10cSrcweir my %globbed_hash = (); 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir print "linklib: $lib\n" if $is_debug; 236*cdf0e10cSrcweir print "has symlinks\n" if ( $has_symlinks && $is_debug ); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir return unless $has_symlinks; 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir $from_dir = expand_macros('../%__SRC%/lib'); 241*cdf0e10cSrcweir $to_dir = expand_macros('%_DEST%/lib%_EXT%'); 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir @globbed_files = glob("$from_dir/$lib"); 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir if ( $#globbed_files == -1 ) { 246*cdf0e10cSrcweir return; 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir foreach $lib (@globbed_files) { 250*cdf0e10cSrcweir $lib = basename($lib); 251*cdf0e10cSrcweir if ( $lib =~ /^(lib\S+(\.so|\.dylib))\.(\d+)\.(\d+)(\.(\d+))?$/ 252*cdf0e10cSrcweir || $lib =~ /^(lib\S+(\.so|\.dylib))\.(\d+)$/ ) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir push(@{$globbed_hash{$1}}, $lib); 255*cdf0e10cSrcweir } 256*cdf0e10cSrcweir else { 257*cdf0e10cSrcweir print_warning("invalid library name: $lib"); 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir foreach $lib_base ( sort keys %globbed_hash ) { 262*cdf0e10cSrcweir $lib = get_latest_patchlevel(@{$globbed_hash{$lib_base}}); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir if ( $lib =~ /^(lib\S+(\.so|\.dylib))\.(\d+)\.(\d+)(\.(\d+))?$/ ) 265*cdf0e10cSrcweir { 266*cdf0e10cSrcweir $lib_major = "$lib_base.$3"; 267*cdf0e10cSrcweir $long = 1; 268*cdf0e10cSrcweir } 269*cdf0e10cSrcweir else 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir # $lib =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)$/; 272*cdf0e10cSrcweir $long = 0; 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir if ( $opt_check ) { 276*cdf0e10cSrcweir if ( $opt_delete ) { 277*cdf0e10cSrcweir print "REMOVE: $to_dir/$lib_major\n" if $long; 278*cdf0e10cSrcweir print "REMOVE: $to_dir/$lib_base\n"; 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir else { 281*cdf0e10cSrcweir print "LINKLIB: $to_dir/$lib -> $to_dir/$lib_major\n" if $long; 282*cdf0e10cSrcweir print "LINKLIB: $to_dir/$lib -> $to_dir/$lib_base\n"; 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir else { 286*cdf0e10cSrcweir if ( $opt_delete ) { 287*cdf0e10cSrcweir print "REMOVE: $to_dir/$lib_major\n" if ($long && $opt_verbose); 288*cdf0e10cSrcweir print "REMOVE: $to_dir/$lib_base\n" if $opt_verbose; 289*cdf0e10cSrcweir unlink "$to_dir/$lib_major" if $long; 290*cdf0e10cSrcweir unlink "$to_dir/$lib_base"; 291*cdf0e10cSrcweir if ( $opt_zip ) { 292*cdf0e10cSrcweir push_on_ziplist("$to_dir/$lib_major") if $long; 293*cdf0e10cSrcweir push_on_ziplist("$to_dir/$lib_base"); 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir return; 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir my $symlib; 298*cdf0e10cSrcweir my @symlibs; 299*cdf0e10cSrcweir if ($long) 300*cdf0e10cSrcweir { 301*cdf0e10cSrcweir @symlibs = ("$to_dir/$lib_major", "$to_dir/$lib_base"); 302*cdf0e10cSrcweir } 303*cdf0e10cSrcweir else 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir @symlibs = ("$to_dir/$lib_base"); 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir # remove old symlinks 308*cdf0e10cSrcweir unlink(@symlibs); 309*cdf0e10cSrcweir foreach $symlib (@symlibs) { 310*cdf0e10cSrcweir print "LINKLIB: $lib -> $symlib\n" if $opt_verbose; 311*cdf0e10cSrcweir if ( !symlink("$lib", "$symlib") ) { 312*cdf0e10cSrcweir print_error("can't symlink $lib -> $symlib: $!",0); 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir else { 315*cdf0e10cSrcweir push_on_ziplist($symlib) if $opt_zip; 316*cdf0e10cSrcweir push_on_loglist("LINK", "$lib", "$symlib") if $opt_log; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir } 319*cdf0e10cSrcweir } 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir} 322*cdf0e10cSrcweir 323*cdf0e10cSrcweirsub do_mkdir 324*cdf0e10cSrcweir{ 325*cdf0e10cSrcweir my $path = expand_macros(shift); 326*cdf0e10cSrcweir # strip whitespaces from path name 327*cdf0e10cSrcweir $path =~ s/\s$//; 328*cdf0e10cSrcweir if (( ! $opt_delete ) && ( ! -d $path )) { 329*cdf0e10cSrcweir if ( $opt_check ) { 330*cdf0e10cSrcweir print "MKDIR: $path\n"; 331*cdf0e10cSrcweir } else { 332*cdf0e10cSrcweir mkpath($path, 0, 0777-$umask); 333*cdf0e10cSrcweir if ( ! -d $path ) { 334*cdf0e10cSrcweir print_error("mkdir: could not create directory '$path'", 0); 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir} 339*cdf0e10cSrcweir 340*cdf0e10cSrcweirsub do_symlink 341*cdf0e10cSrcweir{ 342*cdf0e10cSrcweir my $line = shift; 343*cdf0e10cSrcweir 344*cdf0e10cSrcweir $line = expand_macros($line); 345*cdf0e10cSrcweir ($from, $to) = split(' ',$line); 346*cdf0e10cSrcweir my $fullfrom = $from; 347*cdf0e10cSrcweir if ( dirname($from) eq dirname($to) ) { 348*cdf0e10cSrcweir $from = basename($from); 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir elsif ( dirname($from) eq '.' ) { 351*cdf0e10cSrcweir # nothing to do 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir else { 354*cdf0e10cSrcweir print_error("symlink: link must be in the same directory as file",0); 355*cdf0e10cSrcweir return 0; 356*cdf0e10cSrcweir } 357*cdf0e10cSrcweir 358*cdf0e10cSrcweir print "symlink: $from, to: $to\n" if $is_debug; 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir return unless $has_symlinks; 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir if ( $opt_check ) { 363*cdf0e10cSrcweir if ( $opt_delete ) { 364*cdf0e10cSrcweir print "REMOVE: $to\n"; 365*cdf0e10cSrcweir } 366*cdf0e10cSrcweir else { 367*cdf0e10cSrcweir print "SYMLINK $from -> $to\n"; 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir else { 371*cdf0e10cSrcweir print "REMOVE: $to\n" if $opt_verbose; 372*cdf0e10cSrcweir unlink $to; 373*cdf0e10cSrcweir if ( $opt_delete ) { 374*cdf0e10cSrcweir push_on_ziplist($to) if $opt_zip; 375*cdf0e10cSrcweir return; 376*cdf0e10cSrcweir } 377*cdf0e10cSrcweir return unless -e $fullfrom; 378*cdf0e10cSrcweir print "SYMLIB: $from -> $to\n" if $opt_verbose; 379*cdf0e10cSrcweir if ( !symlink("$from", "$to") ) { 380*cdf0e10cSrcweir print_error("can't symlink $from -> $to: $!",0); 381*cdf0e10cSrcweir } 382*cdf0e10cSrcweir else { 383*cdf0e10cSrcweir push_on_ziplist($to) if $opt_zip; 384*cdf0e10cSrcweir push_on_loglist("LINK", "$from", "$to") if $opt_log; 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir } 387*cdf0e10cSrcweir} 388*cdf0e10cSrcweir 389*cdf0e10cSrcweirsub do_touch 390*cdf0e10cSrcweir{ 391*cdf0e10cSrcweir my ($from, $to); 392*cdf0e10cSrcweir my $line = shift; 393*cdf0e10cSrcweir my $touch = 1; 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir $line = expand_macros($line); 396*cdf0e10cSrcweir ($from, $to) = split(' ', $line); 397*cdf0e10cSrcweir print "touch: $from, to: $to\n" if $is_debug; 398*cdf0e10cSrcweir glob_and_copy($from, $to, $touch); 399*cdf0e10cSrcweir} 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir#### subroutines ##### 402*cdf0e10cSrcweir 403*cdf0e10cSrcweirsub parse_options 404*cdf0e10cSrcweir{ 405*cdf0e10cSrcweir my $arg; 406*cdf0e10cSrcweir my $dontdeletecommon = 0; 407*cdf0e10cSrcweir $opt_silent = 1 if ( defined $ENV{VERBOSE} && $ENV{VERBOSE} eq 'FALSE'); 408*cdf0e10cSrcweir $opt_verbose = 1 if ( defined $ENV{VERBOSE} && $ENV{VERBOSE} eq 'TRUE'); 409*cdf0e10cSrcweir while ( $arg = shift @ARGV ) { 410*cdf0e10cSrcweir $arg =~ /^-force$/ and $opt_force = 1 and next; 411*cdf0e10cSrcweir $arg =~ /^-check$/ and $opt_check = 1 and $opt_verbose = 1 and next; 412*cdf0e10cSrcweir $arg =~ /^-quiet$/ and $opt_silent = 1 and next; 413*cdf0e10cSrcweir $arg =~ /^-verbose$/ and $opt_verbose = 1 and next; 414*cdf0e10cSrcweir $arg =~ /^-zip$/ and $opt_zip = 1 and next; 415*cdf0e10cSrcweir $arg =~ /^-delete$/ and $opt_delete = 1 and next; 416*cdf0e10cSrcweir $arg =~ /^-dontdeletecommon$/ and $dontdeletecommon = 1 and next; 417*cdf0e10cSrcweir $arg =~ /^-help$/ and $opt_help = 1 and $arg = ''; 418*cdf0e10cSrcweir $arg =~ /^-link$/ and $ENV{GUI} ne 'WNT' and $opt_link = 1 and next; 419*cdf0e10cSrcweir $arg =~ /^-deloutput$/ and $opt_deloutput = 1 and next; 420*cdf0e10cSrcweir $arg =~ /^-debug$/ and $is_debug = 1 and next; 421*cdf0e10cSrcweir $arg =~ /^-checkdlst$/ and $opt_checkdlst = 1 and next; 422*cdf0e10cSrcweir print_error("invalid option $arg") if ( $arg =~ /^-/ ); 423*cdf0e10cSrcweir if ( $arg =~ /^-/ || $opt_help || $#ARGV > -1 ) { 424*cdf0e10cSrcweir usage(1); 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir $dest = $arg; 427*cdf0e10cSrcweir } 428*cdf0e10cSrcweir # $dest and $opt_zip or $opt_delete are mutually exclusive 429*cdf0e10cSrcweir if ( $dest and ($opt_zip || $opt_delete) ) { 430*cdf0e10cSrcweir usage(1); 431*cdf0e10cSrcweir } 432*cdf0e10cSrcweir # $opt_silent and $opt_check or $opt_verbose are mutually exclusive 433*cdf0e10cSrcweir if ( ($opt_check or $opt_verbose) and $opt_silent ) { 434*cdf0e10cSrcweir print STDERR "Error on command line: options '-check' and '-quiet' are mutually exclusive.\n"; 435*cdf0e10cSrcweir usage(1); 436*cdf0e10cSrcweir } 437*cdf0e10cSrcweir if ($dontdeletecommon) { 438*cdf0e10cSrcweir if (!$opt_delete) { 439*cdf0e10cSrcweir usage(1); 440*cdf0e10cSrcweir } 441*cdf0e10cSrcweir $delete_common = 0; 442*cdf0e10cSrcweir }; 443*cdf0e10cSrcweir # $opt_delete implies $opt_force 444*cdf0e10cSrcweir $opt_force = 1 if $opt_delete; 445*cdf0e10cSrcweir} 446*cdf0e10cSrcweir 447*cdf0e10cSrcweirsub init_globals 448*cdf0e10cSrcweir{ 449*cdf0e10cSrcweir my $ext; 450*cdf0e10cSrcweir ($module, $repository, $base_dir, $dlst_file) = get_base(); 451*cdf0e10cSrcweir 452*cdf0e10cSrcweir # for CWS: 453*cdf0e10cSrcweir $module =~ s/\.lnk$//; 454*cdf0e10cSrcweir 455*cdf0e10cSrcweir print "Module=$module, Base_Dir=$base_dir, d.lst=$dlst_file\n" if $is_debug; 456*cdf0e10cSrcweir 457*cdf0e10cSrcweir $umask = umask(); 458*cdf0e10cSrcweir if ( !defined($umask) ) { 459*cdf0e10cSrcweir $umask = 22; 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir my $build_sosl = $ENV{'BUILD_SOSL'}; 463*cdf0e10cSrcweir my $common_outdir = $ENV{'COMMON_OUTDIR'}; 464*cdf0e10cSrcweir my $inpath = $ENV{'INPATH'}; 465*cdf0e10cSrcweir my $solarversion = $ENV{'SOLARVERSION'}; 466*cdf0e10cSrcweir my $updater = $ENV{'UPDATER'}; 467*cdf0e10cSrcweir my $updminor = $ENV{'UPDMINOR'}; 468*cdf0e10cSrcweir my $updminorext = $ENV{'UPDMINOREXT'}; 469*cdf0e10cSrcweir my $work_stamp = $ENV{'WORK_STAMP'}; 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir # special security check for release engineers 472*cdf0e10cSrcweir if ( defined($updater) && !defined($build_sosl) && !$opt_force) { 473*cdf0e10cSrcweir my $path = getcwd(); 474*cdf0e10cSrcweir if ( $path !~ /$work_stamp/io ) { 475*cdf0e10cSrcweir print_error("can't deliver from local directory to SOLARVERSION"); 476*cdf0e10cSrcweir print STDERR "\nDANGER! Release Engineer:\n"; 477*cdf0e10cSrcweir print STDERR "do you really want to deliver from $path to SOLARVERSION?\n"; 478*cdf0e10cSrcweir print STDERR "If so, please use the -force switch\n\n"; 479*cdf0e10cSrcweir exit(7); 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir 483*cdf0e10cSrcweir # do we have a valid environment? 484*cdf0e10cSrcweir if ( !defined($inpath) ) { 485*cdf0e10cSrcweir print_error("no environment", 0); 486*cdf0e10cSrcweir exit(3); 487*cdf0e10cSrcweir } 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir $ext = ""; 490*cdf0e10cSrcweir if ( ($updminor) && !$dest ) { 491*cdf0e10cSrcweir $ext = "$updminorext"; 492*cdf0e10cSrcweir } 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir # Do we have common trees? 495*cdf0e10cSrcweir if ( defined($ENV{'common_build'}) && $ENV{'common_build'} eq 'TRUE' ) { 496*cdf0e10cSrcweir $common_build = 1; 497*cdf0e10cSrcweir if ((defined $common_outdir) && ($common_outdir ne "")) { 498*cdf0e10cSrcweir $common_outdir = $common_outdir . ".pro" if $inpath =~ /\.pro$/; 499*cdf0e10cSrcweir if ( $dest ) { 500*cdf0e10cSrcweir $common_dest = $dest; 501*cdf0e10cSrcweir } else { 502*cdf0e10cSrcweir $common_dest = "$solarversion/$common_outdir"; 503*cdf0e10cSrcweir $dest = "$solarversion/$inpath"; 504*cdf0e10cSrcweir } 505*cdf0e10cSrcweir } else { 506*cdf0e10cSrcweir print_error("common_build defined without common_outdir", 0); 507*cdf0e10cSrcweir exit(6); 508*cdf0e10cSrcweir } 509*cdf0e10cSrcweir } else { 510*cdf0e10cSrcweir $common_outdir = $inpath; 511*cdf0e10cSrcweir $dest = "$solarversion/$inpath" if ( !$dest ); 512*cdf0e10cSrcweir $common_dest = $dest; 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir $dest =~ s#\\#/#g; 515*cdf0e10cSrcweir $common_dest =~ s#\\#/#g; 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir # the following macros are obsolete, will be flagged as error 518*cdf0e10cSrcweir # %__WORKSTAMP% 519*cdf0e10cSrcweir # %GUIBASE% 520*cdf0e10cSrcweir # %SDK% 521*cdf0e10cSrcweir # %SOLARVER% 522*cdf0e10cSrcweir # %__OFFENV% 523*cdf0e10cSrcweir # %DLLSUFFIX%' 524*cdf0e10cSrcweir # %OUTPATH% 525*cdf0e10cSrcweir # %L10N_FRAMEWORK% 526*cdf0e10cSrcweir # %UPD% 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir # valid macros 529*cdf0e10cSrcweir @macros = ( 530*cdf0e10cSrcweir [ '%__PRJROOT%', $base_dir ], 531*cdf0e10cSrcweir [ '%__SRC%', $inpath ], 532*cdf0e10cSrcweir [ '%_DEST%', $dest ], 533*cdf0e10cSrcweir [ '%_EXT%', $ext ], 534*cdf0e10cSrcweir [ '%COMMON_OUTDIR%', $common_outdir ], 535*cdf0e10cSrcweir [ '%COMMON_DEST%', $common_dest ], 536*cdf0e10cSrcweir [ '%GUI%', $gui ] 537*cdf0e10cSrcweir ); 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir # find out if the system supports symlinks 540*cdf0e10cSrcweir $has_symlinks = eval { symlink("",""); 1 }; 541*cdf0e10cSrcweir} 542*cdf0e10cSrcweir 543*cdf0e10cSrcweirsub get_base 544*cdf0e10cSrcweir{ 545*cdf0e10cSrcweir # a module base dir contains a subdir 'prj' 546*cdf0e10cSrcweir # which in turn contains a file 'd.lst' 547*cdf0e10cSrcweir my (@field, $repo, $base, $dlst); 548*cdf0e10cSrcweir my $path = getcwd(); 549*cdf0e10cSrcweir 550*cdf0e10cSrcweir @field = split(/\//, $path); 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir while ( $#field != -1 ) { 553*cdf0e10cSrcweir $base = join('/', @field); 554*cdf0e10cSrcweir $dlst = $base . '/prj/d.lst'; 555*cdf0e10cSrcweir last if -e $dlst; 556*cdf0e10cSrcweir pop @field; 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir if ( $#field == -1 ) { 560*cdf0e10cSrcweir print_error("can't find d.lst"); 561*cdf0e10cSrcweir exit(2); 562*cdf0e10cSrcweir } 563*cdf0e10cSrcweir else { 564*cdf0e10cSrcweir if ( defined $field[-2] ) { 565*cdf0e10cSrcweir $repo = $field[-2]; 566*cdf0e10cSrcweir } else { 567*cdf0e10cSrcweir print_error("Internal error: cannot determine module's parent directory"); 568*cdf0e10cSrcweir } 569*cdf0e10cSrcweir return ($field[-1], $repo, $base, $dlst); 570*cdf0e10cSrcweir } 571*cdf0e10cSrcweir} 572*cdf0e10cSrcweir 573*cdf0e10cSrcweirsub parse_dlst 574*cdf0e10cSrcweir{ 575*cdf0e10cSrcweir my $line_cnt = 0; 576*cdf0e10cSrcweir open(DLST, "<$dlst_file") or die "can't open d.lst"; 577*cdf0e10cSrcweir while(<DLST>) { 578*cdf0e10cSrcweir $line_cnt++; 579*cdf0e10cSrcweir tr/\r\n//d; 580*cdf0e10cSrcweir next if /^#/; 581*cdf0e10cSrcweir next if /^\s*$/; 582*cdf0e10cSrcweir if (!$delete_common && /%COMMON_DEST%/) { 583*cdf0e10cSrcweir # Just ignore all lines with %COMMON_DEST% 584*cdf0e10cSrcweir next; 585*cdf0e10cSrcweir }; 586*cdf0e10cSrcweir if ( /^\s*(\w+?):\s+(.*)$/ ) { 587*cdf0e10cSrcweir if ( !exists $action_hash{$1} ) { 588*cdf0e10cSrcweir print_error("unknown action: \'$1\'", $line_cnt); 589*cdf0e10cSrcweir exit(4); 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir push(@action_data, [$1, $2]); 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir else { 594*cdf0e10cSrcweir if ( /^\s*%(COMMON)?_DEST%\\/ ) { 595*cdf0e10cSrcweir # only copy from source dir to solver, not from solver to solver 596*cdf0e10cSrcweir print_warning("illegal copy action, ignored: \'$_\'", $line_cnt); 597*cdf0e10cSrcweir next; 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir push(@action_data, ['copy', $_]); 600*cdf0e10cSrcweir # for each ressource file (.res) copy its image list (.ilst) 601*cdf0e10cSrcweir if ( /\.res\s/ ) { 602*cdf0e10cSrcweir my $imagelist = $_; 603*cdf0e10cSrcweir $imagelist =~ s/\.res/\.$ilst_ext/g; 604*cdf0e10cSrcweir $imagelist =~ s/\\bin%_EXT%\\/\\res%_EXT%\\img\\/; 605*cdf0e10cSrcweir push(@action_data, ['copy', $imagelist]); 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir } 608*cdf0e10cSrcweir # call expand_macros()just to find any undefined macros early 609*cdf0e10cSrcweir # real expansion is done later 610*cdf0e10cSrcweir expand_macros($_, $line_cnt); 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir close(DLST); 613*cdf0e10cSrcweir} 614*cdf0e10cSrcweir 615*cdf0e10cSrcweirsub expand_macros 616*cdf0e10cSrcweir{ 617*cdf0e10cSrcweir # expand all macros and change backslashes to slashes 618*cdf0e10cSrcweir my $line = shift; 619*cdf0e10cSrcweir my $line_cnt = shift; 620*cdf0e10cSrcweir my $i; 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir for ($i=0; $i<=$#macros; $i++) { 623*cdf0e10cSrcweir $line =~ s/$macros[$i][0]/$macros[$i][1]/gi 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir if ( $line =~ /(%\w+%)/ ) { 626*cdf0e10cSrcweir if ( $1 ne '%OS%' ) { # %OS% looks like a macro but is not ... 627*cdf0e10cSrcweir print_error("unknown/obsolete macro: \'$1\'", $line_cnt); 628*cdf0e10cSrcweir } 629*cdf0e10cSrcweir } 630*cdf0e10cSrcweir $line =~ s#\\#/#g; 631*cdf0e10cSrcweir return $line; 632*cdf0e10cSrcweir} 633*cdf0e10cSrcweir 634*cdf0e10cSrcweirsub walk_action_data 635*cdf0e10cSrcweir{ 636*cdf0e10cSrcweir # all actions have to be excuted relative to the prj directory 637*cdf0e10cSrcweir chdir("$base_dir/prj"); 638*cdf0e10cSrcweir # dispatch depending on action type 639*cdf0e10cSrcweir for (my $i=0; $i <= $#action_data; $i++) { 640*cdf0e10cSrcweir &{"do_".$action_data[$i][0]}($action_data[$i][1]); 641*cdf0e10cSrcweir if ( $action_data[$i][0] eq 'mkdir' ) { 642*cdf0e10cSrcweir # fill array with (possibly) created directories in 643*cdf0e10cSrcweir # revers order for removal in 'cleanup' 644*cdf0e10cSrcweir unshift @dirlist, $action_data[$i][1]; 645*cdf0e10cSrcweir } 646*cdf0e10cSrcweir } 647*cdf0e10cSrcweir} 648*cdf0e10cSrcweir 649*cdf0e10cSrcweirsub glob_line 650*cdf0e10cSrcweir{ 651*cdf0e10cSrcweir my $from = shift; 652*cdf0e10cSrcweir my $to = shift; 653*cdf0e10cSrcweir my $to_dir = shift; 654*cdf0e10cSrcweir my $replace = 0; 655*cdf0e10cSrcweir my @globbed_files = (); 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir if ( ! ( $from && $to ) ) { 658*cdf0e10cSrcweir print_warning("Error in d.lst? source: '$from' destination: '$to'"); 659*cdf0e10cSrcweir return \@globbed_files; 660*cdf0e10cSrcweir } 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir if ( $to =~ /[\*\?\[\]]/ ) { 663*cdf0e10cSrcweir my $to_fname; 664*cdf0e10cSrcweir ($to_fname, $to_dir) = fileparse($to); 665*cdf0e10cSrcweir $replace = 1; 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir if ( $from =~ /[\*\?\[\]]/ ) { 669*cdf0e10cSrcweir # globbing necessary, no renaming possible 670*cdf0e10cSrcweir my $file; 671*cdf0e10cSrcweir my @file_list = glob($from); 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir foreach $file ( @file_list ) { 674*cdf0e10cSrcweir next if ( -d $file); # we only copy files, not directories 675*cdf0e10cSrcweir my ($fname, $dir) = fileparse($file); 676*cdf0e10cSrcweir my $copy = ($replace) ? $to_dir . $fname : $to . '/' . $fname; 677*cdf0e10cSrcweir push(@globbed_files, [$file, $copy]); 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir } 680*cdf0e10cSrcweir else { 681*cdf0e10cSrcweir # no globbing but renaming possible 682*cdf0e10cSrcweir # #i89066# 683*cdf0e10cSrcweir if (-d $to && -f $from) { 684*cdf0e10cSrcweir my $filename = File::Basename::basename($from); 685*cdf0e10cSrcweir $to .= '/' if ($to !~ /[\\|\/]$/); 686*cdf0e10cSrcweir $to .= $filename; 687*cdf0e10cSrcweir }; 688*cdf0e10cSrcweir push(@globbed_files, [$from, $to]); 689*cdf0e10cSrcweir } 690*cdf0e10cSrcweir if ( $opt_checkdlst ) { 691*cdf0e10cSrcweir my $outtree = expand_macros("%__SRC%"); 692*cdf0e10cSrcweir my $commonouttree = expand_macros("%COMMON_OUTDIR%"); 693*cdf0e10cSrcweir if (( $from !~ /\Q$outtree\E/ ) && ( $from !~ /\Q$commonouttree\E/ )) { 694*cdf0e10cSrcweir print_warning("'$from' does not match any file") if ( $#globbed_files == -1 ); 695*cdf0e10cSrcweir } 696*cdf0e10cSrcweir } 697*cdf0e10cSrcweir return \@globbed_files; 698*cdf0e10cSrcweir} 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir 701*cdf0e10cSrcweirsub glob_and_copy 702*cdf0e10cSrcweir{ 703*cdf0e10cSrcweir my $from = shift; 704*cdf0e10cSrcweir my $to = shift; 705*cdf0e10cSrcweir my $touch = shift; 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir my @copy_files = @{glob_line($from, $to)}; 708*cdf0e10cSrcweir 709*cdf0e10cSrcweir for (my $i = 0; $i <= $#copy_files; $i++) { 710*cdf0e10cSrcweir next if filter_out($copy_files[$i][0]); # apply copy filter 711*cdf0e10cSrcweir copy_if_newer($copy_files[$i][0], $copy_files[$i][1], $touch) 712*cdf0e10cSrcweir ? $files_copied++ : $files_unchanged++; 713*cdf0e10cSrcweir } 714*cdf0e10cSrcweir} 715*cdf0e10cSrcweir 716*cdf0e10cSrcweirsub is_unstripped { 717*cdf0e10cSrcweir my $file_name = shift; 718*cdf0e10cSrcweir my $nm_output; 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir if (-f $file_name.$maybedot) { 721*cdf0e10cSrcweir my $file_type = `file $file_name`; 722*cdf0e10cSrcweir # OS X file command doesn't know if a file is stripped or not 723*cdf0e10cSrcweir if (($file_type =~ /not stripped/o) || ($file_type =~ /Mach-O/o) || 724*cdf0e10cSrcweir (($file_type =~ /PE/o) && ($ENV{GUI} eq 'WNT') && 725*cdf0e10cSrcweir ($nm_output = `nm $file_name 2>&1`) && $nm_output && 726*cdf0e10cSrcweir !($nm_output =~ /no symbols/i) && !($nm_output =~ /not recognized/i))) { 727*cdf0e10cSrcweir return '1' if ($file_name =~ /\.bin$/o); 728*cdf0e10cSrcweir return '1' if ($file_name =~ /\.so\.*/o); 729*cdf0e10cSrcweir return '1' if ($file_name =~ /\.dylib\.*/o); 730*cdf0e10cSrcweir return '1' if ($file_name =~ /\.com\.*/o); 731*cdf0e10cSrcweir return '1' if ($file_name =~ /\.dll\.*/o); 732*cdf0e10cSrcweir return '1' if ($file_name =~ /\.exe\.*/o); 733*cdf0e10cSrcweir return '1' if (basename($file_name) !~ /\./o); 734*cdf0e10cSrcweir } 735*cdf0e10cSrcweir }; 736*cdf0e10cSrcweir return ''; 737*cdf0e10cSrcweir} 738*cdf0e10cSrcweir 739*cdf0e10cSrcweirsub initialize_strip { 740*cdf0e10cSrcweir if ((!defined $ENV{DISABLE_STRIP}) || ($ENV{DISABLE_STRIP} eq "")) { 741*cdf0e10cSrcweir $strip .= 'guw ' if ($^O eq 'cygwin'); 742*cdf0e10cSrcweir $strip .= 'strip'; 743*cdf0e10cSrcweir $strip .= " -x" if ($ENV{OS} eq 'MACOSX'); 744*cdf0e10cSrcweir $strip .= " -R '.comment' -s" if ($ENV{OS} eq 'LINUX'); 745*cdf0e10cSrcweir }; 746*cdf0e10cSrcweir}; 747*cdf0e10cSrcweir 748*cdf0e10cSrcweirsub is_jar { 749*cdf0e10cSrcweir my $file_name = shift; 750*cdf0e10cSrcweir 751*cdf0e10cSrcweir if (-f $file_name && (( `file $file_name` ) =~ /Zip archive/o)) { 752*cdf0e10cSrcweir return '1' if ($file_name =~ /\.jar\.*/o); 753*cdf0e10cSrcweir }; 754*cdf0e10cSrcweir return ''; 755*cdf0e10cSrcweir} 756*cdf0e10cSrcweir 757*cdf0e10cSrcweirsub execute_system { 758*cdf0e10cSrcweir my $command = shift; 759*cdf0e10cSrcweir if (system($command)) { 760*cdf0e10cSrcweir print_error("Failed to execute $command"); 761*cdf0e10cSrcweir exit($?); 762*cdf0e10cSrcweir }; 763*cdf0e10cSrcweir}; 764*cdf0e10cSrcweir 765*cdf0e10cSrcweirsub strip_target { 766*cdf0e10cSrcweir my $file = shift; 767*cdf0e10cSrcweir my $temp_file = shift; 768*cdf0e10cSrcweir $temp_file =~ s/\/{2,}/\//g; 769*cdf0e10cSrcweir my $rc = copy($file, $temp_file); 770*cdf0e10cSrcweir execute_system("$strip $temp_file"); 771*cdf0e10cSrcweir return $rc; 772*cdf0e10cSrcweir}; 773*cdf0e10cSrcweir 774*cdf0e10cSrcweirsub copy_if_newer 775*cdf0e10cSrcweir{ 776*cdf0e10cSrcweir # return 0 if file is unchanged ( for whatever reason ) 777*cdf0e10cSrcweir # return 1 if file has been copied 778*cdf0e10cSrcweir my $from = shift; 779*cdf0e10cSrcweir my $to = shift; 780*cdf0e10cSrcweir my $touch = shift; 781*cdf0e10cSrcweir my $from_stat_ref; 782*cdf0e10cSrcweir my $rc = 0; 783*cdf0e10cSrcweir 784*cdf0e10cSrcweir print "testing $from, $to\n" if $is_debug; 785*cdf0e10cSrcweir push_on_ziplist($to) if $opt_zip; 786*cdf0e10cSrcweir push_on_loglist("COPY", "$from", "$to") if $opt_log; 787*cdf0e10cSrcweir return 0 unless ($from_stat_ref = is_newer($from, $to, $touch)); 788*cdf0e10cSrcweir 789*cdf0e10cSrcweir if ( $opt_delete ) { 790*cdf0e10cSrcweir print "REMOVE: $to\n" if $opt_verbose; 791*cdf0e10cSrcweir $rc = unlink($to) unless $opt_check; 792*cdf0e10cSrcweir return 1 if $opt_check; 793*cdf0e10cSrcweir return $rc; 794*cdf0e10cSrcweir } 795*cdf0e10cSrcweir 796*cdf0e10cSrcweir if( !$opt_check && $opt_link ) { 797*cdf0e10cSrcweir # hard link if possible 798*cdf0e10cSrcweir if( link($from, $to) ){ 799*cdf0e10cSrcweir print "LINK: $from -> $to\n" if $opt_verbose; 800*cdf0e10cSrcweir return 1; 801*cdf0e10cSrcweir } 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir 804*cdf0e10cSrcweir if( $touch ) { 805*cdf0e10cSrcweir print "TOUCH: $from -> $to\n" if $opt_verbose; 806*cdf0e10cSrcweir } 807*cdf0e10cSrcweir else { 808*cdf0e10cSrcweir print "COPY: $from -> $to\n" if $opt_verbose; 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir return 1 if( $opt_check ); 812*cdf0e10cSrcweir 813*cdf0e10cSrcweir # 814*cdf0e10cSrcweir # copy to temporary file first and rename later 815*cdf0e10cSrcweir # to minimize the possibility for race conditions 816*cdf0e10cSrcweir local $temp_file = sprintf('%s.%d-%d', $to, $$, time()); 817*cdf0e10cSrcweir $rc = ''; 818*cdf0e10cSrcweir if (($strip ne '') && (defined $ENV{PROEXT}) && (is_unstripped($from))) { 819*cdf0e10cSrcweir $rc = strip_target($from, $temp_file); 820*cdf0e10cSrcweir } else { 821*cdf0e10cSrcweir $rc = copy($from, $temp_file); 822*cdf0e10cSrcweir }; 823*cdf0e10cSrcweir if ( $rc) { 824*cdf0e10cSrcweir if ( is_newer($temp_file, $from, 0) ) { 825*cdf0e10cSrcweir $rc = utime($$from_stat_ref[9], $$from_stat_ref[9], $temp_file); 826*cdf0e10cSrcweir if ( !$rc ) { 827*cdf0e10cSrcweir print_warning("can't update temporary file modification time '$temp_file': $!\n 828*cdf0e10cSrcweir Check file permissions of '$from'.",0); 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir } 831*cdf0e10cSrcweir fix_file_permissions($$from_stat_ref[2], $temp_file); 832*cdf0e10cSrcweir if ( $^O eq 'os2' ) 833*cdf0e10cSrcweir { 834*cdf0e10cSrcweir $rc = unlink($to); # YD OS/2 can't rename if $to exists! 835*cdf0e10cSrcweir } 836*cdf0e10cSrcweir # Ugly hack: on windows file locking(?) sometimes prevents renaming. 837*cdf0e10cSrcweir # Until we've found and fixed the real reason try it repeatedly :-( 838*cdf0e10cSrcweir my $try = 0; 839*cdf0e10cSrcweir my $maxtries = 1; 840*cdf0e10cSrcweir $maxtries = 5 if ( $^O eq 'MSWin32' ); 841*cdf0e10cSrcweir my $success = 0; 842*cdf0e10cSrcweir while ( $try < $maxtries && ! $success ) { 843*cdf0e10cSrcweir sleep $try; 844*cdf0e10cSrcweir $try ++; 845*cdf0e10cSrcweir $success = rename($temp_file, $to); 846*cdf0e10cSrcweir if ( $^O eq 'cygwin' && $to =~ /\.bin$/) { 847*cdf0e10cSrcweir # hack to survive automatically added .exe for executables renamed to 848*cdf0e10cSrcweir # *.bin - will break if there is intentionally a .bin _and_ .bin.exe file. 849*cdf0e10cSrcweir $success = rename( "$to.exe", $to ) if -f "$to.exe"; 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir } 852*cdf0e10cSrcweir if ( $success ) { 853*cdf0e10cSrcweir # handle special packaging of *.dylib files for Mac OS X 854*cdf0e10cSrcweir if ( $^O eq 'darwin' ) 855*cdf0e10cSrcweir { 856*cdf0e10cSrcweir system("macosx-create-bundle", "$to=$from.app") if ( -d "$from.app" ); 857*cdf0e10cSrcweir system("ranlib", "$to" ) if ( $to =~ /\.a/ ); 858*cdf0e10cSrcweir } 859*cdf0e10cSrcweir if ( $try > 1 ) { 860*cdf0e10cSrcweir print_warning("File '$to' temporarily locked. Dependency bug?"); 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir return 1; 863*cdf0e10cSrcweir } 864*cdf0e10cSrcweir else { 865*cdf0e10cSrcweir print_error("can't rename temporary file to $to: $!",0); 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir } 868*cdf0e10cSrcweir else { 869*cdf0e10cSrcweir print_error("can't copy $from: $!",0); 870*cdf0e10cSrcweir my $destdir = dirname($to); 871*cdf0e10cSrcweir if ( ! -d $destdir ) { 872*cdf0e10cSrcweir print_error("directory '$destdir' does not exist", 0); 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir unlink($temp_file); 876*cdf0e10cSrcweir return 0; 877*cdf0e10cSrcweir} 878*cdf0e10cSrcweir 879*cdf0e10cSrcweirsub is_newer 880*cdf0e10cSrcweir{ 881*cdf0e10cSrcweir # returns whole stat buffer if newer 882*cdf0e10cSrcweir my $from = shift; 883*cdf0e10cSrcweir my $to = shift; 884*cdf0e10cSrcweir my $touch = shift; 885*cdf0e10cSrcweir my (@from_stat, @to_stat); 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir @from_stat = stat($from.$maybedot); 888*cdf0e10cSrcweir if ( $opt_checkdlst ) { 889*cdf0e10cSrcweir my $outtree = expand_macros("%__SRC%"); 890*cdf0e10cSrcweir my $commonouttree = expand_macros("%COMMON_OUTDIR%"); 891*cdf0e10cSrcweir if ( $from !~ /$outtree/ ) { 892*cdf0e10cSrcweir if ( $from !~ /$commonouttree/ ) { 893*cdf0e10cSrcweir print_warning("'$from' does not exist") unless -e _; 894*cdf0e10cSrcweir } 895*cdf0e10cSrcweir } 896*cdf0e10cSrcweir } 897*cdf0e10cSrcweir return 0 unless -f _; 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir if ( $touch ) { 900*cdf0e10cSrcweir $from_stat[9] = time(); 901*cdf0e10cSrcweir } 902*cdf0e10cSrcweir # adjust timestamps to even seconds 903*cdf0e10cSrcweir # this is necessary since NT platforms have a 904*cdf0e10cSrcweir # 2s modified time granularity while the timestamps 905*cdf0e10cSrcweir # on Samba volumes have a 1s granularity 906*cdf0e10cSrcweir 907*cdf0e10cSrcweir $from_stat[9]-- if $from_stat[9] % 2; 908*cdf0e10cSrcweir 909*cdf0e10cSrcweir if ( $to =~ /^\Q$dest\E/ ) { 910*cdf0e10cSrcweir if ( $from_stat[9] > $logfiledate ) { 911*cdf0e10cSrcweir $logfiledate = $from_stat[9]; 912*cdf0e10cSrcweir } 913*cdf0e10cSrcweir } elsif ( $common_build && ( $to =~ /^\Q$common_dest\E/ ) ) { 914*cdf0e10cSrcweir if ( $from_stat[9] > $commonlogfiledate ) { 915*cdf0e10cSrcweir $commonlogfiledate = $from_stat[9]; 916*cdf0e10cSrcweir } 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir @to_stat = stat($to.$maybedot); 920*cdf0e10cSrcweir return \@from_stat unless -f _; 921*cdf0e10cSrcweir 922*cdf0e10cSrcweir if ( $opt_force ) { 923*cdf0e10cSrcweir return \@from_stat; 924*cdf0e10cSrcweir } 925*cdf0e10cSrcweir else { 926*cdf0e10cSrcweir return ($from_stat[9] > $to_stat[9]) ? \@from_stat : 0; 927*cdf0e10cSrcweir } 928*cdf0e10cSrcweir} 929*cdf0e10cSrcweir 930*cdf0e10cSrcweirsub filter_out 931*cdf0e10cSrcweir{ 932*cdf0e10cSrcweir my $file = shift; 933*cdf0e10cSrcweir 934*cdf0e10cSrcweir foreach my $pattern ( @copy_filter_patterns ) { 935*cdf0e10cSrcweir if ( $file =~ /$pattern/ ) { 936*cdf0e10cSrcweir print "filter out: $file\n" if $is_debug; 937*cdf0e10cSrcweir return 1; 938*cdf0e10cSrcweir } 939*cdf0e10cSrcweir } 940*cdf0e10cSrcweir 941*cdf0e10cSrcweir return 0; 942*cdf0e10cSrcweir} 943*cdf0e10cSrcweir 944*cdf0e10cSrcweirsub fix_file_permissions 945*cdf0e10cSrcweir{ 946*cdf0e10cSrcweir my $mode = shift; 947*cdf0e10cSrcweir my $file = shift; 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir if ( ($mode >> 6) % 2 == 1 ) { 950*cdf0e10cSrcweir $mode = 0777 & ~$umask; 951*cdf0e10cSrcweir } 952*cdf0e10cSrcweir else { 953*cdf0e10cSrcweir $mode = 0666 & ~$umask; 954*cdf0e10cSrcweir } 955*cdf0e10cSrcweir chmod($mode, $file); 956*cdf0e10cSrcweir} 957*cdf0e10cSrcweir 958*cdf0e10cSrcweirsub get_latest_patchlevel 959*cdf0e10cSrcweir{ 960*cdf0e10cSrcweir # note: feed only well formed library names to this function 961*cdf0e10cSrcweir # of the form libfoo.so.x.y.z with x,y,z numbers 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir my @sorted_files = sort by_rev @_; 964*cdf0e10cSrcweir return $sorted_files[-1]; 965*cdf0e10cSrcweir 966*cdf0e10cSrcweir sub by_rev { 967*cdf0e10cSrcweir # comparison function for sorting 968*cdf0e10cSrcweir my (@field_a, @field_b, $i); 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir $a =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)\.(\d+)\.(\d+)$/; 971*cdf0e10cSrcweir @field_a = ($3, $4, $5); 972*cdf0e10cSrcweir $b =~ /^(lib[\w-]+(\.so|\.dylib))\.(\d+)\.(\d+)\.(\d+)$/; 973*cdf0e10cSrcweir @field_b = ($3, $4, $5); 974*cdf0e10cSrcweir 975*cdf0e10cSrcweir for ($i = 0; $i < 3; $i++) 976*cdf0e10cSrcweir { 977*cdf0e10cSrcweir if ( ($field_a[$i] < $field_b[$i]) ) { 978*cdf0e10cSrcweir return -1; 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir if ( ($field_a[$i] > $field_b[$i]) ) { 981*cdf0e10cSrcweir return 1; 982*cdf0e10cSrcweir } 983*cdf0e10cSrcweir } 984*cdf0e10cSrcweir 985*cdf0e10cSrcweir # can't happen 986*cdf0e10cSrcweir return 0; 987*cdf0e10cSrcweir } 988*cdf0e10cSrcweir 989*cdf0e10cSrcweir} 990*cdf0e10cSrcweir 991*cdf0e10cSrcweirsub push_default_actions 992*cdf0e10cSrcweir{ 993*cdf0e10cSrcweir # any default action (that is an action which must be done even without 994*cdf0e10cSrcweir # a corresponding d.lst entry) should be pushed here on the 995*cdf0e10cSrcweir # @action_data list. 996*cdf0e10cSrcweir my $subdir; 997*cdf0e10cSrcweir my @subdirs = ( 998*cdf0e10cSrcweir 'bin', 999*cdf0e10cSrcweir 'doc', 1000*cdf0e10cSrcweir 'inc', 1001*cdf0e10cSrcweir 'lib', 1002*cdf0e10cSrcweir 'par', 1003*cdf0e10cSrcweir 'pck', 1004*cdf0e10cSrcweir 'rdb', 1005*cdf0e10cSrcweir 'res', 1006*cdf0e10cSrcweir 'xml' 1007*cdf0e10cSrcweir ); 1008*cdf0e10cSrcweir push(@subdirs, 'zip') if $opt_zip; 1009*cdf0e10cSrcweir push(@subdirs, 'idl') if ! $common_build; 1010*cdf0e10cSrcweir push(@subdirs, 'pus') if ! $common_build; 1011*cdf0e10cSrcweir my @common_subdirs = ( 1012*cdf0e10cSrcweir 'bin', 1013*cdf0e10cSrcweir 'idl', 1014*cdf0e10cSrcweir 'inc', 1015*cdf0e10cSrcweir 'pck', 1016*cdf0e10cSrcweir 'pus', 1017*cdf0e10cSrcweir 'res' 1018*cdf0e10cSrcweir ); 1019*cdf0e10cSrcweir push(@common_subdirs, 'zip') if $opt_zip; 1020*cdf0e10cSrcweir 1021*cdf0e10cSrcweir if ( ! $opt_delete ) { 1022*cdf0e10cSrcweir # create all the subdirectories on solver 1023*cdf0e10cSrcweir foreach $subdir (@subdirs) { 1024*cdf0e10cSrcweir push(@action_data, ['mkdir', "%_DEST%/$subdir%_EXT%"]); 1025*cdf0e10cSrcweir } 1026*cdf0e10cSrcweir if ( $common_build ) { 1027*cdf0e10cSrcweir foreach $subdir (@common_subdirs) { 1028*cdf0e10cSrcweir push(@action_data, ['mkdir', "%COMMON_DEST%/$subdir%_EXT%"]); 1029*cdf0e10cSrcweir } 1030*cdf0e10cSrcweir } 1031*cdf0e10cSrcweir } 1032*cdf0e10cSrcweir push(@action_data, ['mkdir', "%_DEST%/inc%_EXT%/$module"]); 1033*cdf0e10cSrcweir if ( $common_build ) { 1034*cdf0e10cSrcweir push(@action_data, ['mkdir', "%COMMON_DEST%/inc%_EXT%/$module"]); 1035*cdf0e10cSrcweir push(@action_data, ['mkdir', "%COMMON_DEST%/res%_EXT%/img"]); 1036*cdf0e10cSrcweir } else { 1037*cdf0e10cSrcweir push(@action_data, ['mkdir', "%_DEST%/res%_EXT%/img"]); 1038*cdf0e10cSrcweir } 1039*cdf0e10cSrcweir 1040*cdf0e10cSrcweir # deliver build.lst to $dest/inc/$module 1041*cdf0e10cSrcweir push(@action_data, ['copy', "build.lst %_DEST%/inc%_EXT%/$module/build.lst"]); 1042*cdf0e10cSrcweir if ( $common_build ) { 1043*cdf0e10cSrcweir # ... and to $common_dest/inc/$module 1044*cdf0e10cSrcweir push(@action_data, ['copy', "build.lst %COMMON_DEST%/inc%_EXT%/$module/build.lst"]); 1045*cdf0e10cSrcweir } 1046*cdf0e10cSrcweir 1047*cdf0e10cSrcweir # need to copy libstaticmxp.dylib for Mac OS X 1048*cdf0e10cSrcweir if ( $^O eq 'darwin' ) 1049*cdf0e10cSrcweir { 1050*cdf0e10cSrcweir push(@action_data, ['copy', "../%__SRC%/lib/lib*static*.dylib %_DEST%/lib%_EXT%/lib*static*.dylib"]); 1051*cdf0e10cSrcweir } 1052*cdf0e10cSrcweir} 1053*cdf0e10cSrcweir 1054*cdf0e10cSrcweirsub walk_addincpath_list 1055*cdf0e10cSrcweir{ 1056*cdf0e10cSrcweir my (@addincpath_headers); 1057*cdf0e10cSrcweir return if $#addincpath_list == -1; 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir # create hash with all addincpath header names 1060*cdf0e10cSrcweir for (my $i = 0; $i <= $#addincpath_list; $i++) { 1061*cdf0e10cSrcweir my @field = split('/', $addincpath_list[$i][0]); 1062*cdf0e10cSrcweir push (@addincpath_headers, $field[-1]); 1063*cdf0e10cSrcweir } 1064*cdf0e10cSrcweir 1065*cdf0e10cSrcweir # now stream all addincpath headers through addincpath filter 1066*cdf0e10cSrcweir for (my $i = 0; $i <= $#addincpath_list; $i++) { 1067*cdf0e10cSrcweir add_incpath_if_newer($addincpath_list[$i][0], $addincpath_list[$i][1], \@addincpath_headers) 1068*cdf0e10cSrcweir ? $files_copied++ : $files_unchanged++; 1069*cdf0e10cSrcweir } 1070*cdf0e10cSrcweir} 1071*cdf0e10cSrcweir 1072*cdf0e10cSrcweirsub add_incpath_if_newer 1073*cdf0e10cSrcweir{ 1074*cdf0e10cSrcweir my $from = shift; 1075*cdf0e10cSrcweir my $to = shift; 1076*cdf0e10cSrcweir my $modify_headers_ref = shift; 1077*cdf0e10cSrcweir my ($from_stat_ref, $header); 1078*cdf0e10cSrcweir 1079*cdf0e10cSrcweir push_on_ziplist($to) if $opt_zip; 1080*cdf0e10cSrcweir push_on_loglist("ADDINCPATH", "$from", "$to") if $opt_log; 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir if ( $opt_delete ) { 1083*cdf0e10cSrcweir print "REMOVE: $to\n" if $opt_verbose; 1084*cdf0e10cSrcweir my $rc = unlink($to); 1085*cdf0e10cSrcweir return 1 if $rc; 1086*cdf0e10cSrcweir return 0; 1087*cdf0e10cSrcweir } 1088*cdf0e10cSrcweir 1089*cdf0e10cSrcweir if ( $from_stat_ref = is_newer($from, $to) ) { 1090*cdf0e10cSrcweir print "ADDINCPATH: $from -> $to\n" if $opt_verbose; 1091*cdf0e10cSrcweir 1092*cdf0e10cSrcweir return 1 if $opt_check; 1093*cdf0e10cSrcweir 1094*cdf0e10cSrcweir my $save = $/; 1095*cdf0e10cSrcweir undef $/; 1096*cdf0e10cSrcweir open(FROM, "<$from"); 1097*cdf0e10cSrcweir # slurp whole file in one big string 1098*cdf0e10cSrcweir my $content = <FROM>; 1099*cdf0e10cSrcweir close(FROM); 1100*cdf0e10cSrcweir $/ = $save; 1101*cdf0e10cSrcweir 1102*cdf0e10cSrcweir foreach $header (@$modify_headers_ref) { 1103*cdf0e10cSrcweir $content =~ s/#include [<"]$header[>"]/#include <$module\/$header>/g; 1104*cdf0e10cSrcweir } 1105*cdf0e10cSrcweir 1106*cdf0e10cSrcweir open(TO, ">$to"); 1107*cdf0e10cSrcweir print TO $content; 1108*cdf0e10cSrcweir close(TO); 1109*cdf0e10cSrcweir 1110*cdf0e10cSrcweir utime($$from_stat_ref[9], $$from_stat_ref[9], $to); 1111*cdf0e10cSrcweir fix_file_permissions($$from_stat_ref[2], $to); 1112*cdf0e10cSrcweir return 1; 1113*cdf0e10cSrcweir } 1114*cdf0e10cSrcweir return 0; 1115*cdf0e10cSrcweir} 1116*cdf0e10cSrcweir 1117*cdf0e10cSrcweirsub push_on_ziplist 1118*cdf0e10cSrcweir{ 1119*cdf0e10cSrcweir my $file = shift; 1120*cdf0e10cSrcweir return if ( $opt_check ); 1121*cdf0e10cSrcweir # strip $dest from path since we don't want to record it in zip file 1122*cdf0e10cSrcweir if ( $file =~ s#^\Q$dest\E/##o ) { 1123*cdf0e10cSrcweir if ( $updminor ){ 1124*cdf0e10cSrcweir # strip minor from path 1125*cdf0e10cSrcweir my $ext = "%_EXT%"; 1126*cdf0e10cSrcweir $ext = expand_macros($ext); 1127*cdf0e10cSrcweir $file =~ s#^$ext##o; 1128*cdf0e10cSrcweir } 1129*cdf0e10cSrcweir push(@zip_list, $file); 1130*cdf0e10cSrcweir } elsif ( $file =~ s#^\Q$common_dest\E/##o ) { 1131*cdf0e10cSrcweir if ( $updminor ){ 1132*cdf0e10cSrcweir # strip minor from path 1133*cdf0e10cSrcweir my $ext = "%_EXT%"; 1134*cdf0e10cSrcweir $ext = expand_macros($ext); 1135*cdf0e10cSrcweir $file =~ s#^$ext##o; 1136*cdf0e10cSrcweir } 1137*cdf0e10cSrcweir push(@common_zip_list, $file); 1138*cdf0e10cSrcweir } 1139*cdf0e10cSrcweir} 1140*cdf0e10cSrcweir 1141*cdf0e10cSrcweirsub push_on_loglist 1142*cdf0e10cSrcweir{ 1143*cdf0e10cSrcweir my @entry = @_; 1144*cdf0e10cSrcweir return 0 if ( $opt_check ); 1145*cdf0e10cSrcweir return -1 if ( $#entry != 2 ); 1146*cdf0e10cSrcweir if (( $entry[0] eq "COPY" ) || ( $entry[0] eq "ADDINCPATH" )) { 1147*cdf0e10cSrcweir return 0 if ( ! -e $entry[1].$maybedot ); 1148*cdf0e10cSrcweir # make 'from' relative to source root 1149*cdf0e10cSrcweir $entry[1] = $repository ."/" . $module . "/prj/" . $entry[1]; 1150*cdf0e10cSrcweir $entry[1] =~ s/$module\/prj\/\.\./$module/; 1151*cdf0e10cSrcweir } 1152*cdf0e10cSrcweir # platform or common tree? 1153*cdf0e10cSrcweir my $common; 1154*cdf0e10cSrcweir if ( $entry[2] =~ /^\Q$dest\E/ ) { 1155*cdf0e10cSrcweir $common = 0; 1156*cdf0e10cSrcweir } elsif ( $common_build && ( $entry[2] =~ /^\Q$common_dest\E/ )) { 1157*cdf0e10cSrcweir $common = 1; 1158*cdf0e10cSrcweir } else { 1159*cdf0e10cSrcweir warn "Neither common nor platform tree?"; 1160*cdf0e10cSrcweir return; 1161*cdf0e10cSrcweir } 1162*cdf0e10cSrcweir # make 'to' relative to SOLARVERSION 1163*cdf0e10cSrcweir my $solarversion = $ENV{'SOLARVERSION'}; 1164*cdf0e10cSrcweir $solarversion =~ s#\\#/#g; 1165*cdf0e10cSrcweir $entry[2] =~ s/^\Q$solarversion\E\///; 1166*cdf0e10cSrcweir # strip minor from 'to' 1167*cdf0e10cSrcweir my $ext = "%_EXT%"; 1168*cdf0e10cSrcweir $ext = expand_macros($ext); 1169*cdf0e10cSrcweir $entry[2] =~ s#$ext([\\\/])#$1#o; 1170*cdf0e10cSrcweir 1171*cdf0e10cSrcweir if ( $common ) { 1172*cdf0e10cSrcweir push @common_log_list, [@entry]; 1173*cdf0e10cSrcweir } else { 1174*cdf0e10cSrcweir push @log_list, [@entry]; 1175*cdf0e10cSrcweir } 1176*cdf0e10cSrcweir return 1; 1177*cdf0e10cSrcweir} 1178*cdf0e10cSrcweir 1179*cdf0e10cSrcweirsub zip_files 1180*cdf0e10cSrcweir{ 1181*cdf0e10cSrcweir my $zipexe = 'zip'; 1182*cdf0e10cSrcweir $zipexe .= ' -y' unless $^O eq 'MSWin32'; 1183*cdf0e10cSrcweir 1184*cdf0e10cSrcweir my ($platform_zip_file, $common_zip_file); 1185*cdf0e10cSrcweir $platform_zip_file = "%_DEST%/zip%_EXT%/$module.zip"; 1186*cdf0e10cSrcweir $platform_zip_file = expand_macros($platform_zip_file); 1187*cdf0e10cSrcweir my (%dest_dir, %list_ref); 1188*cdf0e10cSrcweir $dest_dir{$platform_zip_file} = $dest; 1189*cdf0e10cSrcweir $list_ref{$platform_zip_file} = \@zip_list; 1190*cdf0e10cSrcweir if ( $common_build ) { 1191*cdf0e10cSrcweir $common_zip_file = "%COMMON_DEST%/zip%_EXT%/$module.zip"; 1192*cdf0e10cSrcweir $common_zip_file = expand_macros($common_zip_file); 1193*cdf0e10cSrcweir $dest_dir{$common_zip_file} = $common_dest; 1194*cdf0e10cSrcweir $list_ref{$common_zip_file} = \@common_zip_list; 1195*cdf0e10cSrcweir } 1196*cdf0e10cSrcweir 1197*cdf0e10cSrcweir my $ext = "%_EXT%"; 1198*cdf0e10cSrcweir $ext = expand_macros($ext); 1199*cdf0e10cSrcweir 1200*cdf0e10cSrcweir my @zipfiles; 1201*cdf0e10cSrcweir $zipfiles[0] = $platform_zip_file; 1202*cdf0e10cSrcweir if ( $common_build ) { 1203*cdf0e10cSrcweir push @zipfiles, ($common_zip_file); 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir foreach my $zip_file ( @zipfiles ) { 1206*cdf0e10cSrcweir print "ZIP: updating $zip_file\n" if $opt_verbose; 1207*cdf0e10cSrcweir next if ( $opt_check ); 1208*cdf0e10cSrcweir 1209*cdf0e10cSrcweir if ( $opt_delete ) { 1210*cdf0e10cSrcweir if ( -e $zip_file ) { 1211*cdf0e10cSrcweir unlink $zip_file or die "Error: can't remove file '$zip_file': $!"; 1212*cdf0e10cSrcweir } 1213*cdf0e10cSrcweir next; 1214*cdf0e10cSrcweir } 1215*cdf0e10cSrcweir 1216*cdf0e10cSrcweir local $work_file = ""; 1217*cdf0e10cSrcweir if ( $zip_file eq $common_zip_file) { 1218*cdf0e10cSrcweir # Zip file in common tree: work on uniq copy to avoid collisions 1219*cdf0e10cSrcweir $work_file = $zip_file; 1220*cdf0e10cSrcweir $work_file =~ s/\.zip$//; 1221*cdf0e10cSrcweir $work_file .= (sprintf('.%d-%d', $$, time())) . ".zip"; 1222*cdf0e10cSrcweir die "Error: temp file $work_file already exists" if ( -e $work_file); 1223*cdf0e10cSrcweir if ( -e $zip_file ) { 1224*cdf0e10cSrcweir if ( -z $zip_file) { 1225*cdf0e10cSrcweir # sometimes there are files of 0 byte size - remove them 1226*cdf0e10cSrcweir unlink $zip_file or print_error("can't remove empty file '$zip_file': $!",0); 1227*cdf0e10cSrcweir } else { 1228*cdf0e10cSrcweir if ( ! copy($zip_file, $work_file)) { 1229*cdf0e10cSrcweir # give a warning, not an error: 1230*cdf0e10cSrcweir # we can zip from scratch instead of just updating the old zip file 1231*cdf0e10cSrcweir print_warning("can't copy'$zip_file' into '$work_file': $!", 0); 1232*cdf0e10cSrcweir unlink $work_file; 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir } 1235*cdf0e10cSrcweir } 1236*cdf0e10cSrcweir } else { 1237*cdf0e10cSrcweir # No pre processing necessary, working directly on solver. 1238*cdf0e10cSrcweir $work_file = $zip_file; 1239*cdf0e10cSrcweir } 1240*cdf0e10cSrcweir 1241*cdf0e10cSrcweir # zip content has to be relative to $dest_dir 1242*cdf0e10cSrcweir chdir($dest_dir{$zip_file}) or die "Error: cannot chdir into $dest_dir{$zip_file}"; 1243*cdf0e10cSrcweir my $this_ref = $list_ref{$zip_file}; 1244*cdf0e10cSrcweir open(ZIP, "| $zipexe -q -o -u -@ $work_file") or die "error opening zip file"; 1245*cdf0e10cSrcweir foreach $file ( @$this_ref ) { 1246*cdf0e10cSrcweir print "ZIP: adding $file to $zip_file\n" if $is_debug; 1247*cdf0e10cSrcweir print ZIP "$file\n"; 1248*cdf0e10cSrcweir } 1249*cdf0e10cSrcweir close(ZIP); 1250*cdf0e10cSrcweir fix_broken_cygwin_created_zips($work_file) if $^O eq "cygwin"; 1251*cdf0e10cSrcweir 1252*cdf0e10cSrcweir if ( $zip_file eq $common_zip_file) { 1253*cdf0e10cSrcweir # rename work file back 1254*cdf0e10cSrcweir if ( -e $work_file ) { 1255*cdf0e10cSrcweir if ( -e $zip_file) { 1256*cdf0e10cSrcweir # do some tricks to be fast. otherwise we may disturb other platforms 1257*cdf0e10cSrcweir # by unlinking a file which just gets copied -> stale file handle. 1258*cdf0e10cSrcweir my $buffer_file=$work_file . '_rm'; 1259*cdf0e10cSrcweir rename($zip_file, $buffer_file) or warn "Warning: can't rename old zip file '$zip_file': $!"; 1260*cdf0e10cSrcweir if (! rename($work_file, $zip_file)) { 1261*cdf0e10cSrcweir print_error("can't rename temporary file to $zip_file: $!",0); 1262*cdf0e10cSrcweir unlink $work_file; 1263*cdf0e10cSrcweir } 1264*cdf0e10cSrcweir unlink $buffer_file; 1265*cdf0e10cSrcweir } else { 1266*cdf0e10cSrcweir if (! rename($work_file, $zip_file)) { 1267*cdf0e10cSrcweir print_error("can't rename temporary file to $zip_file: $!",0); 1268*cdf0e10cSrcweir unlink $work_file; 1269*cdf0e10cSrcweir } 1270*cdf0e10cSrcweir } 1271*cdf0e10cSrcweir } 1272*cdf0e10cSrcweir } 1273*cdf0e10cSrcweir } 1274*cdf0e10cSrcweir} 1275*cdf0e10cSrcweir 1276*cdf0e10cSrcweirsub fix_broken_cygwin_created_zips 1277*cdf0e10cSrcweir# add given extension to or strip it from stored path 1278*cdf0e10cSrcweir{ 1279*cdf0e10cSrcweir require Archive::Zip; import Archive::Zip; 1280*cdf0e10cSrcweir my $zip_file = shift; 1281*cdf0e10cSrcweir 1282*cdf0e10cSrcweir $zip = Archive::Zip->new(); 1283*cdf0e10cSrcweir unless ( $zip->read($work_file) == AZ_OK ) { 1284*cdf0e10cSrcweir die "Error: can't open zip file '$zip_file' to fix broken cygwin file permissions"; 1285*cdf0e10cSrcweir } 1286*cdf0e10cSrcweir my $latest_member_mod_time = 0; 1287*cdf0e10cSrcweir foreach $member ( $zip->members() ) { 1288*cdf0e10cSrcweir my $attributes = $member->unixFileAttributes(); 1289*cdf0e10cSrcweir $attributes &= ~0xFE00; 1290*cdf0e10cSrcweir print $member->fileName() . ": " . sprintf("%lo", $attributes) if $is_debug; 1291*cdf0e10cSrcweir $attributes |= 0x10; # add group write permission 1292*cdf0e10cSrcweir print "-> " . sprintf("%lo", $attributes) . "\n" if $is_debug; 1293*cdf0e10cSrcweir $member->unixFileAttributes($attributes); 1294*cdf0e10cSrcweir if ( $latest_member_mod_time < $member->lastModTime() ) { 1295*cdf0e10cSrcweir $latest_member_mod_time = $member->lastModTime(); 1296*cdf0e10cSrcweir } 1297*cdf0e10cSrcweir } 1298*cdf0e10cSrcweir die "Error: can't overwrite zip file '$zip_file' for fixing permissions" unless $zip->overwrite() == AZ_OK; 1299*cdf0e10cSrcweir utime($latest_member_mod_time, $latest_member_mod_time, $zip_file); 1300*cdf0e10cSrcweir} 1301*cdf0e10cSrcweir 1302*cdf0e10cSrcweirsub get_tempfilename 1303*cdf0e10cSrcweir{ 1304*cdf0e10cSrcweir my $temp_dir = shift; 1305*cdf0e10cSrcweir $temp_dir = ( -d '/tmp' ? '/tmp' : $ENV{TMPDIR} || $ENV{TEMP} || '.' ) 1306*cdf0e10cSrcweir unless defined($temp_dir); 1307*cdf0e10cSrcweir if ( ! -d $temp_dir ) { 1308*cdf0e10cSrcweir die "no temp directory $temp_dir\n"; 1309*cdf0e10cSrcweir } 1310*cdf0e10cSrcweir my $base_name = sprintf( "%d-%di-%d", $$, time(), $tempcounter++ ); 1311*cdf0e10cSrcweir return "$temp_dir/$base_name"; 1312*cdf0e10cSrcweir} 1313*cdf0e10cSrcweir 1314*cdf0e10cSrcweirsub write_log 1315*cdf0e10cSrcweir{ 1316*cdf0e10cSrcweir my (%log_file, %file_date); 1317*cdf0e10cSrcweir $log_file{\@log_list} = "%_DEST%/inc%_EXT%/$module/deliver.log"; 1318*cdf0e10cSrcweir $log_file{\@common_log_list} = "%COMMON_DEST%/inc%_EXT%/$module/deliver.log"; 1319*cdf0e10cSrcweir $file_date{\@log_list} = $logfiledate; 1320*cdf0e10cSrcweir $file_date{\@common_log_list} = $commonlogfiledate; 1321*cdf0e10cSrcweir 1322*cdf0e10cSrcweir my @logs = ( \@log_list ); 1323*cdf0e10cSrcweir push @logs, ( \@common_log_list ) if ( $common_build ); 1324*cdf0e10cSrcweir foreach my $log ( @logs ) { 1325*cdf0e10cSrcweir $log_file{$log} = expand_macros( $log_file{$log} ); 1326*cdf0e10cSrcweir if ( $opt_delete ) { 1327*cdf0e10cSrcweir print "LOG: removing $log_file{$log}\n" if $opt_verbose; 1328*cdf0e10cSrcweir next if ( $opt_check ); 1329*cdf0e10cSrcweir unlink $log_file{$log}; 1330*cdf0e10cSrcweir } else { 1331*cdf0e10cSrcweir print "LOG: writing $log_file{$log}\n" if $opt_verbose; 1332*cdf0e10cSrcweir next if ( $opt_check ); 1333*cdf0e10cSrcweir open( LOGFILE, "> $log_file{$log}" ) or warn "Error: could not open log file."; 1334*cdf0e10cSrcweir foreach my $item ( @$log ) { 1335*cdf0e10cSrcweir print LOGFILE "@$item\n"; 1336*cdf0e10cSrcweir } 1337*cdf0e10cSrcweir close( LOGFILE ); 1338*cdf0e10cSrcweir utime($file_date{$log}, $file_date{$log}, $log_file{$log}); 1339*cdf0e10cSrcweir } 1340*cdf0e10cSrcweir push_on_ziplist( $log_file{$log} ) if $opt_zip; 1341*cdf0e10cSrcweir } 1342*cdf0e10cSrcweir return; 1343*cdf0e10cSrcweir} 1344*cdf0e10cSrcweir 1345*cdf0e10cSrcweirsub check_dlst 1346*cdf0e10cSrcweir{ 1347*cdf0e10cSrcweir my %createddir; 1348*cdf0e10cSrcweir my %destdir; 1349*cdf0e10cSrcweir my %destfile; 1350*cdf0e10cSrcweir # get all checkable actions to perform 1351*cdf0e10cSrcweir foreach my $action ( @action_data ) { 1352*cdf0e10cSrcweir my $path = expand_macros( $$action[1] ); 1353*cdf0e10cSrcweir if ( $$action[0] eq 'mkdir' ) { 1354*cdf0e10cSrcweir $createddir{$path} ++; 1355*cdf0e10cSrcweir } elsif (( $$action[0] eq 'copy' ) || ( $$action[0] eq 'addincpath' )) { 1356*cdf0e10cSrcweir my ($from, $to) = split(' ', $path); 1357*cdf0e10cSrcweir my ($to_fname, $to_dir); 1358*cdf0e10cSrcweir my $withwildcard = 0; 1359*cdf0e10cSrcweir if ( $from =~ /[\*\?\[\]]/ ) { 1360*cdf0e10cSrcweir $withwildcard = 1; 1361*cdf0e10cSrcweir } 1362*cdf0e10cSrcweir ($to_fname, $to_dir) = fileparse($to); 1363*cdf0e10cSrcweir if ( $withwildcard ) { 1364*cdf0e10cSrcweir if ( $to !~ /[\*\?\[\]]/ ) { 1365*cdf0e10cSrcweir $to_dir = $to; 1366*cdf0e10cSrcweir $to_fname =''; 1367*cdf0e10cSrcweir } 1368*cdf0e10cSrcweir } 1369*cdf0e10cSrcweir $to_dir =~ s/[\\\/\s]$//; 1370*cdf0e10cSrcweir $destdir{$to_dir} ++; 1371*cdf0e10cSrcweir # Check: copy into non existing directory? 1372*cdf0e10cSrcweir if ( ! $createddir{$to_dir} ) { 1373*cdf0e10cSrcweir # unfortunately it is not so easy: it's OK if a subdirectory of $to_dir 1374*cdf0e10cSrcweir # gets created, because mkpath creates the whole tree 1375*cdf0e10cSrcweir foreach my $directory ( keys %createddir ) { 1376*cdf0e10cSrcweir if ( $directory =~ /^\Q$to_dir\E[\\\/]/ ) { 1377*cdf0e10cSrcweir $createddir{$to_dir} ++; 1378*cdf0e10cSrcweir last; 1379*cdf0e10cSrcweir } 1380*cdf0e10cSrcweir } 1381*cdf0e10cSrcweir print_warning("Possibly copying into directory without creating in before: '$to_dir'") 1382*cdf0e10cSrcweir unless $createddir{$to_dir}; 1383*cdf0e10cSrcweir } 1384*cdf0e10cSrcweir # Check: overwrite file? 1385*cdf0e10cSrcweir if ( ! $to ) { 1386*cdf0e10cSrcweir if ( $destfile{$to} ) { 1387*cdf0e10cSrcweir print_warning("Multiple entries copying to '$to'"); 1388*cdf0e10cSrcweir } 1389*cdf0e10cSrcweir $destfile{$to} ++; 1390*cdf0e10cSrcweir } 1391*cdf0e10cSrcweir } 1392*cdf0e10cSrcweir } 1393*cdf0e10cSrcweir} 1394*cdf0e10cSrcweir 1395*cdf0e10cSrcweirsub cleanup 1396*cdf0e10cSrcweir{ 1397*cdf0e10cSrcweir # remove empty directories 1398*cdf0e10cSrcweir foreach my $path ( @dirlist ) { 1399*cdf0e10cSrcweir $path = expand_macros($path); 1400*cdf0e10cSrcweir if ( $opt_check ) { 1401*cdf0e10cSrcweir print "RMDIR: $path\n" if $opt_verbose; 1402*cdf0e10cSrcweir } else { 1403*cdf0e10cSrcweir rmdir $path; 1404*cdf0e10cSrcweir } 1405*cdf0e10cSrcweir } 1406*cdf0e10cSrcweir} 1407*cdf0e10cSrcweir 1408*cdf0e10cSrcweirsub delete_output 1409*cdf0e10cSrcweir{ 1410*cdf0e10cSrcweir my $output_path = expand_macros("../%__SRC%"); 1411*cdf0e10cSrcweir if ( "$output_path" ne "../" ) { 1412*cdf0e10cSrcweir if ( rmtree([$output_path], 0, 1) ) { 1413*cdf0e10cSrcweir print "Deleted output tree.\n" if $opt_verbose; 1414*cdf0e10cSrcweir } 1415*cdf0e10cSrcweir else { 1416*cdf0e10cSrcweir print_error("Error deleting output tree $output_path: $!",0); 1417*cdf0e10cSrcweir } 1418*cdf0e10cSrcweir } 1419*cdf0e10cSrcweir else { 1420*cdf0e10cSrcweir print_error("Output not deleted - INPATH is not set"); 1421*cdf0e10cSrcweir } 1422*cdf0e10cSrcweir} 1423*cdf0e10cSrcweir 1424*cdf0e10cSrcweirsub print_warning 1425*cdf0e10cSrcweir{ 1426*cdf0e10cSrcweir my $message = shift; 1427*cdf0e10cSrcweir my $line = shift; 1428*cdf0e10cSrcweir 1429*cdf0e10cSrcweir print STDERR "$script_name: "; 1430*cdf0e10cSrcweir if ( $dlst_file ) { 1431*cdf0e10cSrcweir print STDERR "$dlst_file: "; 1432*cdf0e10cSrcweir } 1433*cdf0e10cSrcweir if ( $line ) { 1434*cdf0e10cSrcweir print STDERR "line $line: "; 1435*cdf0e10cSrcweir } 1436*cdf0e10cSrcweir print STDERR "WARNING: $message\n"; 1437*cdf0e10cSrcweir} 1438*cdf0e10cSrcweir 1439*cdf0e10cSrcweirsub print_error 1440*cdf0e10cSrcweir{ 1441*cdf0e10cSrcweir my $message = shift; 1442*cdf0e10cSrcweir my $line = shift; 1443*cdf0e10cSrcweir 1444*cdf0e10cSrcweir print STDERR "$script_name: "; 1445*cdf0e10cSrcweir if ( $dlst_file ) { 1446*cdf0e10cSrcweir print STDERR "$dlst_file: "; 1447*cdf0e10cSrcweir } 1448*cdf0e10cSrcweir if ( $line ) { 1449*cdf0e10cSrcweir print STDERR "line $line: "; 1450*cdf0e10cSrcweir } 1451*cdf0e10cSrcweir print STDERR "ERROR: $message\n"; 1452*cdf0e10cSrcweir $error ++; 1453*cdf0e10cSrcweir} 1454*cdf0e10cSrcweir 1455*cdf0e10cSrcweirsub print_stats 1456*cdf0e10cSrcweir{ 1457*cdf0e10cSrcweir print "Module '$module' delivered "; 1458*cdf0e10cSrcweir if ( $error ) { 1459*cdf0e10cSrcweir print "with errors\n"; 1460*cdf0e10cSrcweir } else { 1461*cdf0e10cSrcweir print "successfully."; 1462*cdf0e10cSrcweir if ( $opt_delete ) { 1463*cdf0e10cSrcweir print " $files_copied files removed,"; 1464*cdf0e10cSrcweir } 1465*cdf0e10cSrcweir else { 1466*cdf0e10cSrcweir print " $files_copied files copied,"; 1467*cdf0e10cSrcweir } 1468*cdf0e10cSrcweir print " $files_unchanged files unchanged\n"; 1469*cdf0e10cSrcweir } 1470*cdf0e10cSrcweir} 1471*cdf0e10cSrcweir 1472*cdf0e10cSrcweirsub cleanup_and_die 1473*cdf0e10cSrcweir{ 1474*cdf0e10cSrcweir # clean up on unexpected termination 1475*cdf0e10cSrcweir my $sig = shift; 1476*cdf0e10cSrcweir if ( defined($temp_file) && -e $temp_file ) { 1477*cdf0e10cSrcweir unlink($temp_file); 1478*cdf0e10cSrcweir } 1479*cdf0e10cSrcweir if ( defined($work_file) && -e $work_file ) { 1480*cdf0e10cSrcweir unlink($work_file); 1481*cdf0e10cSrcweir print STDERR "$work_file removed\n"; 1482*cdf0e10cSrcweir } 1483*cdf0e10cSrcweir 1484*cdf0e10cSrcweir die "caught unexpected signal $sig, terminating ..."; 1485*cdf0e10cSrcweir} 1486*cdf0e10cSrcweir 1487*cdf0e10cSrcweirsub usage 1488*cdf0e10cSrcweir{ 1489*cdf0e10cSrcweir my $exit_code = shift; 1490*cdf0e10cSrcweir print STDERR "Usage:\ndeliver [OPTIONS] [DESTINATION-PATH]\n"; 1491*cdf0e10cSrcweir print STDERR "Options:\n"; 1492*cdf0e10cSrcweir print STDERR " -check just print what would happen, no actual copying of files\n"; 1493*cdf0e10cSrcweir print STDERR " -checkdlst be verbose about (possible) d.lst bugs\n"; 1494*cdf0e10cSrcweir print STDERR " -delete delete files (undeliver), use with care\n"; 1495*cdf0e10cSrcweir print STDERR " -deloutput remove the output tree after copying\n"; 1496*cdf0e10cSrcweir print STDERR " -dontdeletecommon do not delete common files (for -delete option)\n"; 1497*cdf0e10cSrcweir print STDERR " -force copy even if not newer\n"; 1498*cdf0e10cSrcweir print STDERR " -help print this message\n"; 1499*cdf0e10cSrcweir if ( !defined($ENV{GUI}) || $ENV{GUI} ne 'WNT' ) { 1500*cdf0e10cSrcweir print STDERR " -link hard link files into the solver to save disk space\n"; 1501*cdf0e10cSrcweir } 1502*cdf0e10cSrcweir print STDERR " -quiet be quiet, only report errors\n"; 1503*cdf0e10cSrcweir print STDERR " -verbose be verbose\n"; 1504*cdf0e10cSrcweir print STDERR " -zip additionally create zip files of delivered content\n"; 1505*cdf0e10cSrcweir print STDERR "Options '-zip' and a destination-path are mutually exclusive.\n"; 1506*cdf0e10cSrcweir print STDERR "Options '-check' and '-quiet' are mutually exclusive.\n"; 1507*cdf0e10cSrcweir exit($exit_code); 1508*cdf0e10cSrcweir} 1509*cdf0e10cSrcweir 1510*cdf0e10cSrcweir# vim: set ts=4 shiftwidth=4 expandtab syntax=perl: 1511