File Coverage

blib/lib/Module/Build/FFI/Fortran/ExtUtilsF77.pm
Criterion Covered Total %
statement 71 181 39.2
branch 22 86 25.5
condition 4 33 12.1
subroutine 16 22 72.7
pod 6 14 42.8
total 119 336 35.4


line stmt bran cond sub pod time code
1             package Module::Build::FFI::Fortran::ExtUtilsF77;
2              
3             # Copyright (c) 2001 by Karl Glazebrook.
4             # see licensing details below
5              
6 1     1   7 use strict;
  1         2  
  1         80  
7 1     1   6 use warnings;
  1         2  
  1         26  
8 1     1   20 use 5.008001;
  1         16  
9 1     1   9 use Config;
  1         2  
  1         51  
10 1     1   6 use File::Spec;
  1         8  
  1         66  
11              
12             =head1 NAME
13              
14             Module::Build::FFI::Fortran::ExtUtilsF77 - Simple interface to F77 libs
15              
16             =head1 DESCRIPTION
17              
18             This is a fork of L with necessary changes needed
19             for L and L. The
20             rest of this documentation is from the original, with the class
21             names updated to reflect the fork.
22              
23             This module tries to figure out how to link C programs with
24             Fortran subroutines on your system. Basically one must add a list
25             of Fortran runtime libraries. The problem is their location
26             and name varies with each OS/compiler combination!
27              
28             This module tries to implement a simple
29             'rule-of-thumb' database for various flavours of UNIX systems.
30             A simple self-documenting Perl database of knowledge/code
31             for figuring out how to link for various combinations of OS and
32             compiler is embedded in the modules Perl code. Please help
33             save the world by sending database entries for
34             your system to karl_pgplot@mac.com
35              
36             Note the default on most systems is now to search for a generic 'GNU' compiler
37             which can be g77, gfortran or g95 and then find the appropriate link
38             libraries automatically. (This is the 'Generic' 'GNU' database entry
39             in the code.)
40              
41             The library list which the module returns
42             can be explicitly overridden by setting the environment
43             variable F77LIBS, e.g.
44              
45             % setenv F77LIBS "-lfoo -lbar"
46             % perl Makefile.PL
47             ...
48              
49             =cut
50              
51             our $VERSION = '0.09';
52              
53 1 50   1 0 2050 BEGIN { eval q{ sub config_log {} } unless __PACKAGE__->can('config_log') }
        10      
54              
55             config_log "\nModule::Build::FFI::Fortran::ExtUtilsF77: Version $VERSION";
56              
57             # Database starts here. Basically we have a large hash specifying
58             # entries for each os/compiler combination. Entries can be code refs
59             # in which case they are executed and the returned value used. This
60             # allows us to be quite smart.
61              
62             # Hash key convention is uppercase first letter of
63             # hash keys. First key is usually the name of the architecture as
64             # returned by Config (modulo ucfirst()).
65              
66             config_log "\nLoaded Module::Build::FFI::Fortran::ExtUtilsF77 version $VERSION\n";
67              
68             # formally implicit globals
69              
70             our %F77config=();
71             our $gcc;
72             our $gfortran;
73             our $fallback_compiler;
74             our $dir;
75             our $ok;
76             our %CACHE;
77              
78             # Package variables
79              
80             our $Runtime = "-LSNAFU -lwontwork";
81             our $RuntimeOK = 0;
82             our $Trail_ = 1;
83             our $Pkg = "";
84             our $Compiler = "";
85             our $Cflags = "";
86              
87              
88             ########## Win32 Specific ##############
89             if($^O =~ /MSWin/i) {
90             my @version;
91             if($Config{cc} =~ /x86_64\-w64\-mingw32\-gcc/) {
92             # This must be gcc-4.x.x
93             $gcc = 'x86_64-w64-mingw32-gcc';
94             $gfortran = 'x86_64-w64-mingw32-gfortran';
95             $fallback_compiler = 'GFortran';
96             }
97             elsif($Config{gccversion}) {
98             # Could be either gcc-4.x.x or gcc-3.x.x
99             $gcc = 'gcc';
100             @version = split /\./, $Config{gccversion};
101             $fallback_compiler = $version[0] == 4 ? 'GFortran' : 'G77';
102             $gfortran = 'gfortran';
103             }
104             else {
105             $gcc = 'gcc';
106             $gfortran = 'gfortran';
107             $fallback_compiler = 'G77';
108             }
109             }
110             else {
111             # No change from version 1.16.
112             $gcc = 'gcc';
113             $gfortran = 'gfortran';
114             $fallback_compiler = 'G77';
115             }
116              
117             ############## End of Win32 Specific ##############
118              
119             $F77config{MinGW}{G77}{Link} = sub {
120             my @libs = ('g2c', 'f2c');
121             my ($dir, $lib, $test);
122             foreach $test (@libs) {
123             $dir = `g77 -print-file-name=lib$test.a`;
124             chomp $dir;
125             # Note that -print-file-name returns just the library name
126             # if it cant be found - make sure that we only accept the
127             # directory if it returns a proper path (or matches a /)
128             if (defined $dir && $dir ne "lib$test.a") {
129             $lib = $test; # Found an existing library
130             last;
131             }
132             }
133              
134             if( defined $dir && defined $lib) {
135             $dir =~ s,/lib$lib.a$,,;
136             } else {
137             $dir = "/usr/local/lib";
138             $lib = "f2c";
139             }
140             return( "-L$dir -L/usr/lib -l$lib -lm" );
141             };
142              
143             $F77config{MinGW}{GFortran}{Link} = sub {
144             $dir = `$gfortran -print-file-name=libgfortran.a`;
145             chomp $dir;
146             # Note that -print-file-name returns just the library name
147             # if it cant be found - make sure that we only accept the
148             # directory if it returns a proper path (or matches a /)
149              
150             if( defined $dir ) {
151             $dir =~ s,/libgfortran.a$,,;
152             } else {
153             $dir = "/usr/local/lib";
154             }
155             return( "-L$dir -L/usr/lib -lgfortran -lm" );
156             };
157              
158             $F77config{MinGW}{G77}{Trail_} = 1;
159             $F77config{MinGW}{GFortran}{Trail_} = 1;
160             $F77config{MinGW}{G77}{Compiler} = find_in_path('g77','f77','fort77');
161             $F77config{MinGW}{GFortran}{Compiler} = "$gfortran";
162             $F77config{MinGW}{G77}{Cflags} = '-O';
163             $F77config{MinGW}{GFortran}{Cflags} = '-O';
164              
165             ### SunOS (use this as a template for new entries) ###
166              
167             # Code to figure out and return link-string for this architecture
168             # Returns false if it can't find anything sensible.
169              
170             $F77config{Sunos}{F77}{Link} = sub {
171             $dir = find_highest_SC("/usr/lang/SC*");
172             return "" unless $dir; # Failure
173             config_log "$Pkg: Found Fortran latest version lib dir $dir\n";
174             return "-L$dir -lF77 -lm";
175             };
176              
177             # Whether symbols (subroutine names etc.) have trailing underscores
178             # (true/false)
179              
180             $F77config{Sunos}{F77}{Trail_} = 1;
181              
182             # Name of default compiler - corresponds to one of the above keys
183              
184             $F77config{Sunos}{DEFAULT} = 'F77';
185              
186             # Program to run to actually compile stuff
187              
188             $F77config{Sunos}{F77}{Compiler} = 'f77';
189              
190             # Associated compiler flags
191              
192             $F77config{Sunos}{F77}{Cflags} = '-O';
193              
194             ############ Rest of database is here ############
195              
196             ### Solaris ###
197              
198             $F77config{Solaris}{F77}{Link} = sub {
199             my $NSPATH;
200             my $dir;
201              
202             #find the SUNWspro entry of nonstandard inst. in LD_LIBRARY_PATH
203             if ( defined $ENV{'LD_LIBRARY_PATH'} &&
204             $ENV{'LD_LIBRARY_PATH'} =~ m{([^:]*SUNWspro[^/]*)} )
205             {
206             $NSPATH = $1;
207             }
208              
209             elsif ( defined $ENV{'PATH'} ) {
210              
211             foreach ( split (/:/,$ENV{PATH}) ) {
212             if ( m{(.*SUNWspro[^/]*)} ) {
213             $NSPATH = $1;
214             last;
215             }
216             }
217             }
218              
219              
220             if (defined $NSPATH) {
221              
222             config_log "$Pkg: Found F77 path:--->$NSPATH\n";
223              
224             $dir = find_highest_SC("$NSPATH/WS*/lib") ||
225             find_highest_SC("$NSPATH/SC*/lib") ||
226             find_highest_SC("$NSPATH/sunwspro*/SUNWspro/SC*/lib");
227              
228             # that failed. try $NSPATH/lib. use glob to
229             # match for libF77.*, as libF77.a isn't there anymore?
230             unless ( $dir )
231             {
232             config_log "$Pkg: Trying $NSPATH/lib\n";
233             $dir = "$NSPATH/lib" if glob("$NSPATH/lib/libF77*");
234             }
235            
236             } else {
237             }
238             return "" unless $dir; # Failure
239             config_log "$Pkg: Found Fortran latest version lib dir $dir\n";
240              
241             my @libs;
242              
243             # determine libraries. F77 and M77 aren't available in the latest
244             # compilers
245             my $vcruft = qx/$F77config{Solaris}{F77}{Compiler} -V 2>&1/;
246             if ( $vcruft =~ /Forte Developer 7/
247             || $vcruft =~ /f90:/
248             )
249             {
250             push @libs, qw/
251             -lf77compat
252             -lfui
253             -lfai
254             -lfai2
255             -lfsumai
256             -lfprodai
257             -lfminlai
258             -lfmaxlai
259             -lfminvai
260             -lfmaxvai
261             -lfsu
262             -lsunmath
263             -lm
264             /;
265             }
266             else
267             {
268             push @libs, qw/
269             -lF77
270             -lM77
271             -lsunmath
272             -lm
273             /;
274             }
275              
276             join( ' ', "-L$dir", @libs );
277             };
278              
279              
280             $F77config{Solaris}{F77}{Trail_} = 1;
281             $F77config{Solaris}{F77}{Compiler} = 'f77';
282             $F77config{Solaris}{F77}{Cflags} = '-O';
283             $F77config{Solaris}{DEFAULT} = 'F77';
284              
285             ### Generic GNU-77 or F2C system ###
286              
287             $F77config{Generic}{GNU}{Trail_} = 1;
288             $F77config{Generic}{GNU}{Cflags} = ' '; # <---need this space!
289             $F77config{Generic}{GNU}{Link} = link_gnufortran_compiler('g77', 'gfortran', 'g95', 'fort77');
290             $F77config{Generic}{GNU}{Compiler} = find_in_path('g77', "$gfortran", 'g95','fort77');
291             $F77config{Generic}{DEFAULT} = 'GNU';
292              
293             ### cygwin ###
294              
295             $F77config{Cygwin}{GNU}{Trail_} = 1;
296             $F77config{Cygwin}{GNU}{Cflags} = '-O'; # <---need this space!
297             $F77config{Cygwin}{GNU}{Link} = link_gnufortran_compiler('g77', 'gfortran', 'g95', 'fort77');
298             $F77config{Cygwin}{GNU}{Compiler} = find_in_path('g77', "$gfortran", 'g95','fort77');
299             $F77config{Cygwin}{DEFAULT} = 'GNU';
300              
301             ### Linux ###
302              
303             $F77config{Linux}{GNU} = $F77config{Generic}{GNU};
304             $F77config{Linux}{DEFAULT} = 'GNU';
305              
306             ### DEC OSF/1 ###
307              
308             $F77config{Dec_osf}{F77}{Link} = "-L/usr/lib -lUfor -lfor -lFutil -lm -lots -lc";
309             $F77config{Dec_osf}{F77}{Trail_} = 1;
310             $F77config{Dec_osf}{F77}{Compiler} = 'f77';
311             $F77config{Dec_osf}{F77}{Cflags} = '-O';
312             $F77config{Dec_osf}{DEFAULT} = 'F77';
313              
314             ### HP/UX ###
315              
316             $F77config{Hpux}{F77}{Link} = "-L/usr/lib -lcl -lm";
317             $F77config{Hpux}{F77}{Trail_} = 0;
318             $F77config{Hpux}{F77}{Compiler} = 'f77';
319             $F77config{Hpux}{F77}{Cflags} = '-O';
320             $F77config{Hpux}{DEFAULT} = 'F77';
321              
322             ### IRIX ###
323              
324             # From: Ovidiu Toader
325             # For an SGI running IRIX 6.4 or higher (probably lower than 6.4 also)
326             # there is a new abi, -64, which produces 64 bit executables. This is no
327             # longer an experimental feature and I am using it exclusively without any
328             # problem. The code below is what I use instead of original IRIX section
329             # in the Module::Build::FFI::Fortran::ExtUtilsF77 package. It adds the -64 flag and it is supposed to
330             # provide the same functionality as the old code for a non -64 abi.
331              
332             if (ucfirst($Config{'osname'}) eq "Irix")
333             {
334             my ($cflags,$mips,$default_abi,$abi,$mips_dir,$libs);
335             $cflags = $Config{cc};
336             ($mips) = ($cflags =~ /(-mips\d)/g);
337             $mips = "" if ! defined($mips);
338             $mips_dir = $mips;$mips_dir =~ s/-//g;
339             $default_abi = $Config{osvers} >= 6.4 ? "-n32" : "-o32";
340             GET_ABI:
341             {
342             # -32 seems to be synonymous for -o32 (CS)
343             $abi = "-o32",last GET_ABI if $cflags =~ /-o?32/;
344             $abi = "-n32",last GET_ABI if $cflags =~ /-n32/;
345             $abi = "-64",last GET_ABI if $cflags =~ /-64/;
346             $abi = $default_abi;
347             }
348             if ( $abi eq "-64" ){
349             $libs = ( (-r "/usr/lib64/$mips_dir") && (-d _) && (-x _) ) ?
350             "-L/usr/lib64/$mips_dir" : "";
351             $libs .= " -L/usr/lib64 -lfortran -lm";
352             }
353             if ( $abi eq "-n32" ){
354             $libs = ( (-r "/usr/lib32/$mips_dir") && (-d _) && (-x _) ) ?
355             "-L/usr/lib32/$mips_dir" : "";
356             $libs .= " -L/usr/lib32 -lfortran -lm";
357             }
358             if ( $abi eq "-o32" ){
359             $libs = "-L/usr/lib -lF77 -lI77 -lU77 -lisam -lm";
360             }
361             $F77config{Irix}{F77}{Cflags} = "$abi $mips";
362             $F77config{Irix}{F77}{Link} = "$libs";
363             $F77config{Irix}{F77}{Trail_} = 1;
364             $F77config{Irix}{F77}{Compiler} = "f77 $abi";
365             $F77config{Irix}{DEFAULT} = 'F77';
366             }
367              
368             ### AIX ###
369              
370             $F77config{Aix}{F77}{Link} = "-L/usr/lib -lxlf90 -lxlf -lc -lm";
371             $F77config{Aix}{F77}{Trail_} = 0;
372             $F77config{Aix}{DEFAULT} = 'F77';
373              
374             ### FreeBSD ###
375              
376             $F77config{Freebsd}{F77}{Trail_} = 1;
377             $F77config{Freebsd}{F77}{Link} = '-L/usr/lib -lf2c -lm';
378             $F77config{Freebsd}{DEFAULT} = 'F77';
379              
380             ### VMS ###
381              
382             $F77config{VMS}{Fortran}{Trail_} = 0;
383             $F77config{VMS}{Fortran}{Link} = ' '; # <---need this space!
384             $F77config{VMS}{DEFAULT} = 'Fortran';
385             $F77config{VMS}{Fortran}{Compiler} = 'Fortran';
386              
387             ### Darwin (Mac OS X) ###
388              
389             $F77config{Darwin}{GNU} = $F77config{Generic}{GNU};
390             $F77config{Darwin}{DEFAULT} = 'GNU';
391              
392              
393             ############ End of database is here ############
394              
395             =head1 SYNOPSIS
396              
397             use Module::Build::FFI::Fortran::ExtUtilsF77; # Automatic guess
398             use Module::Build::FFI::Fortran::ExtUtilsF77 qw(sunos); # Specify system
399             use Module::Build::FFI::Fortran::ExtUtilsF77 qw(linux g77); # Specify system and compiler
400             $fortranlibs = Module::Build::FFI::Fortran::ExtUtilsF77->runtime;
401              
402              
403             =cut
404              
405             sub get; # See below
406              
407             # All the figuring out occurs during import - this is because
408             # a lot of the answers depend on a lot of the guesswork.
409              
410             sub import {
411 1     1   8 no warnings; # Shuts up complaints on Win32 when running PDL tests
  1         3  
  1         2722  
412 1     1   3 $Pkg = shift;
413 1         3 my $system = ucfirst(shift); # Set package variables
414 1         2 my $compiler = ucfirst(shift);
415 1         7 $Runtime = "-LSNAFU -lwontwork";
416              
417             # Guesses if system/compiler not specified.
418              
419 1 50       8 $system = ucfirst $Config{'osname'} unless $system;
420 1 50       5 $system = 'Cygwin' if $system =~ /Cygwin/;
421 1 50       4 $compiler = get $F77config{$system}{DEFAULT} unless $compiler;
422              
423 1 50       31 config_log "$Pkg: Using system=$system compiler=" .
424             (defined $compiler ? $compiler : "") . "\n";
425              
426 1 50       4 if (defined($ENV{F77LIBS})) {
427 0         0 config_log "Overriding Fortran libs from value of enviroment variable F77LIBS = $ENV{F77LIBS}\n";
428 0         0 $Runtime = $ENV{F77LIBS};
429             }
430             else {
431              
432             # Try this combination
433              
434 1 50 33     7 if ( defined( $compiler ) and defined( $F77config{$system} )){
435 1         3 my $flibs = get ($F77config{$system}{$compiler}{Link});
436 1 50       4 if ($flibs ne "") {
437 0         0 $Runtime = $flibs;# . gcclibs();
438             # We don't want to append gcc libs if we are using
439             # non gnu compilers. Initially, explicitly check for
440             # use of sun compiler
441             #$Runtime .= gcclibs($flibs) unless $flibs =~ /sunmath/;
442             #(Note appending gcclibs seems to be no longer required)
443 0 0       0 $Runtime =~ s|L([a-z,A-Z]):|L//$1|g if $^O =~ /cygwin/i;
444 0 0       0 $Runtime = ' ' if $^O eq 'VMS'; # <-- need this space!
445 0         0 config_log "Runtime: $Runtime\n";
446 0         0 $ok = 1;
447 0 0       0 $ok = validate_libs($Runtime) if $flibs ne "";
448             }
449             }else {
450 0         0 $Runtime = $ok = "";
451             }
452              
453             # If it doesn't work try Generic + GNU77
454              
455 1 50 33     4 unless (("$Runtime" ne "-LSNAFU -lwontwork") && $ok) {
456 1         27 config_log <<"EOD";
457             $Pkg: Unable to guess and/or validate system/compiler configuration
458             $Pkg: Will try system=Generic Compiler=$fallback_compiler
459             EOD
460             $system =
461 1 50 33     8 $Config{cc} =~ /\bgcc/ && $^O =~ /MSWin32/i ? "MinGW"
462             :"Generic";
463 1         4 $compiler = $fallback_compiler;
464 1         3 my $flibs = get ($F77config{$system}{$compiler}{Link});
465 1         3 $Runtime = $flibs ; #. gcclibs($flibs); # Note gcclibs appears to be no longer required.
466 1 50       3 $ok = validate_libs($Runtime) if $flibs ne "";
467 1 50 33     27 config_log "$Pkg: Well that didn't appear to validate. Well I will try it anyway.\n"
468             unless $Runtime && $ok;
469             }
470              
471 1         2 $RuntimeOK = $ok;
472              
473             } # Not overriding
474              
475             # Now get the misc info for the methods.
476              
477 1 50       4 if (defined( $F77config{$system}{$compiler}{Trail_} )){
478 0         0 $Trail_ = get $F77config{$system}{$compiler}{Trail_};
479             }
480             else{
481 1         56 config_log << "EOD";
482             $Pkg: There does not appear to be any configuration info about
483             $Pkg: names with trailing underscores for system $system. Will assume
484             $Pkg: F77 names have trailing underscores.
485             EOD
486 1         3 $Trail_ = 1;
487             }
488              
489 1 50       4 if (defined( $F77config{$system}{$compiler}{Compiler} )) {
490 0         0 $Compiler = get $F77config{$system}{$compiler}{Compiler};
491             } else {
492 1         30 config_log << "EOD";
493             $Pkg: There does not appear to be any configuration info about
494             $Pkg: the F77 compiler name. Will assume 'f77'.
495             EOD
496 1         2 $Compiler = 'f77';
497             }
498 1         26 config_log "$Pkg: Compiler: $Compiler\n";
499              
500 1 50       3 if (defined( $F77config{$system}{$compiler}{Cflags} )) {
501 0         0 $Cflags = get $F77config{$system}{$compiler}{Cflags} ;
502             } else {
503 1         26 config_log << "EOD";
504             $Pkg: There does not appear to be any configuration info about
505             $Pkg: the options for the F77 compiler. Will assume none
506             $Pkg: necessary.
507             EOD
508 1         2 $Cflags = '';
509             }
510              
511 1         24 config_log "$Pkg: Cflags: $Cflags\n";
512              
513             } # End of import ()
514              
515             =head1 METHODS
516              
517             The following methods are provided:
518              
519             =over 4
520              
521             =item * B
522              
523             Returns a list of F77 runtime libraries.
524              
525             $fortranlibs = Module::Build::FFI::Fortran::ExtUtilsF77->runtime;
526              
527             =item * B
528              
529             Returns TRUE only if runtime libraries have been found successfully.
530              
531             =item * B
532              
533             Returns true if F77 names have trailing underscores.
534              
535             =item * B
536              
537             Returns command to execute the compiler (e.g. 'f77').
538              
539             =item * B
540              
541             Returns compiler flags.
542              
543             =item * B
544              
545             Test to see if compiler actually works.
546              
547             =back
548              
549             More methods will probably be added in the future.
550              
551             =cut
552            
553 1     1 1 4 sub runtime { return $Runtime; }
554 0     0 1 0 sub runtimeok { return $RuntimeOK; }
555 1     1 1 3 sub trail_ { return $Trail_; }
556 1     1 1 5 sub compiler { return $Compiler; }
557 1     1 1 4 sub cflags { return $Cflags; }
558              
559             ### Minor internal utility routines ###
560              
561             # Get hash entry, evaluating code references
562              
563 3 50   3 0 13 sub get { ref($_[0]) eq "CODE" ? &{$_[0]} : $_[0] };
  0         0  
564              
565             # Test if any files exist matching glob
566              
567             sub any_exists {
568 0     0 0 0 my @glob = glob(shift);
569 0         0 return scalar(@glob);
570             }
571              
572             # Find highest version number of SCN.N(.N) directories
573             # (Nasty SunOS/Solaris naming scheme for F77 libs]
574             sub find_highest_SC {
575 0     0 0 0 config_log "$Pkg: Scanning for $_[0]\n";
576 0         0 my @glob = glob(shift);
577 0         0 my %n=();
578 0         0 for (@glob) {
579             #print "Found $_\n";
580 0 0       0 if ( m|/SC(\d)\.(\d)/?.*$| ) {
581 0         0 $n{$_} = $1 *100 + $2 * 10;
582             }
583 0 0       0 if ( m|/SC(\d)\.(\d)\.(\d)/?.*$| ) {
584 0         0 $n{$_} = $1 *100 + $2 * 10 + $3;
585             }
586             }
587 0         0 my @sorted_dirs = grep {-f "$_/libF77.a"} sort {$n{$a} <=> $n{$b}} @glob;
  0         0  
  0         0  
588              
589 0         0 return pop @sorted_dirs; # Highest N
590             }
591              
592             # Validate a string of form "-Ldir -lfoo -lbar"
593              
594             sub validate_libs {
595 0     0 0 0 config_log "$Pkg: Validating $_[0] ";
596 0         0 my @args = split(' ',shift());
597 0         0 my $pat;
598 0         0 my $ret = 1;
599              
600             # Create list of directories to search (with common defaults)
601              
602 0         0 my @path = ();
603 0         0 for (@args, "/usr/lib", "/lib") {
604 0 0 0     0 push @path, $1 if /^-L(.+)$/ && -d $1;
605             }
606              
607             # Search directories
608              
609 0         0 for (@args) {
610 0 0       0 next if /^-L/;
611 0 0       0 next if $_ eq "-lm"; # Ignore this common guy
612 0 0       0 if (/^-l(.+)$/) {
613 0         0 $pat = join(" ", map {$_."/lib".$1.".*"} @path); # Join dirs + file
  0         0  
614             #print "Checking for $pat\n";
615 0 0       0 unless (any_exists($pat)) {
616 0         0 config_log "\n$Pkg: Unable to find library $_" ;
617 0         0 $ret = 0;
618             }
619             }
620             }
621 0 0       0 config_log $ret ? "[ok]\n" : "\n";
622 0         0 return $ret;
623             }
624              
625              
626             sub testcompiler {
627              
628 0     0 1 0 my $file = File::Spec->tmpdir . "/testf77$$";
629 0         0 $file =~ s/\\/\//g; # For Win32
630              
631 0         0 my $ret;
632 0         0 open(OUT,">$file.f");
633 0         0 print OUT " print *, 'Hello World'\n";
634 0         0 print OUT " end\n";
635 0         0 close(OUT);
636 0         0 config_log "Compiling the test Fortran program...\n";
637 0         0 system "$Compiler $Cflags $file.f -o ${file}_exe";
638 0         0 config_log "Executing the test program...\n";
639 0 0       0 if (`${file}_exe` ne " Hello World\n") {
640 0         0 config_log "Test of Fortran Compiler FAILED. \n";
641 0         0 config_log "Do not know how to compile Fortran on your system\n";
642 0         0 $ret=0;
643             }
644             else{
645 0         0 config_log "Congratulations you seem to have a working f77!\n";
646 0         0 $ret=1;
647             }
648 0 0       0 unlink("${file}_exe"); unlink("$file.f"); unlink("$file.o") if -e "$file.o";
  0         0  
  0         0  
649 0         0 return $ret;
650             };
651              
652             # gcclibs() routine
653             # Return gcc link libs (e.g. -L/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3_U1/2.7.0 -lgcc)
654             # Note this routine appears to be no longer required - gcc3 or 4 change? - and is
655             # NO LONGER CALLED from anywhere in the code. Use of this routine in the future
656             # is DEPRECATED. Retain here just in case this logic is ever needed again,
657             # - Karl Glazebrook Dec/2010
658              
659             sub gcclibs {
660 0     0 0 0 my $flibs = shift; # Fortran libs
661 0         0 my $isgcc = $Config{'cc'} eq "$gcc";
662 0 0 0     0 if (!$isgcc && $^O ne 'VMS') {
663 0         0 config_log "Checking for gcc in disguise:\n";
664 0 0       0 $isgcc = 1 if $Config{gccversion};
665 0         0 my $string;
666 0 0       0 if ($isgcc) {
667 0         0 $string = "Compiler is gcc version $Config{gccversion}";
668 0 0       0 $string .= "\n" unless $string =~ /\n$/;
669             } else {
670 0         0 $string = "Not gcc\n";
671             }
672 0         0 config_log $string;
673             }
674 0 0 0     0 if ($isgcc or ($flibs =~ /-lg2c/) or ($flibs =~ /-lf2c/) ) {
      0        
675             # Don't link to libgcc on MS Windows iff we're using gfortran.
676 0 0 0     0 unless($fallback_compiler eq 'GFortran' && $^O =~ /MSWin/i) {
677 0         0 my $gccdir = `$gcc -m32 -print-libgcc-file-name`; chomp $gccdir;
  0         0  
678 0         0 $gccdir =~ s/\/libgcc.a//;
679 0         0 return " -L$gccdir -lgcc";
680             }else{
681 0         0 return "";
682             }
683              
684             }else{
685 0         0 return "";
686             }
687             }
688              
689             # Try and find a program in the users PATH
690              
691             sub find_in_path {
692 5     5 0 11 my @names = @_;
693 5         7 my @path;
694 5 50       14 if($^O =~ /mswin32/i) {
695 0         0 for(@names) { $_ .= '.exe'}
  0         0  
696 0         0 @path = split(";", $ENV{PATH});
697             }
698 5         30 else {@path = split(":",$ENV{PATH})}
699 5         9 my ($name,$dir);
700 5         9 for $name (@names) {
701 19 50       46 return $name if exists $CACHE{$name};
702 19         33 for $dir (@path) {
703 171 50       1348 if (-x $dir."/$name") {
704 0         0 config_log "Found compiler $name\n";
705 0         0 $CACHE{$name}++;
706 0         0 return $name;
707             }
708             }
709             }
710 5 50       20 return '' if $^O eq 'VMS';
711 5         18 return undef;
712             # die "Unable to find a fortran compiler using names: ".join(" ",@names);
713             }
714              
715             # Based on code from Tim Jeness, tries to figure out the correct GNU
716             # fortran compiler libs
717             sub link_gnufortran_compiler {
718 2 50   2 0 6 return () if $^O =~ /MSWin32/i; # Unneeded for MinGW, emits warnings if allowed to proceed.
719 2         6 my @try = @_;
720 2         6 my $compiler = find_in_path( @try );
721             # all the compilers and their libraries
722 2         14 my %complibs = (
723             g77 => [qw/ g2c f2c /],
724             f77 => [qw/ g2c f2c /],
725             fort77 => [qw/ g2c f2c /],
726             gfortran => [qw/ gfortran /],
727             g95 => [qw/ f95 /],
728             );
729 2 50       14 return () unless defined $compiler;
730 0           my @libs = @{$complibs{$compiler}};
  0            
731 0           my ($dir, $lib, $test);
732 0           foreach $test (@libs) {
733 0           $dir = `$compiler -print-file-name=lib$test.a`;
734 0           chomp $dir;
735             # Note that -print-file-name returns just the library name
736             # if it cant be found - make sure that we only accept the
737             # directory if it returns a proper path (or matches a /)
738 0 0 0       if (defined $dir && $dir ne "lib$test.a") {
739 0           $lib = $test; # Found an existing library
740 0           $dir =~ s,/lib$lib.a$,,;
741 0           last;
742             } else {
743             # Try the same thing again but looking for the .so file
744             # rather than the .a file.
745 0           $dir = `$compiler -print-file-name=lib$test.so`;
746 0           chomp $dir;
747 0 0 0       if (defined $dir && $dir ne "lib$test.so") {
748 0           $lib = $test; # Found an existing library
749 0           $dir =~ s,/lib$lib.so$,,;
750 0           last;
751             } else {
752 0           $dir = "/usr/local/lib";
753 0           $lib = "f2c";
754             }
755             }
756             }
757 0           return( "-L$dir -L/usr/lib -l$lib -lm" );
758             }
759              
760              
761             =head1 AUTHOR
762              
763             Karl Glazebrook (karlglazebrook@mac.com).
764              
765             =head1 COPYRIGHT AND LICENSE
766              
767             Copyright (c) 2001 by Karl Glazebrook. All rights reserved. This distribution
768             is free software; you can redistribute it and/or modify it under the same
769             terms as Perl itself.
770              
771             THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
772             OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
773             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
774             ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
775             DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
776             DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
777             OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
778             HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
779             STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
780             IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
781             POSSIBILITY OF SUCH DAMAGE.
782              
783             BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
784             FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
785             OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
786             PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
787             EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
788             WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
789             THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
790             WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
791             ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
792              
793             IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
794             WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
795             REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
796             DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL
797             DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM
798             (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED
799             INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF
800             THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER
801             OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
802              
803             =cut
804              
805              
806             1; # Return true
807              
808              
809              
810