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