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