OOO330
[LibreOffice.git] / solenv / bin / linkoo
blobfe75d0d562d4f7146b0a96aa4d1b54bb8ccbe252
2     eval 'exec perl -S $0 ${1+"$@"}'
3         if 0;
5 #*************************************************************************
7 #    This app makes it easy to link a live build
8 # set into an install set. Then your devel iteration
9 # is: 'build', execute.
11 #*************************************************************************
13 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14
15 # Copyright 2000, 2010 Oracle and/or its affiliates.
17 # OpenOffice.org - a multi-platform office productivity suite
19 # This file is part of OpenOffice.org.
21 # OpenOffice.org is free software: you can redistribute it and/or modify
22 # it under the terms of the GNU Lesser General Public License version 3
23 # only, as published by the Free Software Foundation.
25 # OpenOffice.org is distributed in the hope that it will be useful,
26 # but WITHOUT ANY WARRANTY; without even the implied warranty of
27 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28 # GNU Lesser General Public License version 3 for more details
29 # (a copy is included in the LICENSE file that accompanied this code).
31 # You should have received a copy of the GNU Lesser General Public License
32 # version 3 along with OpenOffice.org.  If not, see
33 # <http://www.openoffice.org/license.html>
34 # for a copy of the LGPLv3 License.
36 #*************************************************************************
38 # ends up in program/ooenv
39 ( $moz_lib = `pkg-config --variable=libdir mozilla-nss` ) =~ tr/\n/:/;
40 $env_script = '
41 java_path=`./javaldx`
42 export LD_LIBRARY_PATH=".:$java_path:' . $moz_lib . '$LD_LIBRARY_PATH"
43 ulimit -c unlimited
44 export PATH=".:$PATH"
45 export GNOME_DISABLE_CRASH_DIALOG=1
46 export STAR_RESOURCEPATH=`pwd`/resource
47 # debugging assistance
48 export OOO_FORCE_SYSALLOC=1
49 export MALLOC_CHECK_=2
50 export OOO_DISABLE_RECOVERY=1
53 $program_dir = 'program';
54 $program_dir = 'MacOS' if ($ENV{OS} eq 'MACOSX');
56 my @exceptions = ( 'cppuhelper', 'sunjavaplugin', 'libjvmfwk' );
58 %replaceable = (
59         $program_dir => '\.so',
60     $program_dir . '/resource' => '\.res$',
61     $program_dir . '/classes' => '\.jar$',
62     'share/config' => '\.zip$',
63 #    'share/uno_packages' => '\.zip$'
66 # strangely enough, OSX has those small differences...
67 $replaceable{$program_dir} = '\.dylib$' if ($ENV{OS} eq 'MACOSX');
69 @search_dirs = ( 'lib', 'bin', 'class' );
71 @known_duplicates = ( 'db.jar', 'libi18n' );
73 sub sniff_target($)
75     my $build_dir = shift;
76     my ($dirhandle, $fname);
77     my ($target, $libver, $lang) = ( 'unxlngi4.pro', '680', 'en-US' ); # defaults
78     
79     opendir ($dirhandle, $build_dir) || die "Can't open $build_dir";
80     while ($fname = readdir ($dirhandle)) {
81         $fname =~ /Set.sh$/ || next;
82         
83         my $file;
84         open ($file, "$build_dir/$fname") || die "Can't open $build_dir/$fname";
85         while (<$file>) {
86             /\s*(\S+)\s*=\s*\"(\S+)\"/ || next;
87             if ($1 eq 'INPATH') {
88                 $target = $2;
89             }
90             if ($1 eq 'UPD') {
91                 $libver = $2;
92             }
93         }
94         close ($file);
95     }
97     closedir ($dirhandle);
99     print "Sniffed target: $target, $libver\n";
101     return ($target, $libver, $lang);
104 sub build_installed_list($)
106     my $path = shift;
107     my %files = ();
109     for my $suffix (keys %replaceable) {
110         my $dirname = "$path/$suffix";
111         my $dirhandle;
112         my $pattern = $replaceable{$suffix};
113         if (opendir ($dirhandle, $dirname)) {
114             while (my $fname = readdir ($dirhandle)) {
115                 $fname =~ m/$pattern/ || next;
117                 my $skip = 0;
118                 for $pattern (@exceptions) {
119                     $fname =~ /$pattern/ || next;
120                     $skip = 1;
121                 }
122                 $files{$fname} = $dirname if !$skip;
123             }
124             closedir ($dirhandle);
125         } else {
126             print "Couldn't find '$dirname': skipping\n";
127         }
128     }
129     return \%files;
132 sub check_create_linked($)
134     my $path = shift;
135     my $linked_dir = "$path/linked";
136     if (! -d $linked_dir) {
137         mkdir $linked_dir || die "Can't make $linked_dir: $!";
138     }
141 sub do_link($$$$@)
143     my $src = shift;
144     my $dest = shift;
145     my $src_name = shift;
146     my $dest_name = shift;
147     my $dont_check_link = shift;
149     if (-l "$dest/$dest_name" ) {
150         my $link = readlink ("$dest/$dest_name");
151         if ($link =~ /^\//) { # Absolute path
152             if (!$dry_run) {
153                 # re-write the link
154                 unlink ("$dest/$dest_name");
155                 symlink ("$src/$src_name", "$dest/$dest_name") || die "Failed to symlink: $!";
156                 print " [$dest_name]";
157             } else {
158                 print "re-make link $src/$src_name => $dest/$dest_name\n";
159             }
160         } elsif ($dry_run) {
161             print "skipping symbolic link $dest/$dest_name -> $link\n";
162         }
163     } else {
164         check_create_linked ($dest);
165         if (!$dry_run) {
166             # move / write the link
167             rename ("$dest/$dest_name", "$dest/linked/$dest_name") ||
168                 defined $dont_check_link || die "Failed rename of $dest/$dest_name: $!";
170             symlink ("$src/$src_name", "$dest/$dest_name") || die "Failed to symlink: $!";
171             print " $dest_name";
172         } else {
173             print "move / symlink $src/$src_name => $dest/$dest_name\n";
174         }
175     }
178 sub scan_and_link_files($$$)
180     my $build_path = shift;
181     my $installed_files = shift;
182     my $target = shift;
183     
184     my @modules = ();
185     my $dirh_toplevel;
186     opendir ($dirh_toplevel, $build_path) || die "Can't open '$build_path': $!";
187     while (my $subdir = readdir ($dirh_toplevel)) {
188         $subdir =~ m/\./ && next; # eg. vcl.old,
189         my $test = "$build_path/$subdir/$target";
190         -d $test || next;
191         push @modules, $test;
192     }
193     closedir ($dirh_toplevel);
195 # FIXME: re-implement the $product functionality
196     my $module;
197     my %build_files;
198     for $module (@modules) {
199         for $elem (@search_dirs) {
200             my $dirh_module;
201             my $module_path = "$module/$elem";
202             if (opendir ($dirh_module, $module_path)) {
203                         while (my $file = readdir($dirh_module)) {
204                                 if (defined $installed_files->{$file}) {
205                                         if (defined $build_files{$file}) {
206                                                 my $known = 0;
207                                                 for my $regexp (@known_duplicates) {
208                                                         if ($file =~ m/$regexp/) {
209                                                                 $known = 1;
210                                                         }
211                                                 }
212                                                 if (!$known) {
213                                                         print "Unknown duplicate file '$file' in: '" . 
214                                                         $build_files{$file} . "' vs '" .
215                                                         $module_path . "' in module $module\n";
216                                                         exit (1);
217                                                 }
218                                         }
219                                         $build_files{$file} = $module_path;
220                                 }
221                         }
222                 }
223             closedir ($dirh_module);
224         }
225     }
227     for my $file (keys %build_files) {
228         my $src = $build_files{$file};
229         my $dest = $installed_files->{$file};
230         
231         do_link ($src, $dest, $file, $file);
232     }
233     print "\n";
236 sub evilness($)
238     my $doit = shift;
239     my $name = 'librecentfile.so';
240     my $src  = "$OOO_BUILD/shell/$TARGET/lib/$name";
241     my $dest = "$OOO_BUILD/sfx2/$TARGET/lib/$name";
243     if ($doit eq 'undo') {
244         if (-l $dest) {
245             print " unlink $name\n";
246             unlink $dest;
247         }
248     } else {
249         $doit eq 'do' || die;
250         if (-f $src) {
251             print " link $name\n";
252             symlink $src, $dest;
253         }
254     }
257 sub link_iso_res()
259     print "Special iso.res case: ";
260     my $ooo_res="$OOO_INSTALL/" . $program_dir . "/resource/ooo".$LIBVER.$LANG.".res";
261     my $star_res="$OOO_INSTALL/" . $program_dir . "/resource/iso".$LIBVER.$LANG.".res";
262     if (-l $ooo_res && -l $star_res) {
263         if ($dry_run) {
264             print "link $ooo_res to $star_res";
265         } else {
266             unlink ($star_res);
267             symlink ($ooo_res, $star_res);
268             print "clobbered";
269         }
270     }
271     print "\n";
274 # Hack for (renamed) types.rdb (types.db)
275 sub link_types_rdb()
277     print "Types.rdb case:";
278     my $src  = "$OOO_BUILD/offapi/$TARGET/ucr";
279     my $dest = "$OOO_INSTALL/" . $program_dir;
280     do_link ($src, $dest, 'types.db', 'types.rdb');
281     print "\n";
284 # link installed files back into src tree:
285 sub link_soffice_bin_files()
287     my $dest;
288     my $src = "$OOO_INSTALL/" . $program_dir;
290     print "soffice files";
291     $dest = "$OOO_BUILD/desktop/$TARGET/bin";
292     do_link ($src, $dest, 'soffice', 'soffice.bin', 1);
293     do_link ($src, $dest, 'bootstraprc', 'bootstraprc', 1);
294     do_link ($src, $dest, 'intro.bmp', 'intro.bmp', 1);
295     do_link ("$OOO_INSTALL", "$OOO_BUILD/desktop/$TARGET", 'share', 'share', 1);
297     print "\n";
300 my $a;
301 my $usage = 0;
302 for $a (@ARGV) {
304 # options
305     if ($a =~ /--product/) {
306         $product = 1;
307     } elsif ($a =~ /--dry-run/) {
308         $dry_run = 1;
309     } elsif (($a eq '--help') || ($a eq '-h')) {
310         $usage = 1;
312 # ordered arguments
313     } elsif (!defined $OOO_INSTALL) {
314         $OOO_INSTALL = $a;
315     } elsif (!defined $OOO_BUILD) {
316         $OOO_BUILD = $a;
317     } else {
318         print "Unknown argument '$a'\n";
319         $usage = 1;
320     }
323 if (!defined $OOO_BUILD && defined $ENV{SRC_ROOT}) {
324     $OOO_BUILD = $ENV{SRC_ROOT};
327 if ($usage || !defined $OOO_INSTALL || !defined $OOO_BUILD) {
328     printf "Usage: linkoo </path/to/ooo/install> [</path/to/ooo/build/tree>] [--product] [--dry-run]\n";
329     exit (1);
332 substr ($OOO_INSTALL, 0, 1) eq '/' || die "linkoo requires absolute paths ($OOO_INSTALL does not qualify)";
333 substr ($OOO_BUILD, 0, 1)   eq '/' || die "linkoo requires absolute paths ($OOO_BUILD does not qualify)";
335 -d $OOO_INSTALL || die "No such directory $OOO_INSTALL";
336 -w $OOO_INSTALL || die "You need write access to $OOO_INSTALL";
337 -d $OOO_BUILD || die "No such directory $OOO_BUILD";
338 -d "$OOO_INSTALL/" . $program_dir . "/resource" || die "$OOO_INSTALL doesn't look like an OO install";
340 ($TARGET, $LIBVER, $LANG) = sniff_target ($OOO_BUILD);
342 evilness ('undo');
344 my $installed_files = build_installed_list ($OOO_INSTALL);
346 scan_and_link_files ($OOO_BUILD, $installed_files, $TARGET);
347 link_iso_res();
348 link_types_rdb();
349 link_soffice_bin_files();
351 if (!-f "$OOO_INSTALL/" . $program_dir . "/ooenv") {
352     print "Creating '$OOO_INSTALL/", $program_dir, "/ooenv'\n";
353     open ($ooenv, ">$OOO_INSTALL/" . $program_dir . "/ooenv") || die "Can't open $OOO_INSTALL/" . $program_dir . "/ooenv: $!";
354     print $ooenv $env_script;
355     close ($ooenv);
358 evilness ('do');
360 print "\nlinkoo finished, please don't forget to source ooenv before ./soffice.\n";