1################################################################################
2
3use strict;
4
5require 'install.prl';
6
7use Config;
8use Cwd        "abs_path";
9use File::Copy "copy";
10use File::Copy::Recursive qw(dircopy);
11use File::Path   "make_path";
12use FindBin    qw($Bin);
13use Getopt::Long "GetOptions";
14
15my ($OS, $MAKING, %INSTALLED_LIBS);
16{
17    my $file = 'os.prl';
18    if (-e $file) {
19        require $file;
20        $OS = OS();
21    } else {
22        ++$MAKING;
23    }
24}
25
26my %HAVE = HAVE();
27BINS() if ($HAVE{BINS});
28if ($HAVE{LIBS}) {
29    ++$HAVE{INCLUDES};
30    LIBS();
31}
32if ($HAVE{INCLUDES} || $HAVE{USR_INCLUDES}) {
33    die "no INCLUDES" unless INCLUDES();
34}
35die "no CONFIG_OUT" unless CONFIG_OUT();
36
37my @bits;
38my @options = ( 'debug', 'examplesdir=s', 'force', 'help',
39                'includedir=s', 'no-create', 'prefix=s', 'root=s', );
40push @options, 'oldincludedir=s' if ($HAVE{USR_INCLUDES});
41if ($HAVE{JAR}) {
42    push @options, 'jardir=s';
43    if (-e "$Bin/../jar") {
44        ++$HAVE{LIBS};
45        $_{JARDIR} = expand_path("$Bin/../jar");
46    }
47} elsif ($HAVE{PYTHON} && ! $MAKING) {
48    ++$HAVE{LIBS};
49}
50if (! $MAKING && ($HAVE{JAR} || $HAVE{PYTHON})) {
51    ++$HAVE{TWO_LIBS};
52    push @options, 'ngslibdir=s', 'vdblibdir=s';
53}
54push @options, 'bindir=s'                     if ($HAVE{BINS});
55push @options, 'bits=s' => \@bits, 'libdir=s' if ($HAVE{LIBS});
56
57my %OPT;
58unless (GetOptions(\%OPT, @options)) {
59    print "install: error\n";
60    exit 1;
61}
62@bits = split(/,/,join(',',@bits));
63foreach (@bits) {
64    unless (/^32$/ || /^64$/) {
65        print "install: error: bad bits option argument value\n";
66        exit 1;
67    }
68}
69if ($#bits > 0) {
70    foreach (qw(bindir libdir ngslibdir vdblibdir)) {
71        if ($OPT{$_}) {
72            print "install: error: cannot supply multiple bits arguments "
73                . "when $_ argument is provided\n";
74            exit 1;
75        }
76    }
77}
78
79$OPT{root} = expand_path($OPT{root}) if ($OPT{root});
80
81prepare();
82
83my $LINUX_ROOT;
84++$LINUX_ROOT if (linux_root());
85my $ROOT = '';
86if ($OPT{root}) {
87    $ROOT = "$OPT{root}/root";
88    ++$LINUX_ROOT;
89    foreach ("$ROOT/usr/include", "$ROOT/etc/profile.d") {
90        unless (-e $_) {
91            print "mkdir -p $_... ";
92            eval { make_path($_) };
93            if ($@) {
94                print "failure: $@\n";
95                exit 1;
96            }
97            print "ok\n";
98        }
99    }
100}
101
102my $oldincludedir = "$ROOT/usr/include";
103
104my $EXAMPLES_DIR = "$Bin/../examples";
105
106@_ = CONFIGURE();
107
108if ($OPT{help}) {
109    help();
110    exit 0;
111}
112
113foreach (qw(BITS INCDIR
114 INST_INCDIR INST_JARDIR INST_LIBDIR INST_NGSLIBDIR INST_SHAREDIR INST_VDBLIBDIR
115 LIBX LPFX MAJVERS MAJVERS_SHLX OS OTHER_PREFIX
116 PACKAGE_NAME PREFIX SHLX VERSION VERSION_LIBX VERSION_SHLX))
117{
118    unless ($_{$_}) {
119        next if (/^INST_JARDIR$/    && ! $HAVE{JAR});
120        next if (/^INST_NGSLIBDIR$/ && ! $HAVE{TWO_LIBS});
121        next if (/^INST_SHAREDIR$/  && ! $HAVE{EXAMPLES});
122        next if (/^INST_VDBLIBDIR$/ && ! $HAVE{TWO_LIBS});
123        fatal_config("$_ not found");
124    }
125}
126unless ($_{LIBDIR32} || $_{LIBDIR64} || ($HAVE{PYTHON} && $MAKING)) {
127    fatal_config('LIBDIR not found');
128}
129
130if ($OPT{prefix}) {
131    $OPT{prefix} = expand_path($OPT{prefix});
132    $_{INST_BINDIR  } = "$OPT{prefix}/bin";
133    $_{INST_LIBDIR  } = "$OPT{prefix}/lib";
134    $_{INST_NGSLIBDIR} = $_{INST_VDBLIBDIR} = $_{INST_LIBDIR};
135    $_{INST_INCDIR  } = "$OPT{prefix}/include";
136    $_{INST_JARDIR  } = "$OPT{prefix}/jar";
137    $_{INST_SHAREDIR} = "$OPT{prefix}/share";
138}
139$_{INST_SHAREDIR} = expand_path($OPT{examplesdir  }) if ($OPT{examplesdir  });
140$_{INST_INCDIR  } = expand_path($OPT{includedir   }) if ($OPT{includedir   });
141$_{INST_JARDIR  } = expand_path($OPT{jardir       }) if ($OPT{jardir       });
142$_{BIN_TARGET   } = expand_path($OPT{bindir       }) if ($OPT{bindir       });
143$oldincludedir    = expand_path($OPT{oldincludedir}) if ($OPT{oldincludedir});
144if ($OPT{libdir}) {
145    $_{INST_NGSLIBDIR} = $_{LIB_TARGET} = expand_path($OPT{libdir}) ;
146    $_{INST_VDBLIBDIR} = $_{LIB_TARGET};
147}
148$_{INST_NGSLIBDIR}= expand_path($OPT{ngslibdir}) if ($OPT{ngslibdir});
149$_{INST_VDBLIBDIR}= expand_path($OPT{vdblibdir}) if ($OPT{vdblibdir});
150
151if ($OPT{'no-create'} && $_{OS} eq 'linux') {
152    if ($LINUX_ROOT) {
153        print "root user\n\n";
154    } else {
155        print "non root user\n\n";
156    }
157}
158
159my $failures = 0;
160my $bFailure = 1;
161
162push @bits, $_{BITS} unless (@bits);
163foreach (@bits) {
164    $_{BITS} = $_;
165
166    print "installing $_{PACKAGE_NAME} ($_{VERSION}) package";
167    print " for $_{OS}-$_{BITS}" if ($HAVE{BINS} || $HAVE{LIBS});
168    print "...\n";
169
170    if ($HAVE{BINS}) {
171        $_{BINDIR} = $_{"BINDIR$_{BITS}"};
172        unless ($_{BINDIR}) {
173            print "install: error: $_{BITS}-bit version is not available\n\n";
174            next;
175        }
176    }
177    if ($HAVE{LIBS} || $HAVE{PYTHON}) {
178# ($_{LIBDIR} for python points where ngs-sdk and ncbi-vdb dynamic libraries
179# can be found to correctly set up LD_LIBRARY_PATH
180        $_{LIBDIR} = $_{"LIBDIR$_{BITS}"};
181        unless ($_{LIBDIR}) {
182            print "install: error: $_{BITS}-bit version is not available\n\n";
183            next;
184        }
185    }
186    if ($HAVE{JAR} && ! $_{JARDIR}) {
187        $_{JARDIR} = $_{"LIBDIR$_{BITS}"};
188        unless ($_{JARDIR}) {
189            if ($_{BITS} == 64) {
190                $_{JARDIR} = $_{LIBDIR32};
191            } else {
192                $_{JARDIR} = $_{LIBDIR64};
193            }
194            unless ($_{JARDIR}) {
195                print "install: error: jar file was not cannot found\n";
196                exit 1;
197            }
198        }
199    }
200    $bFailure = 0;
201
202    if ($OPT{'no-create'}) {
203        print     "includedir : '$_{INST_INCDIR  }'\n" if ($HAVE{INCLUDES  });
204        print     "libdir     : '$_{INST_LIBDIR}$_{BITS}'\n" if ($HAVE{LIBS});
205        print     "jardir     : '$_{INST_JARDIR  }'\n" if ($HAVE{JAR       });
206        print     "examplesdir: '$_{INST_SHAREDIR}'\n" if ($HAVE{EXAMPLES  });;
207        if ($LINUX_ROOT) {
208            print "oldincludedir: '$oldincludedir'\n"  if ($HAVE{USR_INCLUDES});
209        }
210        print "\n";
211        next;
212    }
213
214    $_{BIN_TARGET} = "$_{INST_BINDIR}$_{BITS}" unless ($OPT{bindir});
215    $_{LIB_TARGET} = "$_{INST_LIBDIR}$_{BITS}" unless ($OPT{libdir});
216
217    $File::Copy::Recursive::CPRFComp = 1;
218
219    $failures += copybins    () if ($HAVE{BINS});
220    $failures += copylibs    () if ($HAVE{LIBS});
221    $failures += copyincludes() if ($HAVE{INCLUDES});
222    $failures += copyjars    () if ($HAVE{JAR});
223    $failures += copyconfig  () if ($HAVE{CONFIG});
224
225    if ($HAVE{JAR}) {
226        $File::Copy::Recursive::CPRFComp = 0;
227        $failures += copydocs() ;
228        $File::Copy::Recursive::CPRFComp = 1;
229    }
230
231    $failures += copyexamples() if ($HAVE{EXAMPLES});
232    $failures += finishinstall() unless ($failures);
233
234    unless ($failures) {
235        print "\nsuccessfully installed $_{PACKAGE_NAME} ($_{VERSION}) package";
236    } else {
237        print "\nfailed to install $_{PACKAGE_NAME} ($_{VERSION}) package";
238    }
239    print " for $_{OS}-$_{BITS}" if ($HAVE{BINS} || $HAVE{LIBS});
240    print ".\n\n";
241}
242
243$failures = 1 if (!$failures && $bFailure);
244
245exit $failures;
246
247################################################################################
248
249sub copybins {
250    unless ($_{BIN_TARGET}) {
251        print "error: cannot install executables: no BIN_TARGET\n";
252        return 1;
253    }
254    my $s = $_{BINDIR};
255    my $d = $_{BIN_TARGET};
256    print "installing executables to $d...";
257    unless (-e $s) {
258        print " failure\n";
259        print "install: error: '$s' is not found.\n";
260        return 1;
261    }
262    print "\nchecking $d... ";
263    unless (-e $d) {
264        print "not found\n";
265        print "mkdir -p $d... ";
266        eval { make_path($d) };
267        if ($@) {
268            print "failure\ninstall: error: cannot mkdir $d\n";
269            return 1;
270        } else {
271            print "success\n";
272        }
273    } else {
274        print "exists\n";
275    }
276    print "\t\tcd $d\n" if ($OPT{debug});
277    chdir $d or die "cannot cd $d";
278    my $failures = 0;
279    foreach (BINS()) {
280        print "installing '$_'..." if ($OPT{debug});
281        my $df = "$_$_{VERSION_EXEX}";
282        my $sf = "$s/$df";
283        print "\n\t\t$sf -> $df\n\t" if ($OPT{debug});
284        unless (-e $sf) {
285            print " skipped\n" if ($OPT{debug});
286            next;
287        }
288        if ((! $OPT{force}) && (-e $df) && (-M $df < -M $sf)) {
289            print " found\n" if ($OPT{debug});
290        } else {
291            unless (copy($sf, $df)) {
292                print "failure\n";
293                print "install: error: cannot copy '$sf' '$df'.\n";
294                ++$failures;
295                next;
296            }
297            my $mode = 0755;
298            printf "\tchmod %o $df\n\t", $mode if ($OPT{debug});
299            unless (chmod($mode, $df)) {
300                print " failure\n" if ($OPT{debug});
301                print "install: error: cannot chmod '$df': $!\n";
302                ++$failures;
303                next;
304            }
305            unless (symlinks($_, $df, 'bin')) {
306                print " success\n" if ($OPT{debug});
307            } else {
308                print " failure\n" if ($OPT{debug});
309                ++$failures;
310            }
311        }
312    }
313    return $failures;
314}
315
316sub copyconfig {
317    my $d;
318    if ($LINUX_ROOT) {
319        $d = "$ROOT/etc";
320    }
321    elsif ($HAVE{BINS}) {
322        $d = $_{BIN_TARGET};
323        unless ($d) {
324            print
325               "error: cannot install configuration files: no BIN_TARGET\n";
326            return 1;
327        }
328    } else {
329        $d = $_{LIB_TARGET};
330        unless ($d) {
331            print
332               "error: cannot install configuration files: no LIB_TARGET\n";
333            return 1;
334        }
335    }
336    $d = File::Spec->catdir($d, 'ncbi');
337    my $kfg = File::Spec->catdir($Bin, '..', 'libs/kfg/default.kfg');
338    unless (-e $kfg) {
339        $kfg = File::Spec->catdir($Bin, '..', 'tools/vdb-copy/vdb-copy.kfg');
340    }
341    unless (-e $kfg) {
342        if ($_{BINDIR}) {
343            $kfg = File::Spec->catdir($_{BINDIR}, 'ncbi', 'vdb-copy.kfg');
344        } elsif ($_{LIBDIR}) {
345            $kfg = File::Spec->catdir($_{LIBDIR}, 'ncbi', 'default.kfg');
346            unless (-e $kfg) {
347                print
348                  "error: cannot install configuration files: no default.kfg\n";
349                return 1;
350            }
351        }
352    }
353    print "installing configuration files to $d... ";
354    print "\nchecking $d... ";
355    unless (-e $d) {
356        print "not found\n";
357        print "mkdir -p $d... ";
358        eval { make_path($d) };
359        if ($@) {
360            print "failure\ninstall: error: cannot mkdir $d\n";
361            return 1;
362        } else {
363            print "success\n";
364        }
365    } else {
366        print "exists\n";
367    }
368    my $df = File::Spec->catdir($d, 'ncbi-vdb.kfg');
369    print "\t\t$kfg -> $df\n" if ($OPT{debug});
370    unless (copy($kfg, $df)) {
371        print "install: error: cannot copy '$kfg' '$df'.\n";
372        return 1;
373    } else {
374        print "success\n";
375        return 0;
376    }
377}
378
379sub copylibs {
380    die unless ($HAVE{LIBS});
381
382    my $s = $_{LIBDIR};
383    my $d = $_{LIB_TARGET};
384
385    print "installing libraries to $d... ";
386
387    unless (-e $s) {
388        print "\tfailure\n";
389        print "install: error: '$s' is not found.\n";
390        return 1;
391    }
392
393    if ($HAVE{TWO_LIBS}) {
394        my $ngs = $_{INST_NGSLIBDIR};
395        if ($ngs && ! ($OPT{prefix} && $OPT{libdir} && $OPT{ngslibdir})) {
396            $ngs .= $_{BITS};
397        }
398        my $vdb = $_{INST_VDBLIBDIR};
399        if ($vdb && ! ($OPT{prefix} && $OPT{libdir} && $OPT{vdblibdir})) {
400            $vdb .= $_{BITS};
401        }
402        if ($ngs || $vdb) {
403            unless ($ngs && $vdb) {
404                $ngs = $d unless ($ngs);
405                $vdb = $d unless ($vdb);
406            }
407            $INSTALLED_LIBS{'ngs-sdk' } = $ngs;
408            $INSTALLED_LIBS{'ncbi-vdb'} = $vdb;
409        }
410    }
411    $INSTALLED_LIBS{0} = $d unless (%INSTALLED_LIBS);
412
413    foreach (keys %INSTALLED_LIBS) {
414        my $d = $INSTALLED_LIBS{$_};
415        print "\nchecking $d... ";
416        unless (-e $d) {
417            print "not found\n";
418            print "mkdir -p $d... ";
419            eval { make_path($d) };
420            if ($@) {
421                print "failure\ninstall: error: cannot mkdir $d\n";
422                return 1;
423            } else {
424                print "success\n";
425            }
426        } else {
427            print "exists\n";
428        }
429    }
430
431    return $MAKING ? copybldlibs($s, $d) : copydir($s, %INSTALLED_LIBS);
432}
433
434sub copybldlibs {
435    my ($s, $d) = @_;
436
437    print "\t\tcd $d\n" if ($OPT{debug});
438    chdir $d or die "cannot cd $d";
439
440    my $failures = 0;
441
442    my %LIBRARIES_TO_INSTALL = LIBS();
443    foreach (keys %LIBRARIES_TO_INSTALL) {
444        print "installing '$_'... ";
445
446        my $nb = "$_{LPFX}$_";
447        my $nv = "$nb.";
448        my $lib = 'dll';
449        if ($LIBRARIES_TO_INSTALL{$_} eq 'SHL') {
450            $nv .= $_{VERSION_SHLX};
451        } elsif ($LIBRARIES_TO_INSTALL{$_} eq 'LIB') {
452            $nv .= $_{VERSION_LIBX};
453            $lib = 'lib';
454        } else {
455            die "bad library type";
456        }
457
458        my $sf = "$s/$nv";
459        my $df = "$d/$nv";
460
461        print "\n\t\t$sf -> $df\n\t" if ($OPT{debug});
462
463        unless (-e $sf) {
464            print "failure\n";
465            print "install: error: '$sf' is not found.\n";
466            ++$failures;
467            next;
468        }
469
470        if ((! $OPT{force}) && (-e $df) && (-M $df < -M $sf)) {
471            print "found\n";
472        } else {
473            unless (copy($sf, $df)) {
474                print "failure\n";
475                print "install: error: cannot copy '$sf' '$df'.\n";
476                ++$failures;
477                next;
478            }
479            my $mode = 0644;
480            $mode = 0755 if ($lib eq 'dll');
481            printf "\tchmod %o $df\n\t", $mode if ($OPT{debug});
482            unless (chmod($mode, $df)) {
483                print "failure\n";
484                print "install: error: cannot chmod '$df': $!\n";
485                ++$failures;
486                next;
487            }
488            unless (symlinks($nb, $nv, $lib)) {
489                print "success\n";
490            } else {
491                print "failure\n";
492                ++$failures;
493            }
494        }
495    }
496
497    return $failures;
498}
499
500sub symlinks {
501    my ($nb, $nv, $type) = @_;
502
503    my @l;
504    if ($type eq 'lib') {
505        push @l, "$nb-static.$_{LIBX}";
506        push @l, "$nb.$_{LIBX}";
507        push @l, "$nb.$_{MAJVERS_LIBX}";
508    } elsif ($type eq 'dll') {
509        push @l, "$nb.$_{SHLX}";
510        push @l, "$nb.$_{MAJVERS_SHLX}";
511    } elsif ($type eq 'bin' || $type eq 'jar') {
512        push @l, $nb;
513        push @l, "$nb.$_{MAJVERS}";
514    } else {
515        print "failure\n";
516        print "install: error: unknown symlink type '$type'\n";
517        return 1;
518    }
519
520    my $failures = 0;
521
522    for (my $i = 0; $i <= $#l; ++$i) {
523        my $file = $l[$i];
524        if (-e $file) {
525            print "\trm $file\n\t" if ($OPT{debug});
526            unless (unlink $file) {
527                print "failure\n";
528                print "install: error: cannot rm '$file': $!\n";
529                ++$failures;
530                next;
531            }
532        }
533
534        my $o = $nv;
535        $o = $l[$i + 1] if ($i < $#l);
536
537        print "\tln -s $o $file\n\t" if ($OPT{debug});
538        unless (symlink $o, $file) {
539            print "failure\n";
540            print "install: error: cannot symlink '$o' '$file': $!\n";
541            ++$failures;
542            next;
543        }
544    }
545
546    return $failures;
547}
548
549sub copydir {
550    my ($s, %d) = @_;
551
552    my $failures = 0;
553
554    foreach my $pattern(keys %d) {
555        my $d = $d{$pattern};
556        print "\t\tcd $d\n" if ($OPT{debug});
557        chdir $d or die "cannot cd $d";
558
559        opendir(D, $s) or die "cannot opendir $s: $!";
560
561        while (readdir D) {
562            next if (/^\.{1,2}$/);
563            next if ($pattern && ! /$pattern/);
564
565            my $n = "$s/$_";
566
567            if (-l $n) {
568                print "\t\t$_ (symlink)... " if ($OPT{debug});
569                my $l = readlink $n;
570                if ((-e $_) && (!unlink $_)) {
571                    print "error: cannot remove $l: $!\n";
572                    ++$failures;
573                    next;
574                }
575                unless (symlink($l, $_)) {
576                    print "error: cannot create symlink from $_ to $l: $!\n";
577                    ++$failures;
578                    next;
579                }
580                print "success\n" if ($OPT{debug});
581            } else {
582                print "\t\t$_... " if ($OPT{debug});
583                if ((-e $_) && (!unlink $_)) {
584                    print "error: cannot remove $_: $!\n";
585                    ++$failures;
586                    next;
587                }
588                unless (copy($n, $_)) {
589                    print "error: cannot copy '$n' to '$_': $!\n";
590                    ++$failures;
591                    next;
592                }
593                print "success\n" if ($OPT{debug});
594            }
595        }
596
597        closedir D;
598    }
599
600    return $failures;
601}
602
603sub includes_out {
604    my $out = '';
605    eval { $out = INCLUDES_OUT(); };
606    $out = File::Spec->catdir($_{INST_INCDIR}, $out);
607    $out;
608}
609
610sub copyincludes {
611    print "installing includes to $_{INST_INCDIR}... ";
612
613    my $s = "$_{INCDIR}/" . INCLUDES();
614    unless (-e $s) {
615        print "\tfailure\n";
616        print "install: error: '$s' is not found.\n";
617        return 1;
618    }
619
620    my $out = includes_out();
621    my $d = $out;
622    $d = $_{INST_INCDIR} unless ($d);
623
624    unless (-e $d) {
625        print "\n\t\tmkdir -p $d" if ($OPT{debug});
626        eval { make_path($d) };
627        if ($@) {
628            print "\tfailure\ninstall: error: cannot mkdir $d\n";
629            return 1;
630        }
631    }
632
633    if ($out && -f $s) {
634        print "\n\t\tcp $s $d\n\t" if ($OPT{debug});
635        unless (copy($s, $d)) {
636            print "failure\n";
637            return 1;
638        }
639    } else {
640        print "\n\t\tcp -r $s $d\n\t" if ($OPT{debug});
641        unless (dircopy($s, $d)) {
642            print "\tfailure\ninstall: error: cannot copy '$s' 'd'";
643            return 1;
644        }
645    }
646
647    print "success\n";
648    return 0;
649}
650
651sub copyjars {
652    my $s = $_{JARDIR};
653    my $d = $_{INST_JARDIR};
654
655    print "installing jar files to $d... ";
656
657    unless (-e $s) {
658        print "\tfailure\n";
659        print "install: error: '$s' is not found.\n";
660        return 1;
661    }
662
663    print "\nchecking $d... ";
664    unless (-e $d) {
665        print "not found\n";
666        print "mkdir -p $d... ";
667        eval { make_path($d) };
668        if ($@) {
669            print "failure\ninstall: error: cannot mkdir $d\n";
670            return 1;
671        } else {
672            print "success\n";
673        }
674    } else {
675        print "exists\n";
676    }
677
678    return $MAKING ? copybldjars($s, $d) : copydir($s, 0 => $d);
679}
680
681sub copybldjars {
682    my ($s, $d) = @_;
683    my $n = 'ngs-java.jar';
684    $s .= "/$n";
685
686    unless (-e $s) {
687        print "\tfailure\n";
688        print "install: error: '$s' is not found.\n";
689        return 1;
690    }
691
692    my $nd = "$n.$_{VERSION}";
693    print "installing '$n'... ";
694
695    print "\t\tcd $d\n" if ($OPT{debug});
696    chdir $d or die "cannot cd $d";
697
698    $d .= "/$nd";
699
700    print "\n\t\t$s -> $d\n\t" if ($OPT{debug});
701
702    if ((! $OPT{force}) && (-e $d) && (-M $d < -M $s)) {
703        print "found\n";
704    } else {
705        unless (copy($s, $d)) {
706            print "failure\n";
707            print "install: error: cannot copy '$s' '$d'.\n";
708            return 1;
709        }
710        my $mode = 0644;
711        printf "\tchmod %o $d\n\t", $mode if ($OPT{debug});
712        unless (chmod($mode, $d)) {
713            print "failure\n";
714            print "install: error: cannot chmod '$d': $!\n";
715            return 1;
716        }
717        unless (symlinks($n, $nd, 'jar')) {
718            print "success\n";
719        } else {
720            print "failure\n";
721            return 1;
722        }
723    }
724
725    return 0;
726}
727
728sub copydocs {
729    my $s = "$_{JARDIR}/javadoc";
730    $s = expand_path("$Bin/../doc") unless ($MAKING);
731    my $d = "$_{INST_SHAREDIR}/doc";
732
733    print "installing html documents to $d... ";
734
735    unless (-e $s) {
736        print "\tfailure\n";
737        print "install: error: '$s' is not found.\n";
738        return 1;
739    }
740
741    print "\nchecking $d... ";
742    unless (-e $d) {
743        print "not found\n";
744        print "mkdir -p $d... ";
745        eval { make_path($d) };
746        if ($@) {
747            print "failure\ninstall: error: cannot mkdir $d\n";
748            return 1;
749        } else {
750            print "success\n";
751        }
752    } else {
753        print "exists\n";
754    }
755
756    print "\t\t$s -> $d\n\t" if ($OPT{debug});
757    unless (dircopy($s, $d)) {
758        print "\tfailure\ninstall: error: cannot copy '$s' to '$d'";
759        return 1;
760    }
761
762    print "success\n";
763    return 0;
764}
765
766sub copyexamples {
767    my $failures = 0;
768    my $CPRFComp = $File::Copy::Recursive::CPRFComp;
769    my $sd = $EXAMPLES_DIR;
770    return 0 unless (-e $sd);
771
772    my $d = $_{INST_SHAREDIR};
773    unless ($d) {
774        print "install: error: cannot install examples\n";
775        return 0;
776    }
777
778    if ($HAVE{JAR}) {
779        $d .= '/examples-java';
780    } elsif ($HAVE{PYTHON}) {
781        $File::Copy::Recursive::CPRFComp = 0;
782        $d .= '/examples-python';
783    }
784
785    print "installing examples to $d... ";
786
787    my $s = $sd;
788    $s = "$sd/examples" if ($HAVE{JAR} && $MAKING);
789
790    unless (-e $s) {
791        print "\tfailure\n";
792        print "install: error: '$s' is not found.\n";
793        ++$failures;
794    }
795
796    unless ($failures) {
797        print "\nchecking $d... ";
798        unless (-e $d) {
799            print "not found\n";
800            print "mkdir -p $d... ";
801            eval { make_path($d) };
802            if ($@) {
803                print "failure\ninstall: error: cannot mkdir $d\n";
804                ++$failures;
805            } else {
806                print "success\n";
807            }
808        } else {
809            print "exists\n";
810        }
811    }
812
813    unless ($failures) {
814        print "\t\t$s -> $d\n\t" if ($OPT{debug});
815        if ($HAVE{JAR} && ! $MAKING) {
816            if (copydir($s, 0 => $d)) {
817                ++$failures;
818            }
819        } else {
820            unless (dircopy($s, $d)) {
821                print "\tfailure\ninstall: error: cannot copy '$s' to '$d'";
822                ++$failures;
823            }
824        }
825    }
826
827    unless ($failures) {
828        if ($HAVE{JAR} && $MAKING) {
829            $sd = "$sd/Makefile";
830            $d = "$d/Makefile";
831            print "\t$sd -> $d\n\t" if ($OPT{debug});
832            unless (-e $sd) {
833                print "\tfailure\n";
834                print "install: error: '$sd' is not found.\n";
835                ++$failures;
836            }
837            unless ($failures) {
838                if (-e $d) {
839                unless (unlink $d) {
840                    print "failure\n";
841                    print "install: error: cannot rm '$d': $!\n";
842                    ++$failures;
843                }
844            }
845            unless ($failures) {
846                unless (copy($sd, $d)) {
847                    print "error: cannot copy '$sd' to '$d': $!\n";
848                    ++$failures;
849                }
850            }
851        }
852      }
853    }
854
855    print "success\n" unless ($failures);
856
857    $File::Copy::Recursive::CPRFComp = $CPRFComp;
858
859    return $failures;
860}
861
862sub finishinstall {
863    my $failures = 0;
864
865    $_{JAR_TARGET} = "$_{INST_JARDIR}/ngs-java.jar";
866
867    my @libs;
868    if (%INSTALLED_LIBS) {
869        my %libs;
870        ++$libs{$INSTALLED_LIBS{$_}} foreach (keys %INSTALLED_LIBS);
871        push @libs, $_ foreach (keys %libs);
872    } else {
873        push @libs, $_{LIB_TARGET};
874    }
875    my $libs;
876    foreach (@libs) {
877        $libs .= ":" if ($libs);
878        $libs .= $_;
879    }
880
881    if ($HAVE{PYTHON}) {
882        chdir "$Bin/.." or die "cannot cd '$Bin/..'";
883        my $cmd = "python setup.py install";
884        $cmd .= ' --user' unless (linux_root());
885        print `$cmd`;
886        if ($?) {
887            ++$failures;
888        } else {
889            unless ($libs) {
890                print "internal python failure\n";
891                ++$failures;
892            } elsif ($HAVE{LIBS}) {
893                print <<EndText;
894Please add $libs to your LD_LIBRARY_PATH, e.g.:
895      export LD_LIBRARY_PATH=$libs:\$LD_LIBRARY_PATH
896EndText
897            }
898        }
899    } elsif ($LINUX_ROOT) {
900        print "\t\tlinux root\n" if ($OPT{debug});
901
902        if ($HAVE{USR_INCLUDES}) {
903            unless (-e $oldincludedir) {
904                print "install: error: '$oldincludedir' does not exist\n";
905                ++$failures;
906            } else {
907                my $o = includes_out();
908                if ($o) {
909                    eval { INCLUDES_OUT(); };
910                    if ($@) {
911                        print "install: cannot find INCLUDES_OUT\n";
912                        ++$failures;
913                    } else {
914                        my $INCLUDE_SYMLINK
915                            = "$oldincludedir/" . INCLUDES_OUT();
916                        print "updating $INCLUDE_SYMLINK... ";
917                        unlink $INCLUDE_SYMLINK;
918                        if ($OPT{debug}) {
919                            print "\n\t\tln -s $o $INCLUDE_SYMLINK... ";
920                        }
921                        unless (symlink $o, $INCLUDE_SYMLINK) {
922                            print "failure\n";
923                            print "install: error: " .
924                                "cannot symlink '$o' '$INCLUDE_SYMLINK': $!\n";
925                            ++$failures;
926                        } else {
927                            print "success\n";
928                        }
929                    }
930                } else {
931                    my $INCLUDE_SYMLINK = "$oldincludedir/" . INCLUDES();
932                    print "updating $INCLUDE_SYMLINK... ";
933                    unlink $INCLUDE_SYMLINK;
934                    my $o = "$_{INST_INCDIR}/" . INCLUDES();
935                    unless (symlink $o, $INCLUDE_SYMLINK) {
936                        print "failure\n";
937                        print "install: error: "
938                            . "cannot symlink '$o' '$INCLUDE_SYMLINK': $!\n";
939                        ++$failures;
940                    } else {
941                        print "success\n";
942                    }
943                }
944            }
945        }
946
947        my $NAME = PACKAGE_NAME();
948        if ($HAVE{BINS} || $HAVE{JAR}
949            || ($HAVE{LIBS}
950                && ($HAVE{DLLS} || $NAME eq 'NGS-SDK' || $NAME eq 'NGS-BAM')
951               )
952            )
953        {
954            my $profile = "$ROOT/etc/profile.d";
955            my $PROFILE_FILE = "$profile/" . lc(PACKAGE_NAME());
956            unless (-e $profile) {
957                print "install: error: '$profile' does not exist\n";
958                ++$failures;
959            } else {
960                print "updating $PROFILE_FILE.[c]sh... ";
961
962                my $f = "$PROFILE_FILE.sh";
963                if (!open F, ">$f") {
964                    print "failure\n";
965                    print "install: error: cannot open '$f': $!\n";
966                    ++$failures;
967                } else {
968                    print F "#version $_{VERSION}\n\n";
969
970                    if ($HAVE{LIBS}) {
971                        unless (@libs) {
972                            print "internal root libraries failure\n";
973                            ++$failures;
974                        } else {
975                            if ($HAVE{DLLS}) {
976                                foreach (@libs) {
977                                    print F <<EndText;
978if ! echo \$LD_LIBRARY_PATH | /bin/grep -q $_
979then export LD_LIBRARY_PATH=$_:\$LD_LIBRARY_PATH
980fi
981
982EndText
983                                }
984                            }
985                            if ($NAME eq 'NGS-SDK') {
986                                print F "export NGS_LIBDIR=$_{LIB_TARGET}\n";
987                            } elsif ($NAME eq 'NGS-BAM') {
988                                print F
989                                      "\nexport NGS_BAM_LIBDIR=$_{LIB_TARGET}\n"
990                            }
991                        }
992                    }
993                    if ($HAVE{JAR}) {
994                        print F <<EndText;
995if ! echo \$CLASSPATH | /bin/grep -q $_{JAR_TARGET}
996then export CLASSPATH=$_{JAR_TARGET}:\$CLASSPATH
997fi
998EndText
999                    }
1000                    if ($HAVE{BINS}) {
1001                        print F <<EndText;
1002if ! echo \$PATH | /bin/grep -q $_{INST_BINDIR}
1003then export PATH=$_{INST_BINDIR}:\$PATH
1004fi
1005EndText
1006                    }
1007                    close F;
1008                    unless (chmod(0644, $f)) {
1009                        print "failure\n";
1010                        print "install: error: cannot chmod '$f': $!\n";
1011                        ++$failures;
1012                    }
1013                }
1014            }
1015
1016            my $f = "$PROFILE_FILE.csh";
1017            if (!open F, ">$f") {
1018                print "failure\n";
1019                print "install: error: cannot open '$f': $!\n";
1020                ++$failures;
1021            } else {
1022                print F "#version $_{VERSION}\n\n";
1023
1024                if ($HAVE{LIBS}) {
1025                    unless (@libs) {
1026                        print "internal libraries failure\n";
1027                        ++$failures;
1028                    } else {
1029                        if ($HAVE{DLLS}) {
1030                            foreach (@libs) {
1031                                print F <<EndText;
1032echo \$LD_LIBRARY_PATH | /bin/grep -q $_
1033if ( \$status ) setenv LD_LIBRARY_PATH $_:\$LD_LIBRARY_PATH
1034
1035EndText
1036                            }
1037                        }
1038                    }
1039                    if (PACKAGE_NAME() eq 'NGS-BAM') {
1040                        print F "setenv NGS_BAM_LIBDIR $_{LIB_TARGET}\n";
1041                    } elsif (PACKAGE_NAME() eq 'NGS-SDK') {
1042                        print F "setenv NGS_LIBDIR $_{LIB_TARGET}\n";
1043                    } elsif (PACKAGE_NAME() eq 'NCBI-VDB') {
1044                        print F "setenv NCBI_VDB_LIBDIR $_{LIB_TARGET}\n";
1045                    }
1046                }
1047                if ($HAVE{JAR}) {
1048                    print F <<EndText;
1049echo \$CLASSPATH | /bin/grep -q $_{JAR_TARGET}
1050if ( \$status ) setenv CLASSPATH $_{JAR_TARGET}:\$CLASSPATH
1051EndText
1052                }
1053                if ($HAVE{BINS}) {
1054                    print F <<EndText;
1055echo \$PATH | /bin/grep -q $_{INST_BINDIR}
1056if ( \$status ) setenv PATH $_{INST_BINDIR}:\$PATH
1057EndText
1058                }
1059                close F;
1060                unless (chmod(0644, $f)) {
1061                    print "failure\n";
1062                    print "install: error: cannot chmod '$f': $!\n";
1063                    ++$failures;
1064                }
1065            }
1066#	@ #TODO: check version of the files above
1067            print "success\n" unless ($failures);
1068        }
1069
1070        unless ($failures) {
1071            if ($HAVE{LIBS}) {
1072                if (PACKAGE_NAME() eq 'NGS-BAM') {
1073                    print "\n";
1074                    print "Use \$NGS_BAM_LIBDIR in your link commands, e.g.:\n";
1075                    print "      ld -L\$NGS_BAM_LIBDIR -lngs-bam ...\n";
1076                } elsif (PACKAGE_NAME() eq 'NGS-SDK') {
1077                    print "\nUse \$NGS_LIBDIR in your link commands, e.g.:\n";
1078                    print "      ld -L\$NGS_LIBDIR -lngs-sdk ...\n";
1079                } elsif (PACKAGE_NAME() eq 'NCBI-VDB') {
1080                    print "\n"
1081                       . "Use \$NCBI_VDB_LIBDIR in your link commands, e.g.:\n";
1082                    print "      ld -L\$NCBI_VDB_LIBDIR -lncbi-vdb ...\n";
1083                }
1084            }
1085        }
1086    } else {
1087        print "\t\tnot linux root\n" if ($OPT{debug});
1088        if ($HAVE{LIBS}) {
1089            unless ($libs) {
1090                print "internal libraries failure\n";
1091                ++$failures;
1092            } else {
1093                print "\n";
1094                print <<EndText if ($HAVE{DLLS});
1095Please add $libs to your LD_LIBRARY_PATH, e.g.:
1096      export LD_LIBRARY_PATH=$libs:\$LD_LIBRARY_PATH
1097EndText
1098                if (PACKAGE_NAME() eq 'NGS-SDK') {
1099                    print "Use $libs in your link commands, e.g.:\n"
1100                        . "export NGS_LIBDIR=$libs\n"
1101                        . "ld -L\$NGS_LIBDIR -lngs-sdk ...\n";
1102                } elsif (PACKAGE_NAME() eq 'NGS-BAM') {
1103                    print "Use $libs in your link commands, e.g.:\n"
1104                        . "export NGS_BAM_LIBDIR=$libs\n"
1105                        . "ld -L\$NGS_BAM_LIBDIR -lngs-bam ...\n";
1106                }
1107            }
1108        }
1109        if ($HAVE{JAR}) {
1110            print <<EndText;
1111
1112Please add $_{JAR_TARGET} to your CLASSPATH, i.e.:
1113      export CLASSPATH=$_{JAR_TARGET}:\$CLASSPATH
1114EndText
1115        }
1116    }
1117
1118    return $failures;
1119}
1120
1121sub expand_path {
1122    my ($filename) = @_;
1123    return unless ($filename);
1124
1125    if ($filename =~ /^~/) {
1126        if ($filename =~ m|^~([^/]*)|) {
1127            if ($1 && ! getpwnam($1)) {
1128                print "install: error: bad path: '$filename'\n";
1129                exit 1;
1130            }
1131        }
1132
1133        $filename =~ s{ ^ ~ ( [^/]* ) }
1134                      { $1
1135                            ? (getpwnam($1))[7]
1136                            : ( $ENV{HOME} || $ENV{USERPROFILE} || $ENV{LOGDIR}
1137                                || (getpwuid($<))[7]
1138                              )
1139                      }ex;
1140    }
1141
1142    my $a = abs_path($filename);
1143    $filename = $a if ($a);
1144
1145    $filename;
1146}
1147
1148sub help {
1149    $_{LIB_TARGET} = "$_{INST_LIBDIR}$_{BITS}";
1150
1151    print <<EndText;
1152'install' installs $_{PACKAGE_NAME} $_{VERSION} package.
1153
1154Usage: ./install [OPTION]...
1155
1156Defaults for the options are specified in brackets.
1157
1158Configuration:
1159  -h, --help              display this help and exit
1160  -n, --no-create         do not run installation
1161
1162EndText
1163
1164    if ($HAVE{TWO_LIBS}) {
1165        my $p = lc(PACKAGE_NAME());
1166        print "By default, `./install' will install all the files in\n";
1167        print "`/usr/local/ngs/$p/jar', " if ($HAVE{JAR});
1168        print <<EndText;
1169`/usr/local/ngs/$p/share',
1170`/usr/local/ngs/ngs-sdk/lib$_{BITS}', `/usr/local/ncbi/ncbi-vdb/lib$_{BITS}'.
1171You can spefify other installation directories using the options below.
1172
1173Fine tuning of the installation directories:
1174EndText
1175        if ($HAVE{JAR}) {
1176            print
1177                "  --jardir=DIR         jar files [/usr/local/ngs/$p/jar]\n"
1178        }
1179        print <<EndText;
1180  --ngslibdir=DIR      ngs-sdk libraries [/usr/local/ngs/ngs-sdk/lib$_{BITS}]
1181  --vdblibdir=DIR      ncbi-vdb libraries [/usr/local/ncbi/ncbi-vdb/lib$_{BITS}]
1182  --examplesdir=DIR    example files [/usr/local/ngs/$p/share]
1183
1184  --libdir=DIR         install all libraries in the same directory
1185  --prefix=DIR         install files in PREFIX/lib$_{BITS}, PREFIX/share etc.
1186EndText
1187    } else {
1188        print <<EndText;
1189Installation directories:
1190  --prefix=PREFIX         install all files in PREFIX
1191                          [$_{PREFIX}]
1192
1193By default, `./install' will install all the files in
1194EndText
1195
1196        if ($HAVE{INCLUDES}) {
1197            print
1198"`$_{PREFIX}/include', `$_{PREFIX}/lib$_{BITS}' etc.  You can specify\n"
1199        } elsif ($HAVE{JAR}) {
1200            print "`$_{PREFIX}/jar', `$_{PREFIX}/share' etc.  You can specify\n"
1201        } elsif ($MAKING) {
1202            print "`$_{PREFIX}/share' etc.  You can specify\n"
1203        } else {
1204            print
1205"`$_{PREFIX}/lib$_{BITS}' `$_{PREFIX}/share' etc.  You can specify\n"
1206        }
1207
1208        print <<EndText;
1209an installation prefix other than `$_{PREFIX}' using `--prefix',
1210for instance `--prefix=$_{OTHER_PREFIX}'.
1211For better control, use the options below.
1212
1213Fine tuning of the installation directories:
1214EndText
1215
1216        if ($HAVE{BINS}) {
1217            print "  --bindir=DIR            executables [PREFIX/bin]\n";
1218        }
1219        if ($HAVE{JAR}) {
1220            print "  --jardir=DIR            jar files [PREFIX/jar]\n";
1221        }
1222        if ($HAVE{LIBS}) {
1223            print
1224"  --libdir=DIR            object code libraries [PREFIX/lib$_{BITS}]\n"
1225        }
1226        if ($HAVE{INCLUDES}) {
1227            print "  --includedir=DIR        C header files [PREFIX/include]\n";
1228        }
1229        if ($HAVE{USR_INCLUDES}) {
1230            print
1231"  --oldincludedir=DIR     C header files for non-gcc [$oldincludedir]\n"
1232        }
1233
1234        if (-e $EXAMPLES_DIR) {
1235            print "  --examplesdir=DIR       example files [PREFIX/share]\n";
1236        }
1237    }
1238
1239    if ($HAVE{LIBS}) {
1240        print <<EndText;
1241
1242System types:
1243  --bits=[32|64]          use a 32- or 64-bit data model
1244EndText
1245    }
1246
1247    print "\nReport bugs to sra-tools\@ncbi.nlm.nih.gov\n";
1248}
1249
1250sub prepare {
1251    if ($MAKING) {
1252        my $os_arch = `perl -w $Bin/os-arch.perl`;
1253        unless ($os_arch) {
1254            print "install: error\n";
1255            exit 1;
1256        }
1257        chomp $os_arch;
1258        my $config =
1259            "$Bin/../" . CONFIG_OUT() . "/Makefile.config.install.$os_arch.prl";
1260        fatal_config("$config not found") unless (-e "$config");
1261
1262        eval { require $config; };
1263        fatal_config($@) if ($@);
1264    } else {
1265        my $a = $Config{archname64};
1266        $_ = lc PACKAGE_NAME();
1267        my $root = '';
1268        $root = $OPT{root} if ($OPT{root});
1269        my $code =
1270            'sub CONFIGURE { ' .
1271            '   $_{OS           } = $OS; ' .
1272            '   $_{VERSION      } = "1.0.0"; ' .
1273            '   $_{MAJVERS      } = "1"; ' .
1274            '   $_{LPFX         } = "lib"; ' .
1275            '   $_{LIBX         } = "a"; ' .
1276            '   $_{MAJVERS_LIBX } = "a.1"; ' .
1277            '   $_{VERSION_LIBX } = "a.1.0.0"; ' .
1278            '   $_{SHLX         } = "so"; ' .
1279            '   $_{OTHER_PREFIX } = \'$HOME/ngs/' . $_ . '\'; ' .
1280            '   $_{PREFIX       } = "' . "$root/usr/local/ngs/$_" . '"; ' .
1281            '   $_{INST_INCDIR  } = "$_{PREFIX}/include"; ' .
1282            '   $_{INST_LIBDIR  } = "$_{PREFIX}/lib"; ' .
1283            '   $_{INST_JARDIR  } = "$_{PREFIX}/jar"; ' .
1284            '   $_{INST_SHAREDIR} = "$_{PREFIX}/share"; ' .
1285            '   $_{INCDIR       } = "$Bin/../include"; ' .
1286            '   $_{LIBDIR64     } = "$Bin/../lib"; ' .
1287            '   $_{LIBDIR32     } = "$Bin/../lib"; ';
1288        if ($HAVE{TWO_LIBS}) {
1289            $code .=
1290               '$_{INST_NGSLIBDIR} = "' . "$root/usr/local/ngs/ngs-sdk/lib\";"
1291             . '$_{INST_VDBLIBDIR} = "' . "$root/usr/local/ncbi/ncbi-vdb/lib\";"
1292        }
1293        $code .= ' $_{PACKAGE_NAME} = "' . PACKAGE_NAME() . '"; ';
1294
1295        if (defined $Config{archname64}) {
1296            $code .= ' $_{BITS} = 64; ';
1297        } else {
1298            $code .= ' $_{BITS} = 32; ';
1299        }
1300
1301        $code .=
1302            '   $_{MAJVERS_SHLX } = "so.1"; ' .
1303            '   $_{VERSION_SHLX } = "so.1.0.0"; ' ;
1304
1305        $code .=
1306            '   @_ ' .
1307            '}';
1308
1309        eval $code;
1310
1311        die $@ if ($@);
1312    }
1313}
1314
1315sub linux_root { $^O eq 'linux' && `id -u` == 0 }
1316
1317sub fatal_config {
1318    if ($OPT{debug}) {
1319        print "\t\t";
1320        print "@_";
1321        print "\n";
1322    }
1323
1324    print "install: error: run ./configure [OPTIONS] first.\n";
1325
1326    exit 1;
1327}
1328
1329################################################################################
1330