#!/bin/sh exec perl -lwx $0 ${1+"$@"} #!/usr/bin/perl -lw # The above tries to ensure support for non-standard locations of perl # # This file is part of the SDD/DFS/Pipeline Team tools # Copyright (C) 2005,2007,2009 European Southern Observatory # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA # # # $Author: llundin $ # $Date: 2013-10-09 14:10:22 $ # $Revision: 1.100 $ # $Name: not supported by cvs2svn $ # $developers_help = <<'REQ'; 1) Now (as before) the user provides interactively as input a $prefixdir, where all common packages are installed: CPL (6.3), esorex (3.10), CIFTSIO (3.31), WCS (4.16), GSL (1.15) and FFTW (3.3.3). 2) The pipeline themselves will no longer be installed in $prefixdir, but instead in $prefixdir/$instrume-$version. 3) Consequently, the user _must_ update $LD_LIBRARY_PATH to the value that ./install_pipeline suggests. REQ $developers_help = <<'HELP'; This script assumes the following: 0) In the below description gz can be substituted with bz2, or dropped 1) In the directory where it resides, it expects to find a number of gzipped tar-files, with names .tar.gz, that unpack into the directory / : cpl-.tar.gz esorex-.tar.gz gasgano-.tar.gz Optionally: One or more pipelines, -.tar.gz One or more pipeline static calibration files, -calib-.tar.gz External open-source, like fftw-3.3.3.tar.gz 1A) In the directory where it resides, it expects to find a cfitsio3310.tar.gz that unpacks into the directory cfitsio/ :-(((((((((((((((((((( - or a standard packed cfitsio (ca. v. 3.47 or higher). 2) With exception of gasgano-.tar.gz and -calib-.tar.gz, these gzipped tar-files must contain an executable script, configure, that is compatible with configure-scripts generated by autoconf and that generates a Makefile - or they must contain a Makefile. The Makefile must support the targets 'all' and 'install', i.e. `make` and `make install` must work. Specifically, the configure-script must understand the --prefix option and either understand or ignore the --with-extra-includes and --with-extra-libs options. 3) Files of type -calib-.tar.gz are unpacked and installed into calib/-/ . The optional gasgano configuration files, i.e. -calib-/gasgano/config/.prefs -calib-/gasgano/config/.rul -calib-/gasgano/config/.oca and any gasgano scripts in -calib-/gasgano/scripts/ are installed differently: If a gasgano package is delivered, the gasgano files in the calib-file are installed on top. If there is no gasgano delivery they will be ignored. 4) Files of type -calib-.tar.gz should contain: A) The static calibration (FITS-) files also found in the -calibdb-.tar.gz - using the same directory structure (typically a directory for each major observing mode). B) If -calibdb-.tar.gz contains a QC dictionary (in directory dic/), then this should also be present. C) If -calibdb-.tar.gz contains a gasgano/config-directory, then this should also be present. Example: -calib-/gasgano/ -calib-/gasgano/config/ -calib-/gasgano/config/.prefs -calib-/gasgano/config/.rul -calib-/gasgano/config/.oca -calib-/spec/cal/calibration_1.fits -calib-/spec/cal/calibration_2.fits -calib-/spec/cal/calibration_3.fits -calib-/dic/ -calib-/dic/ESO-DFS-DIC._QC 5) .sof files for example runs must be placed in sof/ and name .sof. 6) The filenames in these .sof files shall be relative to the directory where the install-script resides. 7) The name of this directory should be either: -kit-/ - for delivery of one pipeline), or +-kit-/ for delivery of f.ex. two pipelines. The gzipped tar-file should thus be named --kit.tar.gz respectively -+--kit.tar.gz 8) Files with the word 'config' in them are silently ignored. Apart from perl this script assumes the PATH to point the following executables: gzip tar make find cp mv tee HELP use File::Copy "cp"; $supported = 1; # Directory with files to be installed $0 =~ /kit/ or ($srcdir) = $0 =~ /(.+\/)/; $srcdir ||= './'; chdir($srcdir) || die "Could not chdir to $srcdir".$developers_help; $fullpwd = `pwd`; chomp($fullpwd); $pwd=$fullpwd; $pwd =~ s/.+\///; $mso = '(?:s[ol]|dylib)'; # .so or .sl (for HP-UX) or .dylib (for Mac OSX). $mtar = '\.tar(?:\.gz|\.bz2|\.xz)?'; # Support .tar, .tar.gz .tar.bz2 and .tar.xz # FIXME: seems overly complicated ... open(STDOUT, '|tee install.log') || die "Cannot redirect stdout to install.log\n"; open(STDERR, '>&STDOUT') || &mydie("Cannot dup stdout (install-$dir.log)\n"); select(STDERR); $| = 1; # make unbuffered select(STDOUT); $| = 1; # make unbuffered &init_install(); $ignore_esorex_rc = 0; $make = 'make'; $sudoinstall = ''; $sudocalib = ''; for (;@ARGV;) { $ARGV[0] eq '-ignore_gasgano' and shift(@ARGV), $gasgano::doinstall = 0, next; $ARGV[0] eq '-ignore_esorex_rc' and shift(@ARGV), $ignore_esorex_rc = 1, next; $ARGV[0] =~ /^-makeopts=(.+)/ and shift(@ARGV), $make .= " $1", next; last; } if ($0 =~ /kit/) { # If the script is invoked under a name that contains the string 'kit' # then it expects some *-kit-*.tar.gz as arguments. These are unpacked, # checked for consistency, and installed when OK. local($inikit); local(@kit)=(); local(@newdir)=(); # Check argument names for (;@ARGV;) { if ($ARGV[0] =~ /(.+\-kit\-.+)$mtar/) { push(@kit, shift()); } elsif (-d $ARGV[0] || $ARGV[0] =~ /^\// and $#newdir < 1) { push(@newdir, shift()); } else { die "Need *-kit-*.tar.gz, not: $_"; } } @newdir and push(@ARGV, @newdir); @kit or die "I need one or more pipeline kits.\n".$developers_help; local($tmpnam) = "pipeline-kit-$$.tmp"; mkdir($tmpnam, 0755) || die "Could not create directory $tmpnam"; chdir($tmpnam) || die "Could not chdir into directory $tmpnam"; $builddir = 'tmp'; mkdir($builddir, 0755) || die "Could not create directory $builddir"; local(%dsize)=(); local(%dname)=(); # Unpack and check kits for (@kit) { local($kitname) = /(.+\-kit\-.+)$mtar/; local($kitbase) = $kitname; local($gz) = /\.gz/ ? 'z' : (/\.bz2/ ? 'j' : ''); $kitbase =~ s/.+\///; &do_or_die("tar x${gz}f ". (/^\// ? $_ : "../$_")); opendir(IN, $kitbase) or die "Did not find $kitbase after unpacking $_"; local(@kitfiles)=readdir(IN); closedir(IN); if ($inikit) { for $targz (@kitfiles) { $targz =~ /(.+)$mtar/ or next; local($base) = $1; if ($base =~ /(.+)-(.+)/) { defined($dname{$1}) && $dname{$1} ne $2 and die "Cannot install $kitbase and $inikit with both $base and $1-$dname{$1}"; $dname{$1}=$2; } defined($dsize{$base}) && -s $targz != $dsize{$base} and die "Cannot install $kitbase/$targz and $inikit/$targz with " ."different sizes"; $dsize{$base} = -s $targz; symlink("../$kitbase/$targz", "$builddir/$targz"); } } else { $inikit = $kitbase; for $targz (@kitfiles) { $targz =~ /(.+)$mtar/ or next; local($base) = $1; if ($base =~ /(.+)-(.+)/) { defined($dname{$1}) and die "Cannot install $kitbase and $inikit with both $base and $1-$dname{$1}"; $dname{$1}=$2; } $dsize{$base} = -s $targz; symlink("../$kitbase/$targz", "$builddir/$targz"); } } } chdir($builddir); } # List of software to install @targz = glob('*.tar*'); local($_); for (@targz) { /\b(?:calib|config)\b/ and next; if (/^gasgano/) { defined($gasgano::doinstall) or $gasgano::doinstall = &cpl_has_jni(grep(/cpl/, @targz)) || &gasgano::check_java_home($_); $gasgano::doinstall || next; } elsif (/^wcslib/) { $wcslib::doinstall = 1; } elsif (/^fftw/) { $fftw::doinstall = 1; } push(@dist, $_); } $gasgano::doinstall ||= 0; # List of pipeline calibration files to install grep($dist{$_}++, @dist); @calib = grep(/(.+)\-calib(.+)/ && defined($dist{$1.$2}), @targz); %dist=(); @must = ('cfitsio(?:2510|3\d\d\d|\-3\.\d\d\d?|\-\d+\.\d+\.\d+)', 'cpl', 'esorex'); $gasgano::doinstall && push(@must, 'gasgano'); for $dist (@must) { local($n) = 0+grep(/\b$dist\b/,@dist); $n == 0 and die "I am missing a gzipped tar file with $dist in $srcdir ($0)\n".$developers_help; $n == 1 or die "I cannot handle more than one gzipped tar file with $dist in $srcdir (not $n)\n".$developers_help; } &check4pipeline(@dist) or die " You have sucessfully downloaded and unpacked ESOs pipeline infrastructure kit! Please follow these instructions to install one or more pipelines: 1) Point your browser to http://www.eso.org/pipelines 2) Find the pipeline(s) that you wish to install. 3) Download the source code of the pipeline, -.tar.gz, e.g. fors-4.3.5.tar.gz and save the gzipped tar file into the directory where this script resides. 4) Download the static calibration data, if any, of the pipeline, -calib-.tar.gz, e.g. fors-calib-4.3.5.tar.gz and save the gzipped tar file into the directory where this script resides. 5) Redo steps 3) and 4) for any additional pipeline that you wish to install. 6) Rerun the install script and verify that your pipeline(s) are listed among the packages to install. "; for (@dist) { /\bcpl\-(\d+)\.(\d+)/ || next; $cpl::major = $1; $cpl::minor = $2; $cpl::major < 4 and die("The CPL version must be at least 4.0, I cannnot use $_\n" .$developers_help); } print 'I am about to install the following software packages:'; grep(print(" $_"), sort dist_sort @dist); $pipedirlist = join('/, ', map(/(.+)\.tar.*/,grep(!/^($msort)/o, @dist))).'/'; print ''; if (@calib) { print ' - with the following pipeline calibration file(s):'; grep(print(" $_"), sort dist_sort @calib); print " The software installation will be organised in bin/, lib/, include/ and $pipedirlist directories, while the calibration files will be installed in a calib/ directory. "; } else { print " The software installation will be organised in bin/, lib/, include/ and $pipedirlist directories. "; } # Warn about reruns of $0 if (grep(-e &distdir($_), @targz)) { local($fullpwdback)=$fullpwd; $fullpwdback =~ s/[^\/]+\/*$//; opendir(IN, $fullpwdback); local($kit); grep(/\b$pwd$mtar/o && ($kit=$_), readdir(IN)); warn(" Oops, you are trying to rerun the installation. This is not supported and may cause unexpected behaviour or errors. To ensure a correct pipeline installation, you should remove the directory created by untarring the pipeline-kit, untar the kit again and then run the installation script: cd $fullpwdback rm -r $fullpwd tar xzf $kit cd $fullpwd ./install_pipeline "); &confirm("Should I abort the installation") and exit(1); $supported = 0; } $gasgano::doinstall && &gasgano::lookahead(); @plugindirs=(); $prefixdir = ''; # An existing prefixdir may be supplied on the command line $#ARGV >= 0 and $prefixdir = $prefixdir_default = shift(@ARGV) or # Otherwise: If user is root use /usr/local - otherwise use home directory $prefixdir_default = $> ? $ENV{HOME} : '/usr/local'; $makeinstall = "$make install"; while (!-d $prefixdir) { printf("What should be the prefix path for the installation, i.e. the base" ." path where the software packages will be installed ?" ." [$prefixdir_default] "); $prefixdir = ; chomp($prefixdir); $prefixdir ||= $prefixdir_default; if ($prefixdir !~ /^\//) { warn "I need an absolute path\n"; $prefixdir = ''; } elsif ($prefixdir =~ /^$ENV{HOME}\/+gasgano/) { warn("Oops, $prefixdir is reserved for gasgano, " ."I cannot install there\n"); $prefixdir = ''; } elsif (!-d $prefixdir && &confirm("Directory $prefixdir does not exist, create") && !mkdir($prefixdir, 0755) && system("mkdir -p '$prefixdir'") != 0) { warn("Oops, I could not create $prefixdir\n"); if (&is_exe('sudo')) { warn("You can either let me perform the installation in $prefixdir using the command sudo, or you can enter a new location for the installation. "); if (&confirm("Should I use sudo to create '$prefixdir' and " ."for '$makeinstall'")) { if (&sudomkdir($prefixdir, 1)) { $sudoinstall = 'sudo '; } else { warn("Failed to create $prefixdir with sudo"); } } } $sudoinstall or $prefixdir = ''; } elsif (!-w $prefixdir) { warn("Oops, I do not have write access to $prefixdir\n"); if (&is_exe('sudo')) { warn("You can either let me perform the installation in $prefixdir using the command sudo, or you can enter a new location for the installation. "); if (&confirm("Should I use sudo for '$makeinstall'")) { $sudoinstall = 'sudo '; } } $sudoinstall or $prefixdir = ''; } }; $makeinstall = $sudoinstall . $makeinstall; $prefixdir =~ s/\/+$//; # Check if old CPL header files exist in the installation directory and stop # the installation if that is the case (PIPE-5255). local(@found) = `find "$prefixdir" -name 'cpl*.h'`; if ($#found > 0) { warn("CPL header files found in $prefixdir. Will not continue the" ." installation because this will likely fail. Please first remove the" ." old installation of CPL.\n"); exit(1); } $calibdir = ''; if (@calib) { local($calibdir_default); # An existing calibdir may be supplied on the command line $#ARGV >= 0 and $calibdir = shift(@ARGV) or # Otherwise: If user is root use /usr/local - otherwise use home directory $calibdir_default = $prefixdir; while (!-d $calibdir) { printf("What should be the prefix path where the pipeline calibration" ." files will be installed, i.e. the base directory where the" ." calibration directory structure will be prepared ?" ." [$calibdir_default] "); $calibdir = ; chomp($calibdir); $calibdir ||= $calibdir_default; if ($calibdir !~ /^\//) { warn "I need an absolute path\n"; $calibdir = ''; } elsif ($calibdir =~ /^$ENV{HOME}\/+gasgano/) { warn("Oops, $calibdir is reserved for gasgano, " ."I cannot install there\n"); $calibdir = ''; } elsif (-e $calibdir && !-d $calibdir) { warn "I need a directory\n"; $calibdir = ''; } elsif (!-d $calibdir && &confirm("Directory $calibdir does not exist, create") && !mkdir($calibdir, 0755) && system("mkdir -p '$calibdir'") != 0) { if ($sudoinstall && &sudomkdir($calibdir, $sudoinstall)) { $sudocalib = $sudoinstall; } else { warn("Oops, I cannot create the directory $calibdir\n"); if (&is_exe('sudo')) { warn("You can either let me install the pipeline calibration files in $calibdir using the command sudo, or you can enter a new location for the installation of the pipeline calibration files. "); if (&confirm("Should I use sudo for 'mkdir -p '$calibdir'")) { local($cmd) = "sudo mkdir -p '$calibdir'"; if (system($cmd) == 0) { $sudocalib = 'sudo '; } else { warn("The command \"$cmd\" failed"); } } } } $sudocalib or $calibdir = ''; } elsif (!-w $calibdir) { if ($sudoinstall) { $sudocalib = $sudoinstall; } else { warn("Oops, I cannot modify the directory $calibdir\n"); if (&is_exe('sudo')) { warn("You can either let me install the pipeline calibration files in $calibdir using the command sudo, or you can enter a new location for the installation of the pipeline calibration files. "); if (&confirm('Should I use sudo for the installation of the ' .'pipeline calibration files')) { $sudocalib = 'sudo '; } } } } }; &sudomkdir("$calibdir/share", $sudocalib) || die "Could not create directory $calibdir/share".$developers_help; &sudomkdir("$calibdir/share/esopipes", $sudocalib) || die "Could not create directory $calibdir/share/esopipes".$developers_help; &sudomkdir("$calibdir/share/esopipes/datastatic", $sudocalib) || die "Could not create directory $calibdir/share/esopipes/datastatic".$developers_help; symlink("./share/esopipes/datastatic", "$calibdir/calib") || die "Could not create symlink $calibdir/calib".$developers_help; } $ENV{FFTWDIR} = $ENV{ERFADIR} = $ENV{GSLDIR} = $ENV{CFITSIODIR} = $ENV{QFITSDIR} = $ENV{CPLDIR} = $ENV{TELLURICCORRDIR} = $prefixdir; @libdir = ('lib', 'lib64', 'lib32'); # SUSE 12 uses lib64, not lib. lib32 ? # Prepend prefixdir to LD_LIBRARY_PATH - Needed _before_ building, # so configure can link and run test-executables $ldlibdir = join(':', map("$prefixdir/$_", @libdir)); $ldlibpathname = $^O eq 'darwin' ? 'DYLD_LIBRARY_PATH' : 'LD_LIBRARY_PATH'; if (defined($ENV{$ldlibpathname})) { $ENV{$ldlibpathname} =~ /^$ldlibdir(?:$|\:)/o or $ENV{$ldlibpathname} = "$ldlibdir:$ENV{$ldlibpathname}", $^O eq 'darwin' and $dodyldmsg = 1; } else { $ENV{$ldlibpathname} = $ldlibdir; $^O eq 'darwin' and $dodyldmsg = 1; } for $dist (sort dist_sort @dist) { if ($dist =~ /gasgano/){ # Handled separately $gasgano::home = &gasgano::install($dist); next; } local($dir) = &distdir($dist) or die $dir.$developers_help; if ($dir !~ /^($msort)/o && $dist =~ /(.+)$mtar$/) { -e $prefixdir || mkdir($prefixdir, 0755) || system("mkdir -p '$prefixdir'")==0 || die "Could not create directory $prefixdir\n"; print "Installing $dist in $prefixdir (with plugins in ", "lib*/esopipes-plugins/$1)"; push(@plugindirs, map("$prefixdir/$_/esopipes-plugins/$1", @libdir)); } else { print "Installing $dist"; } # next; # FIXME: used for development local($gz) = $dist =~ /\.gz/ ? 'z' : ($dist =~ /\.bz2/ ? 'j' : ''); &do_or_die("tar x${gz}f $dist"); chdir($dir) || die "Could not chdir to $dir (directory created by $dist)\n".$developers_help; # FFTW is built twice to support both single and double precision local($ninstalls) = $dist =~ /fftw/ ? 2 : 1; for $installs (1..$ninstalls) { if ($installs > 1) { &do_or_die("$make clean"); } if (-x 'install_lapack') { # FIXME: Ugly, ugly, ugly kludge for non-standard build procedure of (c)lapack # :-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( &do_or_die("./install_lapack $prefixdir"); } elsif (-x 'configure') { # Old fashioned distributions may not use ./configure local($distbase) = $dist =~ /^(\w+)/; # FIXME: Ugly, ugly, ugly kludge for non-standard tar-ball name of cfitsio # - for versions up to 3.45 # :-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( $distbase =~ s/(cfitsio)\d+/$1/; # Default configure options local($config_opt) = "--with-extra-includes=$prefixdir/include"; $config_opt .= join('', map(" --with-extra-libs=$prefixdir/$_", @libdir)); # Check for package dependent configure options if (defined($distbase) && defined(&{$distbase.'::config'})) { $config_opt = &{$distbase.'::config'}($prefixdir, $installs); } elsif (!defined($sort{$distbase})) { $config_opt = &pipeline_config($prefixdir, $installs); } local($config_cmd) = "./configure --prefix=$prefixdir $config_opt"; # FIXME: Ugly, ugly, ugly kludge for non-standard clapack-3.2.1 configure # :-(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( $distbase =~ /^clapack/ and $config_cmd =~ s/ --prefix=/ /; # Let the user know how the packages are built print "$config_cmd\n"; &do_or_die($config_cmd); } local($molecfit_flags) = "-f BuildThirdParty.mk"; if ($dist =~ /^molecfit_third_party-/) { &do_or_die("make $molecfit_flags prefix=$prefixdir"); } else { &do_or_die($make); } # FIXME: Ugly, ugly, ugly kludge for non-standard build procedure of cfitsio # :-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((( $dist =~ /\bcfitsio(?:\d+|\-\d+\.\d+.*)\.tar\.gz/ and &do_or_die("$make shared"); if ($dist =~ /^molecfit_third_party-/) { &do_or_die("make $molecfit_flags prefix=$prefixdir install"); } else { &do_or_die($makeinstall); } if ($^O eq 'darwin' && $dist =~ /(cfitsio)(?:\d+|\-\d\.\d+.*)\.tar\.gz/) { &darwin_install_name_tool($1); } if ($^O eq 'darwin' && $dist =~ /(wcs)lib(?:-\d+(?:\.\d+)*)\.tar\.bz2/) { &darwin_install_name_tool($1); } } chdir('..'); } #$ENV{LD_LIBRARY_PATH} = defined($ENV{LD_LIBRARY_PATH}) # ? "$prefixdir/lib:$ENV{LD_LIBRARY_PATH}" : "$prefixdir/lib"; #$ENV{PATH} = defined($ENV{PATH}) ? "$prefixdir/bin:$ENV{PATH}" : "$prefixdir/bin"; if ($gasgano::doinstall && !gasgano::gotcpl($prefixdir)) { warn(" Oops, the CPL installation unexpectedly failed to produce the gasgano interface library. You can therefore not use gasgano for recipe execution. You can either let me stop, so you can investigate why CPL failed to produce the gasgano interface library, or you can proceed in which case you should be able to use esorex for the recipe execution. "); &confirm("Should I abort the installation") and exit(1); $gasgano::doinstall = 0; } else { print ''; print "Pipeline installation complete!"; print ''; } local($esorex) = "$prefixdir/bin/esorex"; $ignore_esorex_rc or &check_n_upd_esorexrc(@plugindirs); $cmd = "$esorex --recipes"; @stdout = `$cmd`; if ($?) { $esorex::failed = $?; local($event) = &crashtxt($?); $gasgano::doinstall ? warn(" Oops, I cannot complete the esorex installation: I tried to execute the command $cmd which $event. This indicates that esorex is not supported on this platform. You can either let me stop, so you can investigate why esorex failed, or you can proceed in which case you should be able to use gasgano for the recipe execution. ") : die(" Oops, I cannot complete the esorex installation: I tried to execute the command $cmd which $event. This indicates that esorex is not supported on this platform. Since neither esorex nor gasgano could be installed, I have to stop the installation. "); &confirm("Should I abort the installation") and exit(1); } else { @recipes = (); $found = 0; for (@stdout) { $found and /(\w+)\s*:/ && push(@recipes, $1), next; /List of Available Recipes/ and $found = 1, next; } if ($found) { print "Available recipes:"; grep(print(" $_"), @recipes); } else { $esorex::failed = -1; $gasgano::doinstall ? warn(" Oops, I could not find any recipes:", @stdout, " You can therefore not use esorex for recipe execution. You can either let me stop, so you can investigate why esorex failed, or you can proceed in which case you should be able to use gasgano for the recipe execution. ") : die(" Oops, I could not find any recipes:", @stdout, " You can therefore not use esorex for recipe execution. Since neither esorex nor gasgano could be installed, I have to stop the installation. "); &confirm("Should I abort the installation") and exit(1); } } &install_calib($gasgano::home, @calib); $gasgano::doinstall and &gasgano::config($gasgano::home, \@plugindirs, \@calib), print < $sort{$bsort}; !defined($asort) && defined($bsort) && return 1; !defined($bsort) && defined($asort) && return -1; # Otherwise sort alphabetically (since these two should be pipelines) $a cmp $b; } sub check4pipeline { local(@dist)=@_; local($ok) = 0; grep(/^($msort)/o || $ok++, @dist); $ok; } sub confirm { local($ask)=@_; local($_); do { printf("$ask ? [Y/n] "); -t STDIN || die "I cannot get your answer because my standard input is not opened to a tty\n"; $_ = ; } until (/^\s*[yn]?\s*$/i); !/n/i; } sub do_or_die { local($cmd)=@_; local($exec) = $cmd =~ /^\s*exec\s/ ? $cmd : "exec $cmd"; system($exec) == 0 and return; warn "The command\n $cmd\nfailed with code $?"; $supported and die "This should not have happened. Please submit a bug report with the file ./install.log included to https://support.eso.org using the subject: Installation of pipeline $pwd failed "; } sub cp_or_die { local(@args) = @_; local($dest) = pop(@args); # cp() returns 1 on OK if (grep(!cp($_, $dest) && warn("Copy of $_ to $dest failed: $!"), @args)) { $supported and die "This should not have happened. Please submit a bug report with the file ./install.log included to https://support.eso.org using the subject: Installation of pipeline $pwd failed "; } } sub check_path { local(@fullpath)=@_; local(@actual_path) = split(/:/,$ENV{PATH}); local(%missingpath, @missingpath); local(%precede, %fullpath, %fixprecede); for $fullpath (@fullpath) { -x $fullpath || die $fullpath.$developers_help; local($mypath,$exe) = $fullpath =~/(.+)\/(.+)/; local($myinode) = (stat($fullpath))[1]; local($missingpath) = 1; for $path (@actual_path) { -d "$path/$exe" and next; -x "$path/$exe" or next; $myinode == (stat("$path/$exe"))[1] and $missingpath = 0; # Path points to another instance of the executable $missingpath and $fullpath{$exe}=$fullpath, $fixprecede{$mypath}++, $precede{$exe} ||= $path; } $missingpath && !$fixprecede{$mypath} and push(@missingpath, $fullpath), $missingpath{$mypath}++; } if (%precede || %missingpath) { warn "Warning:\n\n"; if (%precede) { warn "Your PATH points to\n" .join(" and\n", map("$precede{$_}/$_", sort keys %precede)) ."\ninstead of your newly installed\n" .join(" and\n", map($fullpath{$_}, sort keys %precede)).".\n"; if (%missingpath) { warn "\nSecondly, your PATH does not point to your newly installed\n" .join(" and\n",@missingpath).".\n"; } } else { warn "Your PATH does not point to your newly installed\n" .join(" and\n",@missingpath).".\n"; } warn "\nTo ensure execution of the newly installed software you should " ."modify your PATH.\n\n" ."Depending on your type of shell a possible command for doing this may be:\n" ."export PATH=" .join(':', keys %fixprecede, @actual_path, keys %missingpath)."\n\n"; } } sub check_n_upd_esorexrc { local(@plugindirs)=@_; # The recipes in each of the directories must be available and # they may not be available from other directories. # Get the current recipe-dir local($path) = join("",`$esorex --params 2>/dev/null`) =~ /^\s*recipe\-dir\s*\:\s+(\S+)/m; @paths = (); $path and @paths = split(':',$path); # Find those dirs in the recipe-path that contain the plugins with the same # name in other directories local(@remove)=(); for $plugindir (@plugindirs) { opendir(IN, $plugindir) or print("Skipping $plugindir, could not open it for reading"), next; local(%inodes); grep(-f "$plugindir/$_" && ($inodes{$_} = (stat("$plugindir/$_"))[1]), readdir(IN)); closedir(IN); for $path (@paths) { local($found) = 0; for $file (keys %inodes) { -e $path or last; local(@found) = `find $path -name $file`; chomp(@found); grep((stat($_))[1] != $inodes{$file}, @found) and $found++, last; } $found and push(@remove, $path), print "The esorex recipe-dir path needs a removal of the path $path"; } } local($doit) = 0; if (@remove) { $doit = 1; local(@new) = (); for $path (@paths) { grep($path eq $_, @remove) || push(@new, $path); } @paths = @new; } # Find those dirs that are not already available in the recipe-dir path local(@append)=(); for $plugindir (@plugindirs) { -e $plugindir or next; local($inode) = (stat($plugindir))[1]; local($found) = 0; for $path (grep(-e, @paths)) { local(@find) = `find $path -type d`; chomp(@find); grep((stat($_))[1] == $inode, @find) and $found++, last; } $found or push(@append, $plugindir), print "The esorex recipe-dir path needs to be extended with $plugindir"; } $doit ||= @append; $doit || return; @append and push(@paths, @append); # Need to remove (original) non-existing dirs when updating local($newpath) = join(':',grep(-e, @paths)); local($cmd) = "$esorex --create-config --recipe-dir=$newpath 2>/dev/null"; print "Updating the esorex recipe-dir configuration"; local($r) = system("exec $cmd"); if ($r) { $esorex .= " --recipe-dir=$newpath"; local($event) = &crashtxt($r); if (system("exec $esorex --recipes > /dev/null 2>&1") == 0) { warn " Oops, I cannot complete the esorex installation: I tried to execute the command $cmd which $event. This means that the esorex configuration file could not be created. You can either let me stop, so you can investigate why esorex failed, or you can proceed in which case you will need to invoke esorex with a specification of the recipe location on the Command Line Interface, i.e. $esorex "; &confirm("Should I abort the installation") and exit(1); } } } sub gasgano::lookahead { # gasgano must be installed in $HOME :-( local($gasganohome) = "$ENV{HOME}/gasgano"; -e $gasganohome or return 1; -e "$gasganohome.old" or return 1; warn " Oops, I cannot proceed with the gasgano installation: gasgano must be installed in $gasganohome. You appear to already have gasgano installed there. I intended to rename your existing gasgano installation to $gasganohome.old but $gasganohome.old already exists. You can either let me D) Delete the current $gasganohome before I install gasgano there, R) Replace $gasganohome.old with your current $gasganohome, or S) Stop, so you can backup both $gasganohome and $gasganohome.old, and then restart the installation. "; local($_); do { printf("D) Delete, R) Replace, S) Stop ? [d/R/s] "); -t STDIN || die "I cannot get your answer because my standard input is not opened to a tty\n"; $_ = ; } until (/^\s*[drs]?\s*$/i); /s/i and exit(-1); local($delete) = /d/i ? $gasganohome : "$gasganohome.old"; # Try to prevent failure in the cleanup (but ignore a failure here) local(@chmod) = `find $delete -type d`; @chmod and chomp(@chmod), chmod(0700, @chmod); &do_or_die("/bin/rm -rf $delete"); } sub gasgano::gotcpl { local($prefixdir)=@_; scalar glob(join(' ', map("$prefixdir/$_/libcplgasgano.*", @libdir))); } sub gasgano::expand_link { local($fullpath, $peel) = @_; defined($fullpath) or return; while (!&gasgano::check_jdk($fullpath, $peel) && -l $fullpath) { local($_) = readlink($fullpath); if (/^\//) { $fullpath = $_; } else { $fullpath =~ s/\/+[^\/+]+$// while s/^\.\.\///; $_ and $fullpath =~ s/[^\/]+$/$_/; } } $fullpath; } sub gasgano::check_jdk { local($jhome, $peel) = @_; # Verify if $JAVA_HOME is set to the JDK defined($jhome) or return; # Remove $peel entries from end $jhome =~ s/\/+[^\/]+$// while ($peel--); -e $jhome or return; local($bindir, $incdir); # Check for presence of executable $JAVA_HOME/{bin,Commands}/javah for $dir ('bin', 'Commands') { -x "$jhome/$dir/javah" and $bindir = $dir, last; } # Check for presence of $JAVA_HOME/{include,Headers}/jni.h for $dir ('include', 'Headers') { -e "$jhome/$dir/jni.h" and $incdir = $dir, last; } if (!defined($bindir) || !defined($incdir) and opendir(IN, $jhome)) { # Last, desperate try ... # If the javah and jni.h are found in too exotic directories, # then the configure --with-java of CPL may need an upgrade # too work with them. for $dir (readdir(IN)) { $dir eq '.' || $dir eq '..' and next; defined($bindir) or -x "$jhome/$dir/javah" and $bindir = $dir; defined($incdir) or -e "$jhome/$dir/jni.h" and $incdir = $dir; } closedir(IN); } defined($bindir) and defined($incdir) or return; -x "$jhome/$bindir/javah" or return; -e "$jhome/$incdir/jni.h" or return; if ($jhome =~ /\/+Versions\/+Current\/*$/) { local($jjhome) = &gasgano::check_jdk($jhome, 2); $jjhome and $jhome = $jjhome; } $jhome; } sub gasgano::find_java_home { local($exe)=@_; # use $exe to guess $ENV{JAVA_HOME} local($_, $fullpath, $jhome); $fullpath = &gasgano::expand_link(&is_exe($exe), 2) or return; # Peel off executable name $fullpath =~ s#/+[^/]+$## or return; $fullpath = &gasgano::expand_link($fullpath, 1); # Peel off executable directory ($jhome = $fullpath) =~ s#/+[^/]+$## or return; $jhome = &gasgano::expand_link($jhome, 0); &gasgano::check_jdk($jhome) and return $jhome; # If the above fails, try all subdirs (Needed on MacOS) for $dir ('/System/Library/Frameworks/JavaVM.framework', glob("$jhome/*")) { &gasgano::check_jdk($dir) and return $dir; } if (-e '/System') { # Even more desperate for $dir (`find /System -name javah`) { &gasgano::check_jdk($dir) and return $dir; } } $jhome; } sub gasgano::check_java_home { local($dist)=@_; # Check if $JAVA_HOME is already set to the JDK &gasgano::check_jdk($ENV{JAVA_HOME}) and return 1; # It was not. # On Mac OS it is so difficult to predict this location, # that there is a tool for finding it. Try it regardless of OS. if (-x '/usr/libexec/java_home') { local($java_home) = `/usr/libexec/java_home`; # Drop all but 1st line if (!$?) { chop($java_home); local($jjhome) = &gasgano::check_jdk($java_home); defined($jjhome) and $ENV{JAVA_HOME} = $jjhome, return 1; } } for $jexe ('java', 'javah') { local($jhome) = &gasgano::find_java_home($jexe); defined($jhome) || next; local($jjhome) = &gasgano::check_jdk($jhome); defined($jjhome) and $ENV{JAVA_HOME} = $jjhome, return 1; } warn " Oops, I cannot install gasgano, because I cannot find the Java Development Kit (JDK). You can either let me proceed with the installation, in which case gasgano will _not_ be installed, or you can abort the installation, install the JDK, and then restart the installation. To install the JDK you need to: 1) Perform the actual installation of the JDK. On modern systems, such as Ubuntu, this can be done simply by opening the software installation manager and selecting the JDK. 2) In case the JDK installation has already been done, make sure that \$JAVA_HOME is export'ed Please note that you will _not_ be able to use any existing gasgano installation on your machine as a front-end for running the pipeline recipes and that you therefore _must_ install the JDK if you wish to use gasgano as a front-end for running the pipeline recipes. "; &confirm("Should I abort the installation, and let you install the JDK") and exit(1); 0; } sub gasgano::install { local($dist)=@_; -s $dist || die "Invalid gasgano dist, $dist\n". $developers_help; print "Installing gasgano\n"; local($dir) = $dist; $dir =~ s/\.tar\.gz$// || die "Invalid gasgano dist name $dir".$developers_help; $dir eq 'gasgano' and die "Will not unpack a gasgano distribution with no version number\n".$developers_help; # gasgano must be installed in $HOME :-( local($gasganohome) = "$ENV{HOME}/gasgano"; if (-e $gasganohome) { -e "$gasganohome.old" && die "Will not rename $gasganohome to existing $gasganohome.old\n"; rename($gasganohome, "$gasganohome.old") or die "Could not rename $gasganohome to $gasganohome.old\n"; } local($gz) = $dist =~ /\.gz/ ? 'z' : ($dist =~ /\.bz2/ ? 'j' : ''); &do_or_die("tar -x${gz}f $dist"); print "Moving $dir to $gasganohome"; print ''; &do_or_die("mv $dir $gasganohome"); print "Gasgano installation complete"; print ''; $gasganohome; } sub gasgano::config { local($gasganohome, *plugindirs, *calib)=@_; # Make hash of plugins with their location local(%allplugins); local($gasganorcdefault) = ''; local(@gasganorcdefaultinstrume) = (); for $plugindir (@plugindirs) { $plugindir =~ /esopipes-plugins\/(\w+)/ || $plugindir =~ /(\w+)\/plugins/; $instrume = $1; $instrume || next; opendir(IN, $plugindir) or print("Skipping $plugindir, could not open it for reading"), next; %{$plugins{$instrume}}=(); # FIXME: Assuming that the recipename is the basename of the .so grep(/(.+)\.$mso$/o && ($plugins{$instrume}{$1}="$plugindir/$_"), readdir(IN)); closedir(IN); %allplugins = (%allplugins, %{$plugins{$instrume}}); } if (opendir(IN,"$gasganohome/config/")) { local(@prefs) = grep(/\.prefs$/,readdir(IN)); closedir(IN); # Try to match a .prefs file with the pipeline for $plugindir (@plugindirs) { $plugindir =~ /esopipes-plugins\/(\w+)/ || $plugindir =~ /(\w+)\/plugins/; $instrume = $1; local($nprefs) = 0; for $prefs (grep(/$instrume/i, @prefs)) { $nprefs++; local(@calib) = grep(/\b$instrume\-calib/,@calib); local($rul) = $prefs; $rul =~ s/prefs$/rul/; local($oca) = $prefs; $oca =~ s/prefs$/oca/; $oca =~ tr/A-Z/a-z/; # .oca file is lower case # Last one is selected: @gasganorcdefaultinstrume = map("$gasganohome/config/$_", $oca, $rul); &gasgano::update_prefs("$gasganohome/config/$prefs", \@gasganorcdefaultinstrume, \%{$plugins{$instrume}}, \@calib); $gasganorcdefault = "$gasganohome/config/$prefs"; # Last one is selected } $nprefs or print("No gasgano preference file to be updated for pipeline $instrume\n"), next; $nprefs > 1 and warn("Updated preferences for pipeline $instrume with $nprefs preferences\n"); } } local($gasganorc) = "$ENV{HOME}/.gasganorc"; if (-f $gasganorc) { &cp_or_die("$ENV{HOME}/.gasganorc", "$ENV{HOME}/.gasganorc.old"); &gasgano::update_prefs($gasganorc, \@gasganorcdefaultinstrume, \%allplugins, \@calib); } elsif (-f $gasganorcdefault) { print "Copying $gasganorcdefault to $ENV{HOME}/.gasganorc\n"; &cp_or_die($gasganorcdefault, "$ENV{HOME}/.gasganorc"); } -f $gasganorc or warn "Could not create/update $gasganorc\n"; } sub gasgano::update_prefs { local($prefs, *rul, *plugins, *calib)=@_; open(IN, $prefs) || die $prefs.$developers_help; local(@lines)=; close(IN); grep(/Gasgano Application Properties/, @lines) || return; # Obsolete format print "Updating $prefs\n"; local(%recipeset); local($recipeset) = grep(/^RECIPE_SET=/, @lines); if (defined($recipeset)) { $recipeset =~ s/^RECIPE_SET=//; for $recipedef (split(/\s*;+\s*/, $recipeset)) { local($a,$b) = $recipedef =~ /(.+)=(.+)/; $a =~ /\// and ($a,$b) = ($b,$a); # Support old format -e $b || next; # Drop non-existing files # FIXME(DFS03146): Assume that the recipename is listed correctly in the .prefs $recipeset{$a}=$b; } } local(%soset)=(); # Create the .so set from the new plugins grep($plugins{$_} =~ /([^\/]+)\.$mso$/o && ($soset{$1}=$_), keys %plugins); # Overwrite the plugin name of the .so with the one from the .prefs grep($recipeset{$_} =~ /([^\/]+)\.$mso$/o && ($soset{$1}=$_), keys %recipeset); # For each .so we now have the correct plugin name # For each .so we need to update the location local(%soloc)=(); grep($recipeset{$_} =~ /([^\/]+)\.$mso$/o && ($soloc{$1}=$recipeset{$_}), keys %recipeset); # Overwrite with new locations grep($plugins{$_} =~ /([^\/]+)\.$mso$/o && ($soloc{$1}=$plugins{$_}), keys %plugins); # Update the recipe set with the recipename and its location for each .so $recipeset = "RECIPE_SET=". join(';', map("$soset{$_}=$soloc{$_}", sort keys %soset)); local($rul, $rulbase); grep(-s $_ && ($rul ||= $_), @rul) and # Choose 1st $rul =~ /\.(rul|oca)$/, $rulbase = $1; local($didrecipeset) = 0; for (@lines) { # Update the location of the .rul files /^CLASSRULE_FILE=/ && defined($rulbase) && $rul =~ /(\/config\/.+\.$rulbase)$/ and $_ = "CLASSRULE_FILE=$ENV{HOME}/gasgano$1\n"; # Update the recipe locations /^RECIPE_SET=/ and $didrecipeset = 1, $_ = "$recipeset\n"; # Update the location of data files with those of the calibration data if (/^DATA_FILES=/) { local(%dir); for $calib (@calib) { $calib =~ s/(.+)\-calib(.+)$mtar/$calibdir\/share\/esopipes\/datastatic\/$1$2/ || die $calib; grep(/^(.+)\// && $dir{$1}++, `find $calib -name \\*.fits`); } $_ = 'DATA_FILES=' . join(';', sort keys %dir) . "\n"; } } -w $prefs || chmod(0644, $prefs); open(OUT,">$prefs") || die $prefs.$developers_help; print OUT @lines; $didrecipeset or print OUT "$recipeset\n"; close(OUT); } sub install_calib { local($gasganohome, @calib) = @_; print ''; for $calib (@calib) { print "Installing calibration files from $calib"; local($dir) = $calib; $dir =~ s/$mtar// || die $dir.$developers_help; local($gz) = $calib =~ /\.gz/ ? 'z' : ($calib =~ /\.bz2/ ? 'j' : ''); &do_or_die("tar -x${gz}f $calib"); chdir($dir) || die "Could not chdir to $dir (directory should be created by $calib)\n" .$developers_help; if (defined($gasganohome) && -e $gasganohome && chdir('gasgano')) { if (chdir('config')) { # Move supplied gasgano configuration files, if present if (opendir(IN, '.')) { local(@copy) = grep(/\.(?:rul|prefs|oca)$/, readdir(IN)); closedir(IN); if (@copy) { local($dest) = "$gasganohome/config/"; -e $dest || mkdir($dest, 0755); print " Copying gasgano files to $dest"; &cp_or_die(@copy, "$gasganohome/config/"); } } chdir('..') || die; } if (-d 'scripts') { &do_or_die("cp -rf scripts $gasganohome/"); } chdir('..') || die; } local($targetdir) = $dir; $targetdir =~ s/\-calib//; &sudomkdir("$calibdir/share/esopipes/datastatic/$targetdir", $sudocalib) || die "Could not create directory $calibdir/share/esopipes/datastatic/$targetdir".$developers_help; # Temporarily mv gasgano to avoid installing it in the calibdir local($didmvgasgano) = rename('gasgano', '.gasgano'); # Copy without preserving (the unknown) permissions &do_or_die("$sudocalib cp -fR cal/* $calibdir/share/esopipes/datastatic/$targetdir"); $didmvgasgano and rename('.gasgano', 'gasgano'); print ''; chdir('..'); } } sub offer { opendir(IN,'sof') || return; local(@try) = grep(/(\w+)\.sof/, readdir(IN)); closedir(IN); @try || return; print "You are welcome to try out a recipe:"; $srcdir =~ /^\.(\/+\.)*\/*$/ || print "cd $srcdir"; print "$esorex --help"; grep(/(\w+)\.sof/ && print("$esorex --suppress-prefix $1 sof/$_"), @try); } sub is_exe { local($exe)=@_; local($_); for (split(/:/,$ENV{PATH})) { -x "$_/$exe" && !-d "$_/$exe" && return("$_/$exe"); } undef; } sub crashtxt { local($r) = @_; local($txt) = ($r & 127) ? "was killed by signal ".($r & 127) : "failed with error code ".($r>>8); ($r & 128) and $txt .= " causing a core-dump"; $txt; } sub distdir { local($targz) = @_; $targz =~ /(.+)$mtar/ or return; defined($distdir{$1}) ? $distdir{$1} : $1; } sub get_cpu_features { local(%features)=(); # linux if (open(IN,'/proc/cpuinfo')) { while () { chomp; if( /^flags\s*:\s*(.*$)/) { %features = map { $_ => 1 } split(/ /, $1); last; } } close(IN); # darwin } elsif (open(IN, 'sysctl -n machdep.cpu.features |')) { while () { %features = map { $_ => 1 } split(/ /, lc($_)); last; } close(IN); } else { eval { use Config; }; if (%Config) { # Some actual pairs of values # - with Model name and flags from /proc/cpuinfo when present # archname myarchname # x86_64-linux-thread-multi x86_64-linux # Intel(R) Xeon(R) CPU E7540 # fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm syscall nx rdtscp lm constant_tsc ida nonstop_tsc pni monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr sse4_1 sse4_2 popcnt lahf_lm # x86_64-linux-gnu-thread-multi x86_64-linux # Intel(R) Core(TM)2 Duo CPU E6750 # fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm lahf_lm dts tpr_shadow vnmi flexpriority # i386-linux-thread-multi i686-linux # Intel(R) Xeon(R) CPU E5345 # fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe nx lm constant_tsc pni monitor ds_cpl vmx est tm2 cx16 xtpr lahf_lm # i386-linux-thread-multi i686-linux # Pentium III (Katmai) # fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse # darwin-thread-multi-2level i386-darwin # darwin-thread-multi-2level ppc-darwin if (grep(defined($Config{$_}) && $Config{$_} =~ /x86.64/, 'archname', 'myarchname')) { # amd64 always has sse2 $features{'sse2'}=$features{'sse'}=1; } elsif (grep(defined($Config{$_}) && $Config{$_} =~ /i386-darwin/, 'archname', 'myarchname')) { # Intel-based Macs always has sse2 - which is always supported # by the one compiler (gcc) that currently works with CPL $features{'sse2'}=$features{'sse'}=1; } } } local (@simd)=('sse', 'sse2', 'sse3', 'ssse3', 'sse4', 'sse4.1', 'sse4.2', 'sse4a', 'sse5', 'avx', 'avx2'); foreach (@simd) { $features{$_} && !system((defined($ENV{'CC'}) ? '$CC' : 'gcc') ." -m$_ -E - /dev/null 2>/dev/null") || delete($features{$_}); } %features; } sub darwin_install_name_tool { local($libname) = @_; # FIXME: On Darwin (10.11) we need to fix the # dynamic shared library install name local($exe) = &is_exe('install_name_tool'); if ($exe) { local($liblink, $extra) = grep(-l, glob("$prefixdir/lib*/lib$libname.*.dylib")); if ($liblink && !$extra) { local($libfile, $extra) = grep(-f, glob("$prefixdir/lib*/".readlink($liblink))); if ($libfile && !$extra) { local($cmd) = "$sudoinstall$exe -id $liblink $libfile"; local($r) = system($cmd); if ($r) { warn(" Oops, the '$libname' installation could not be finalized with this command: $cmd I am unsure if it will be be possible to complete the installation. "); &confirm("Should I abort the installation") and exit(1); } } } } } sub cpl_has_jni { local($cpldist) = @_; local($major, $minor, $micro) = $cpldist =~ /cpl-(\d+)\.(\d+)\.(\d+)/; defined($major) or $micro = 0, ($major, $minor) = $cpldist =~ /cpl-(\d+)\.(\d+)(?:\D|$)/; defined($major) || die "Unsupported CPL-version (no major): $cpldist"; defined($minor) || die "Unsupported CPL-version (no minor): $cpldist"; defined($micro) || die "Unsupported CPL-version (no micro): $cpldist"; # CPL has built-in JNI support from 7.1.3 $major > 7 && return 1; $major < 7 && return 0; $minor > 1 && return 1; $major < 1 && return 0; $micro > 2 && return 1; return 0; } # Pipeline specific configure options here sub pipeline_config { local($prefixdir)=@_; # This function is called for an pipeline which does not have its own # config-function, e.g. &detmon::config() ''; } # Non-standard configure options here sub qfits::config { local($prefixdir)=@_; # xmemory causes spurious warnings under darwin $^O eq 'darwin' ? ' --enable-memory-mode=1' : ''; } sub cpl::config { local($prefixdir)=@_; local($_); if (!defined($wcslib::doinstall)) { $_ = '--without-wcs '; } elsif ($cpl::major < 7 || $cpl::major == 7 && $cpl::minor == 0) { $_ = "--with-wcs=$prefixdir " } else { $_ = "--with-wcslib=$prefixdir " } $gasgano::doinstall or $_ .= '--enable-gasgano=no '; defined($fftw::doinstall) or $_ .= '--without-fftw '; $_ # Disable this very expensive debugging feature # - and disable a buggy cache-optimization . "CPPFLAGS='-DCX_DISABLE_ASSERT -DL2_CACHE_BYTES=0'"; } sub fftw::config { local($prefixdir, $installs)=@_; local(%features) = &get_cpu_features(); # fftw has runtime feature detection but we need to check for compiler support local($simd) = ""; if ($features{'avx'}) { $simd .= " --enable-avx"; # ignored by fftw < 3.3 } if ($features{'sse2'}) { # fftw < 3.3 does not accept sse2 for floats, fixed in later versions $simd .= $installs > 1 ? " --enable-sse" : " --enable-sse2"; } # --disable-fortran: Disabled not-needed Fortran-callable wrappers # for improved portability $installs > 1 ? "$simd --disable-fortran --enable-shared --enable-float" : "$simd --disable-fortran --enable-shared"; } sub detmon::config { local($prefixdir)=@_; " --with-fftw=$prefixdir"; } sub wcslib::config { local($prefixdir)=@_; # Supported by wcslib-4.4.4, seems to be ignored by 4.3 # Needed to work around hardcoded -Wno-globals, which is not # supported by g77 v. 4.2.4. # Additional paths to the local Cfitsio installation are needed to avoid # compiling and linking against the wrong version of Cfitsio (see PIPE-5111). " --disable-fortran --with-cfitsiolib=$prefixdir/lib --with-cfitsioinc=$prefixdir/include"; } sub cfitsio::config { local($prefixdir)=@_; local(%features) = &get_cpu_features(); local($simd) = $features{'sse2'} ? "--enable-sse2" : ""; $features{'ssse3'} and $simd .= " --enable-ssse3"; # Has an effect from CFITSIO 3.18 # Needed from CPL 6.0 and by CPL 5.3 when CFLAGS include -fopenmp " $simd --enable-reentrant"; } sub telluriccorr::config { local($prefixdir)=@_; " --with-cpl=$prefixdir"; } 1;