xref: /trunk/main/solenv/bin/linkoo (revision cdf0e10c)
1:
2    eval 'exec perl -S $0 ${1+"$@"}'
3        if 0;
4
5#*************************************************************************
6#
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.
10#
11#*************************************************************************
12#
13# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14#
15# Copyright 2000, 2010 Oracle and/or its affiliates.
16#
17# OpenOffice.org - a multi-platform office productivity suite
18#
19# This file is part of OpenOffice.org.
20#
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.
24#
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).
30#
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.
35#
36#*************************************************************************
37
38# ends up in program/ooenv
39( $moz_lib = `pkg-config --variable=libdir mozilla-nss` ) =~ tr/\n/:/;
40$env_script = '
41java_path=`./javaldx`
42export LD_LIBRARY_PATH=".:$java_path:' . $moz_lib . '$LD_LIBRARY_PATH"
43ulimit -c unlimited
44export PATH=".:$PATH"
45export GNOME_DISABLE_CRASH_DIALOG=1
46export STAR_RESOURCEPATH=`pwd`/resource
47# debugging assistance
48export OOO_FORCE_SYSALLOC=1
49export MALLOC_CHECK_=2
50export OOO_DISABLE_RECOVERY=1
51';
52
53$program_dir = 'program';
54$program_dir = 'MacOS' if ($ENV{OS} eq 'MACOSX');
55
56my @exceptions = ( 'cppuhelper', 'sunjavaplugin', 'libjvmfwk' );
57
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$'
64);
65
66# strangely enough, OSX has those small differences...
67$replaceable{$program_dir} = '\.dylib$' if ($ENV{OS} eq 'MACOSX');
68
69@search_dirs = ( 'lib', 'bin', 'class' );
70
71@known_duplicates = ( 'db.jar', 'libi18n' );
72
73sub sniff_target($)
74{
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    }
96
97    closedir ($dirhandle);
98
99    print "Sniffed target: $target, $libver\n";
100
101    return ($target, $libver, $lang);
102}
103
104sub build_installed_list($)
105{
106    my $path = shift;
107    my %files = ();
108
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;
116
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;
130}
131
132sub check_create_linked($)
133{
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    }
139}
140
141sub do_link($$$$@)
142{
143    my $src = shift;
144    my $dest = shift;
145    my $src_name = shift;
146    my $dest_name = shift;
147    my $dont_check_link = shift;
148
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: $!";
169
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    }
176}
177
178sub scan_and_link_files($$$)
179{
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);
194
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    }
226
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";
234}
235
236sub evilness($)
237{
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";
242
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    }
255}
256
257sub link_iso_res()
258{
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";
272}
273
274# Hack for (renamed) types.rdb (types.db)
275sub link_types_rdb()
276{
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";
282}
283
284# link installed files back into src tree:
285sub link_soffice_bin_files()
286{
287    my $dest;
288    my $src = "$OOO_INSTALL/" . $program_dir;
289
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);
296
297    print "\n";
298}
299
300my $a;
301my $usage = 0;
302for $a (@ARGV) {
303
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;
311
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    }
321}
322
323if (!defined $OOO_BUILD && defined $ENV{SRC_ROOT}) {
324    $OOO_BUILD = $ENV{SRC_ROOT};
325}
326
327if ($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);
330}
331
332substr ($OOO_INSTALL, 0, 1) eq '/' || die "linkoo requires absolute paths ($OOO_INSTALL does not qualify)";
333substr ($OOO_BUILD, 0, 1)   eq '/' || die "linkoo requires absolute paths ($OOO_BUILD does not qualify)";
334
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";
339
340($TARGET, $LIBVER, $LANG) = sniff_target ($OOO_BUILD);
341
342evilness ('undo');
343
344my $installed_files = build_installed_list ($OOO_INSTALL);
345
346scan_and_link_files ($OOO_BUILD, $installed_files, $TARGET);
347link_iso_res();
348link_types_rdb();
349link_soffice_bin_files();
350
351if (!-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);
356}
357
358evilness ('do');
359
360print "\nlinkoo finished, please don't forget to source ooenv before ./soffice.\n";
361