1# Copyright (C) 2005-2007, Parrot Foundation.
2
3package init::hints::linux;
4
5use strict;
6use warnings;
7
8sub runstep {
9    my ( $self, $conf ) = @_;
10
11    my $libs      = $conf->option_or_data('libs');
12    my $ccflags   = $conf->option_or_data('ccflags');
13    my $cc        = $conf->option_or_data('cc');
14    my $linkflags = $conf->option_or_data('linkflags');
15    my $share_ext = $conf->option_or_data('share_ext');
16    my $version   = $conf->option_or_data('VERSION');
17
18    $conf->debug("\n");
19
20    # should find g++ in most cases
21    my $link = $conf->data->get('link') || 'c++';
22
23    if ( $libs !~ /-lpthread\b/ ) {
24        $libs .= ' -lpthread';
25    }
26    if ( $libs !~ /-lrt\b/ ) {
27        $libs .= ' -lrt';
28    }
29    my $ld_share_flags = $conf->data->get('ld_share_flags');
30    my $cc_shared      = $conf->data->get('cc_shared');
31
32    if ( $cc =~ /icc/ ) {
33
34        # Intel C++ compiler has the same name as its C compiler
35        $link = $cc;
36        $ld_share_flags = ' -shared -g -pipe -fexceptions -fPIC';
37        $cc_shared .= ' -fPIC';
38
39        $ccflags = _handle_icc_ccflags($conf, $ccflags);
40
41    }
42    elsif ( $cc =~ /suncc/ ) {
43        $link = 'sunCC';
44        if ( $ld_share_flags !~ /-KPIC/ ) {
45            $ld_share_flags = '-KPIC';
46        }
47        if ( $cc_shared !~ /-KPIC/ ) {
48            $cc_shared = '-KPIC';
49        }
50    }
51    else {
52        if ( $ld_share_flags !~ /-fPIC/ ) {
53            $ld_share_flags .= ' -fPIC';
54        }
55        if ( $cc_shared !~ /-fPIC/ ) {
56            $cc_shared .= ' -fPIC';
57        }
58
59        # --export-dynamic, s. info gcc, ld
60        $linkflags .= ' -Wl,-E';
61    }
62
63    if ( $ccflags !~ /-D_GNU_SOURCE/ ) {
64
65        # Request visibility of all POSIX symbols
66        # _XOPEN_SOURCE=600 doesn't work with glibc 2.1.3
67        # _XOPEN_SOURCE=500 gives 2 undefined warns (setenv, unsetenv) on 2.1.3
68        $ccflags .= ' -D_GNU_SOURCE';
69    }
70
71    my $osvers = `/sbin/sysctl -n kernel.osrelease`;
72    chomp $osvers;
73
74    my %linux_selections = (
75        ccflags         => $ccflags,
76        libs            => $libs,
77        ld_share_flags  => $ld_share_flags,
78        ld_load_flags   => $ld_share_flags,
79        linkflags       => $linkflags,
80        link            => $link,
81        cc_shared       => $cc_shared,
82        rpath           => '-Wl,-rpath=',
83        osvers          => $osvers,
84
85        has_dynamic_linking    => 1,
86        parrot_is_shared       => 1,
87        libparrot_shared       => "libparrot$share_ext.$version",
88        libparrot_shared_alias => "libparrot$share_ext",
89        libparrot_soname       => "-Wl,-soname=libparrot$share_ext.$version",
90    );
91    if ( ( split( m/-/, $conf->data->get('archname_provisional'), 2 ) )[0] eq 'ia64' ) {
92
93        $linux_selections{platform_asm} = 1;
94    }
95    my $linux_hints = "Linux hints settings:\n";
96    for my $k (sort keys %linux_selections) {
97        $linux_hints .= sprintf("  %-24s => %s\n" => (
98                $k, qq|'$linux_selections{$k}'|,
99        ) );
100    }
101    $conf->debug($linux_hints);
102
103    $conf->data->set( %linux_selections );
104    return;
105}
106
107sub _handle_icc_ccflags {
108    my ($conf, $ccflags) = @_;
109
110    # enable correct floating point behavior
111    # which is *not* the default behavior. ahem.
112    $ccflags .= ' -we147';
113
114    # TT #1488. ICC optimizes floating-point too aggressively and loses support
115    # for negative zero without this.
116    $ccflags .= ' -fp-model source';
117
118    $conf->debug(" ccflags: $ccflags\n");
119    return $ccflags;
120}
121
1221;
123
124# Local Variables:
125#   mode: cperl
126#   cperl-indent-level: 4
127#   fill-column: 100
128# End:
129# vim: expandtab shiftwidth=4:
130