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