1: 2 eval 'exec perl -S $0 ${1+"$@"}' 3 if 0; 4 5#************************************************************** 6# 7# Licensed to the Apache Software Foundation (ASF) under one 8# or more contributor license agreements. See the NOTICE file 9# distributed with this work for additional information 10# regarding copyright ownership. The ASF licenses this file 11# to you under the Apache License, Version 2.0 (the 12# "License"); you may not use this file except in compliance 13# with the License. You may obtain a copy of the License at 14# 15# http://www.apache.org/licenses/LICENSE-2.0 16# 17# Unless required by applicable law or agreed to in writing, 18# software distributed under the License is distributed on an 19# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 20# KIND, either express or implied. See the License for the 21# specific language governing permissions and limitations 22# under the License. 23# 24#************************************************************** 25# 26# This app makes it easy to link a live build 27# set into an install set. Then your devel iteration 28# is: 'build', execute. 29# 30#************************************************************************* 31 32# ends up in program/ooenv 33( $moz_lib = `pkg-config --variable=libdir mozilla-nss` ) =~ tr/\n/:/; 34$env_script = ' 35java_path=`./javaldx` 36export LD_LIBRARY_PATH=".:$java_path:' . $moz_lib . '$LD_LIBRARY_PATH" 37ulimit -c unlimited 38export PATH=".:$PATH" 39export GNOME_DISABLE_CRASH_DIALOG=1 40export STAR_RESOURCEPATH=`pwd`/resource 41# debugging assistance 42export OOO_FORCE_SYSALLOC=1 43export MALLOC_CHECK_=2 44export OOO_DISABLE_RECOVERY=1 45'; 46 47$program_dir = 'program'; 48$program_dir = 'MacOS' if ($ENV{OS} eq 'MACOSX'); 49 50my @exceptions = ( 'cppuhelper', 'sunjavaplugin', 'libjvmfwk' ); 51 52%replaceable = ( 53 $program_dir => '\.so', 54 $program_dir . '/resource' => '\.res$', 55 $program_dir . '/classes' => '\.jar$', 56 'share/config' => '\.zip$', 57# 'share/uno_packages' => '\.zip$' 58); 59 60# strangely enough, OSX has those small differences... 61$replaceable{$program_dir} = '\.dylib$' if ($ENV{OS} eq 'MACOSX'); 62 63@search_dirs = ( 'lib', 'bin', 'class' ); 64 65@known_duplicates = ( 'db.jar', 'libi18n' ); 66 67sub sniff_target($) 68{ 69 my $build_dir = shift; 70 my ($dirhandle, $fname); 71 my ($target, $libver, $lang) = ( 'unxlngi4.pro', '680', 'en-US' ); # defaults 72 73 opendir ($dirhandle, $build_dir) || die "Can't open $build_dir"; 74 while ($fname = readdir ($dirhandle)) { 75 $fname =~ /Set.sh$/ || next; 76 77 my $file; 78 open ($file, "$build_dir/$fname") || die "Can't open $build_dir/$fname"; 79 while (<$file>) { 80 /\s*(\S+)\s*=\s*\"(\S+)\"/ || next; 81 if ($1 eq 'INPATH') { 82 $target = $2; 83 } 84 if ($1 eq 'UPD') { 85 $libver = $2; 86 } 87 } 88 close ($file); 89 } 90 91 closedir ($dirhandle); 92 93 print "Sniffed target: $target, $libver\n"; 94 95 return ($target, $libver, $lang); 96} 97 98sub build_installed_list($) 99{ 100 my $path = shift; 101 my %files = (); 102 103 for my $suffix (keys %replaceable) { 104 my $dirname = "$path/$suffix"; 105 my $dirhandle; 106 my $pattern = $replaceable{$suffix}; 107 if (opendir ($dirhandle, $dirname)) { 108 while (my $fname = readdir ($dirhandle)) { 109 $fname =~ m/$pattern/ || next; 110 111 my $skip = 0; 112 for $pattern (@exceptions) { 113 $fname =~ /$pattern/ || next; 114 $skip = 1; 115 } 116 $files{$fname} = $dirname if !$skip; 117 } 118 closedir ($dirhandle); 119 } else { 120 print "Couldn't find '$dirname': skipping\n"; 121 } 122 } 123 return \%files; 124} 125 126sub check_create_linked($) 127{ 128 my $path = shift; 129 my $linked_dir = "$path/linked"; 130 if (! -d $linked_dir) { 131 mkdir $linked_dir || die "Can't make $linked_dir: $!"; 132 } 133} 134 135sub do_link($$$$@) 136{ 137 my $src = shift; 138 my $dest = shift; 139 my $src_name = shift; 140 my $dest_name = shift; 141 my $dont_check_link = shift; 142 143 if (-l "$dest/$dest_name" ) { 144 my $link = readlink ("$dest/$dest_name"); 145 if ($link =~ /^\//) { # Absolute path 146 if (!$dry_run) { 147 # re-write the link 148 unlink ("$dest/$dest_name"); 149 symlink ("$src/$src_name", "$dest/$dest_name") || die "Failed to symlink: $!"; 150 print " [$dest_name]"; 151 } else { 152 print "re-make link $src/$src_name => $dest/$dest_name\n"; 153 } 154 } elsif ($dry_run) { 155 print "skipping symbolic link $dest/$dest_name -> $link\n"; 156 } 157 } else { 158 check_create_linked ($dest); 159 if (!$dry_run) { 160 # move / write the link 161 rename ("$dest/$dest_name", "$dest/linked/$dest_name") || 162 defined $dont_check_link || die "Failed rename of $dest/$dest_name: $!"; 163 164 symlink ("$src/$src_name", "$dest/$dest_name") || die "Failed to symlink: $!"; 165 print " $dest_name"; 166 } else { 167 print "move / symlink $src/$src_name => $dest/$dest_name\n"; 168 } 169 } 170} 171 172sub scan_and_link_files($$$) 173{ 174 my $build_path = shift; 175 my $installed_files = shift; 176 my $target = shift; 177 178 my @modules = (); 179 my $dirh_toplevel; 180 opendir ($dirh_toplevel, $build_path) || die "Can't open '$build_path': $!"; 181 while (my $subdir = readdir ($dirh_toplevel)) { 182 $subdir =~ m/\./ && next; # eg. vcl.old, 183 my $test = "$build_path/$subdir/$target"; 184 -d $test || next; 185 push @modules, $test; 186 } 187 closedir ($dirh_toplevel); 188 189# FIXME: re-implement the $product functionality 190 my $module; 191 my %build_files; 192 for $module (@modules) { 193 for $elem (@search_dirs) { 194 my $dirh_module; 195 my $module_path = "$module/$elem"; 196 if (opendir ($dirh_module, $module_path)) { 197 while (my $file = readdir($dirh_module)) { 198 if (defined $installed_files->{$file}) { 199 if (defined $build_files{$file}) { 200 my $known = 0; 201 for my $regexp (@known_duplicates) { 202 if ($file =~ m/$regexp/) { 203 $known = 1; 204 } 205 } 206 if (!$known) { 207 print "Unknown duplicate file '$file' in: '" . 208 $build_files{$file} . "' vs '" . 209 $module_path . "' in module $module\n"; 210 exit (1); 211 } 212 } 213 $build_files{$file} = $module_path; 214 } 215 } 216 } 217 closedir ($dirh_module); 218 } 219 } 220 221 for my $file (keys %build_files) { 222 my $src = $build_files{$file}; 223 my $dest = $installed_files->{$file}; 224 225 do_link ($src, $dest, $file, $file); 226 } 227 print "\n"; 228} 229 230sub evilness($) 231{ 232 my $doit = shift; 233 my $name = 'librecentfile.so'; 234 my $src = "$OOO_BUILD/shell/$TARGET/lib/$name"; 235 my $dest = "$OOO_BUILD/sfx2/$TARGET/lib/$name"; 236 237 if ($doit eq 'undo') { 238 if (-l $dest) { 239 print " unlink $name\n"; 240 unlink $dest; 241 } 242 } else { 243 $doit eq 'do' || die; 244 if (-f $src) { 245 print " link $name\n"; 246 symlink $src, $dest; 247 } 248 } 249} 250 251sub link_iso_res() 252{ 253 print "Special iso.res case: "; 254 my $ooo_res="$OOO_INSTALL/" . $program_dir . "/resource/ooo".$LIBVER.$LANG.".res"; 255 my $star_res="$OOO_INSTALL/" . $program_dir . "/resource/iso".$LIBVER.$LANG.".res"; 256 if (-l $ooo_res && -l $star_res) { 257 if ($dry_run) { 258 print "link $ooo_res to $star_res"; 259 } else { 260 unlink ($star_res); 261 symlink ($ooo_res, $star_res); 262 print "clobbered"; 263 } 264 } 265 print "\n"; 266} 267 268# Hack for (renamed) types.rdb (types.db) 269sub link_types_rdb() 270{ 271 print "Types.rdb case:"; 272 my $src = "$OOO_BUILD/offapi/$TARGET/ucr"; 273 my $dest = "$OOO_INSTALL/" . $program_dir; 274 do_link ($src, $dest, 'types.db', 'types.rdb'); 275 print "\n"; 276} 277 278# link installed files back into src tree: 279sub link_soffice_bin_files() 280{ 281 my $dest; 282 my $src = "$OOO_INSTALL/" . $program_dir; 283 284 print "soffice files"; 285 $dest = "$OOO_BUILD/desktop/$TARGET/bin"; 286 do_link ($src, $dest, 'soffice', 'soffice.bin', 1); 287 do_link ($src, $dest, 'bootstraprc', 'bootstraprc', 1); 288 do_link ($src, $dest, 'intro.bmp', 'intro.bmp', 1); 289 do_link ("$OOO_INSTALL", "$OOO_BUILD/desktop/$TARGET", 'share', 'share', 1); 290 291 print "\n"; 292} 293 294my $a; 295my $usage = 0; 296for $a (@ARGV) { 297 298# options 299 if ($a =~ /--product/) { 300 $product = 1; 301 } elsif ($a =~ /--dry-run/) { 302 $dry_run = 1; 303 } elsif (($a eq '--help') || ($a eq '-h')) { 304 $usage = 1; 305 306# ordered arguments 307 } elsif (!defined $OOO_INSTALL) { 308 $OOO_INSTALL = $a; 309 } elsif (!defined $OOO_BUILD) { 310 $OOO_BUILD = $a; 311 } else { 312 print "Unknown argument '$a'\n"; 313 $usage = 1; 314 } 315} 316 317if (!defined $OOO_BUILD && defined $ENV{SRC_ROOT}) { 318 $OOO_BUILD = $ENV{SRC_ROOT}; 319} 320 321if ($usage || !defined $OOO_INSTALL || !defined $OOO_BUILD) { 322 printf "Usage: linkoo </path/to/ooo/install> [</path/to/ooo/build/tree>] [--product] [--dry-run]\n"; 323 exit (1); 324} 325 326substr ($OOO_INSTALL, 0, 1) eq '/' || die "linkoo requires absolute paths ($OOO_INSTALL does not qualify)"; 327substr ($OOO_BUILD, 0, 1) eq '/' || die "linkoo requires absolute paths ($OOO_BUILD does not qualify)"; 328 329-d $OOO_INSTALL || die "No such directory $OOO_INSTALL"; 330-w $OOO_INSTALL || die "You need write access to $OOO_INSTALL"; 331-d $OOO_BUILD || die "No such directory $OOO_BUILD"; 332-d "$OOO_INSTALL/" . $program_dir . "/resource" || die "$OOO_INSTALL doesn't look like an OO install"; 333 334($TARGET, $LIBVER, $LANG) = sniff_target ($OOO_BUILD); 335 336evilness ('undo'); 337 338my $installed_files = build_installed_list ($OOO_INSTALL); 339 340scan_and_link_files ($OOO_BUILD, $installed_files, $TARGET); 341link_iso_res(); 342link_types_rdb(); 343link_soffice_bin_files(); 344 345if (!-f "$OOO_INSTALL/" . $program_dir . "/ooenv") { 346 print "Creating '$OOO_INSTALL/", $program_dir, "/ooenv'\n"; 347 open ($ooenv, ">$OOO_INSTALL/" . $program_dir . "/ooenv") || die "Can't open $OOO_INSTALL/" . $program_dir . "/ooenv: $!"; 348 print $ooenv $env_script; 349 close ($ooenv); 350} 351 352evilness ('do'); 353 354print "\nlinkoo finished, please don't forget to source ooenv before ./soffice.\n"; 355