1# Copyright (C) 2005-2014, Parrot Foundation. 2 3=head1 NAME 4 5config/inter/libparrot.pm - Determines build information for libparrot 6 7=head1 DESCRIPTION 8 9libparrot is the library containing the parrot VM. This configuration 10step determines whether it should be build static or shared. 11 12=cut 13 14package inter::libparrot; 15 16use strict; 17use warnings; 18 19use base qw(Parrot::Configure::Step); 20 21use File::Spec (); 22use Parrot::Configure::Utils ':inter'; 23 24 25sub _init { 26 my $self = shift; 27 my %data; 28 $data{description} = q{Should parrot link against a shared library}; 29 $data{result} = q{}; 30 return \%data; 31} 32 33sub runstep { 34 my ( $self, $conf ) = @_; 35 my $enable_shared = !$conf->options->get('disable-shared'); 36 my $disable_rpath = $conf->options->get('disable-rpath'); 37 38 $enable_shared = integrate( 39 $conf->data->get('enable-shared'), 40 $enable_shared 41 ); 42 43 # let the command-line override the failed has_dynamic_linking probe 44 unless ($conf->data->get('has_dynamic_linking')) { 45 $enable_shared = 0 unless $conf->options->get('enable-shared'); 46 } 47 $enable_shared = 0 if $conf->options->get('enable-static'); 48 49 # Parrot can't necessarily handle a pre-existing installed shared 50 # libparrot.so without rpath. 51 # At this point, we don't know the actual name of the shared parrot 52 # library. So we try some candidates. 53 my @libs = get_libs(); 54 my @libpaths = get_libpaths($conf); 55 if ($disable_rpath or !$conf->data->get('rpath')) { 56 foreach my $f (@libs) { 57 foreach my $d (@libpaths) { 58 my $oldversion = File::Spec->catfile($d, $f); 59 if (-e $oldversion) { 60 warn("\nWarning: Building a shared parrot library may conflict " . 61 "with your previously-installed $oldversion\n"); 62 } 63 } 64 } 65 } 66 67 if ( 68 $conf->options->get('ask') 69 && 70 $conf->data->get('has_dynamic_linking') 71 ) { 72 $enable_shared = prompt( 73 "\nShould parrot be built using a shared library?", 74 $enable_shared ? 'y' : 'n' 75 ); 76 77 $enable_shared = lc($enable_shared) eq 'y'; 78 } 79 80 $conf->data->set( 81 parrot_is_shared => $enable_shared, 82 libparrot_for_makefile_only => $enable_shared 83 ? '$(LIBPARROT_SHARED)' 84 : '$(LIBPARROT_STATIC)', 85 ); 86 87 # Set -rpath (or equivalent) for executables to find the 88 # shared libparrot in the build directory. 89 $conf->data->set( rpath_blib => ( ! $disable_rpath 90 && $enable_shared 91 && $conf->data->get('rpath') ) 92 ? '"' . $conf->data->get('rpath') 93 . $conf->data->get('build_dir') 94 . '/' 95 . $conf->data->get('blib_dir') . '"' 96 : '' 97 ); 98 99 # Set -rpath (or equivalent) for the installed executables to find the 100 # installed shared libparrot. 101 $conf->data->set( rpath_lib => ( ! $disable_rpath 102 && $enable_shared 103 && $conf->data->get('rpath') ) 104 ? $conf->data->get('rpath') 105 . '"' . $conf->data->get('libdir') . '"' 106 : '' 107 ); 108 109 # When building shared libraries and dynamically loadable 110 # modules with 'ld', do we need to include -lparrot? If so 111 # this variable contains the necessary flags. (This is normally 112 # empty, but may be overridden by various hints files for 113 # specific platforms.) 114 115 # This version works in the build directory. 116 unless ( defined( $conf->data->get('libparrot_ldflags') ) ) { 117 $conf->data->set(libparrot_ldflags => ''); 118 } 119 120 # This version refers to the installed library. 121 unless ( defined( $conf->data->get('inst_libparrot_ldflags') ) ) { 122 $conf->data->set(inst_libparrot_ldflags => ''); 123 } 124 125 # When linking an executable to -lparrot, this variable 126 # contains the necessary flags to find and use -lparrot. 127 128 # This version uses the -lparrot in the build directory. 129 unless ( defined( $conf->data->get('libparrot_linkflags') ) ) { 130 $conf->data->set(libparrot_linkflags => 131 '-L"' 132 . $conf->data->get('build_dir') 133 . '/' 134 . $conf->data->get('blib_dir') 135 . '" -lparrot' 136 ); 137 } 138 139 # This version uses the installed -lparrot. 140 unless ( defined( $conf->data->get('inst_libparrot_linkflags') ) ) { 141 $conf->data->set(inst_libparrot_linkflags => 142 '-L"' 143 . $conf->data->get('libdir') 144 . '" -lparrot' 145 ); 146 } 147 148 $self->set_result( $enable_shared ? 'yes' : 'no' ); 149 150 return 1; 151} 152 153sub get_libs { 154 my @libs = ('libparrot.so'); 155 if ($^O eq 'MSWin32') { 156 @libs = ('libparrot.dll', 'libparrot.lib', 'libparrot.dll.a'); 157 } 158 if ($^O eq 'cygwin') { 159 @libs = ('libparrot.dll.a'); 160 } 161 if ($^O eq 'darwin'){ 162 @libs = qw/libparrot.dylib libparrot.a/; 163 } 164 return @libs; 165} 166 167sub get_libpaths { 168 my $conf = shift; 169 my @libpaths = ('/usr/local/lib', '/usr/lib', $conf->data->get('libdir')); 170 if ($^O eq 'MSWin32') { 171 push @libpaths, (split /;/, $ENV{PATH}); 172 } 173 if (defined $ENV{LD_LIBRARY_PATH}) { 174 push @libpaths, (split /:/, $ENV{LD_LIBRARY_PATH}); 175 } 176 if (defined $ENV{LD_RUN_PATH}) { 177 push @libpaths, (split /:/, $ENV{LD_RUN_PATH}); 178 } 179 if (defined $ENV{DYLD_LIBRARY_PATH}) { 180 push @libpaths, (split /:/, $ENV{DYLD_LIBRARY_PATH}); 181 } 182 return @libpaths; 183} 184 1851; 186 187# Local Variables: 188# mode: cperl 189# cperl-indent-level: 4 190# fill-column: 100 191# End: 192# vim: expandtab shiftwidth=4: 193