MM_Solaris_ON.pm revision 1410:1b2e7ae0aee9
1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or http://www.opensolaris.org/os/licensing. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21 22# 23# Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26# ident "%Z%%M% %I% %E% SMI" 27# 28 29# 30# MM_Solaris_ON.pm overrides various parts of MakeMaker so that perl modules 31# build correctly as part of Solaris/ON. The changes are: 32# 1. parse_args is overriden to merge the values of DEFINE specified in 33# Makefile.PL and on the command line. The default behaviour is that 34# the command line value overwrites any value specified in Makefile.PL. 35# 2. constants() is overriden to add the include paths specified in the 36# ENVCPPFLAGS[1-n] environment variables to the compiler command-line so 37# that the compiler looks in the proto area for include files. 38# 3. ext() is overriden to add the library paths specified in the 39# ENVLDLIBS[1-n] environment variables to the linker command-line so 40# that the linker looks in the proto area for libraries. 41# 42 43# Plug into Makemaker - see ExtUtils::MM_*.pm 44package ExtUtils::MM_Solaris_ON; 45use strict; 46use warnings; 47our ($VERSION, @ISA); 48$VERSION = '%I%'; 49require ExtUtils::MM_Any; 50require ExtUtils::MM_Unix; 51@ISA = qw(ExtUtils::MM_Any ExtUtils::MM_Unix); 52use ExtUtils::MakeMaker qw(&neatvalue); 53 54# 55# The default MakeMaker parse_args function overwrites DEFINE values passed 56# to WriteMakefile with the values specified on the command line, which is 57# obviously broken. This overrides the default implementation and merges the 58# WriteMakefile and command line versions. See ExtUtils::MakeMaker.pm for 59# details of the parse_args() method. Because parse_args isn't an overrideable 60# MakeMaker method, we have to pull some dirty tricks with the MakeMaker stash 61# to make this work. 62# 63our $real_parse_args; 64BEGIN { 65 $real_parse_args = *ExtUtils::MakeMaker::parse_args{CODE}; 66 no warnings qw(redefine); 67 *ExtUtils::MakeMaker::parse_args = \&parse_args; 68} 69sub parse_args 70{ 71 my ($self, @args) = @_; 72 73 my $define = exists($self->{DEFINE}) ? $self->{DEFINE} : undef; 74 $self->$real_parse_args(@args); 75 $self->{DEFINE} = "$define $self->{DEFINE}" 76 if (defined($define) && exists($self->{DEFINE})); 77} 78 79# 80# The constants() method works out the compiler flags needed to build a module. 81# Override it to take into account the current settings of the ENVCPPFLAGS[1-n] 82# environment variables when building as part of Solaris/ON. See 83# ExtUtils::MM_Unix for details of the constants() method. 84# 85sub constants 86{ 87 my ($self) = @_; 88 89 # Find all the ENVCPPFLAGS[1-n] environment variables 90 my (%inc_seen, @newincs, %proto_seen, @protos); 91 foreach my $ip (map({ /^ENVCPPFLAGS\d+$/ ? split(' ', $ENV{$_}) : () } 92 sort(keys(%ENV)))) { 93 # Ignore everything except '-I' flags. 94 next unless ($ip =~ s!^-I(.*)$!$1!); 95 96 # Add to newincs if not seen before. 97 push(@newincs, "-I$ip") unless ($inc_seen{$ip}++); 98 99 # 100 # If the path points to somewhere under a proto area, 101 # figure out the top of the proto area & save for later. 102 # 103 next unless ($ip =~ s!^(.*/proto/root_[^/]+)/.*$!$1!); 104 push(@protos, $ip) unless ($proto_seen{$ip}++); 105 } 106 107 # Search INC string, prepending the proto areas to any absolute paths. 108 foreach (split(' ', exists($self->{INC}) ? $self->{INC} : '')) { 109 # Deal with -I flags 110 if (my ($p) = $_ =~ /^-I(.*)$/) { 111 # Only prepend to absolute paths 112 if ($self->file_name_is_absolute($p)) { 113 foreach my $pp (@protos) { 114 my $ppp = "$pp$p"; 115 push(@newincs, "-I$ppp") 116 unless ($inc_seen{$ppp}++); 117 } 118 # Pass relative paths through. 119 } else { 120 push(@newincs, "-I$p") unless ($inc_seen{$p}++); 121 } 122 123 # Pass anything else through. 124 } else { 125 push(@newincs, $_); 126 } 127 } 128 129 # Call the default Unix constants() method (see MM_Unix.pm) 130 $self->{INC} = join(' ', @newincs); 131 return ($self->ExtUtils::MM_Unix::constants()); 132} 133 134# 135# The ext() method works out the linker flags required to build a module. 136# Override it to take into account the current settings of the ENVLDLIBS[1-n] 137# environment variables when building as part of Solaris/ON. Also remove the 138# LD_RUN_PATH that is returned by the default implementation, as it is not 139# correct when building as part of Solaris/ON. See ExtUtils::Liblist for 140# details of the ext() method. 141# 142sub ext 143{ 144 my ($self, $libs, $verbose, $need_names) = @_; 145 146 # Find all the ENVLDLIBS[1-n] environment variables 147 my (%lib_seen, @lib_prefix, @newlibs, %proto_seen, @protos); 148 foreach my $lp (map({ /^ENVLDLIBS\d+$/ ? split(' ', $ENV{$_}) : () } 149 sort(keys(%ENV)))) { 150 # Ignore everything except '-L' flags 151 next unless ($lp =~ s!^-L(.*)$!$1!); 152 153 # Add to lib_prefix if not seen before 154 push(@lib_prefix, "-L$lp") unless ($lib_seen{$lp}++); 155 156 # 157 # If the path points to somewhere under a proto area, 158 # figure out the top of the proto area & save for later 159 # 160 next unless ($lp =~ s!^(.*/proto/root_[^/]+)/.*$!$1!); 161 push(@protos, $lp) unless ($proto_seen{$lp}++); 162 } 163 164 # Search libs string, prepending the proto areas to any absolute paths 165 %lib_seen = (); 166 foreach (split(' ', $libs)) { 167 # Deal with -L flags 168 if (my ($p) = $_ =~ /^-L(.*)$/) { 169 # Only prepend to absolute paths 170 if ($self->file_name_is_absolute($p)) { 171 foreach my $pp (@protos) { 172 my $ppp = "$pp$p"; 173 push(@newlibs, "-L$ppp") 174 unless ($lib_seen{$ppp}++); 175 } 176 # Pass relative paths through 177 } else { 178 push(@newlibs, "-L$p") unless ($lib_seen{$p}++); 179 } 180 181 # Pass anything else through 182 } else { 183 push(@newlibs, $_); 184 } 185 } 186 187 # Call the default Unix ext() method (see Liblist.pm) 188 require ExtUtils::Liblist; 189 my @retval = $self->ExtUtils::Liblist::Kid::ext(join(' ', @newlibs), 190 $verbose, $need_names); 191 192 # 193 # Prepend any missing members of @lib_prefix onto LDLOADLIBS. 194 # Do this after calling ext() as ext() will strip out all the -L flags 195 # if passed an empty library list. Note we don't touch EXTRALIBS as 196 # it is only used to create the extralibs.ld file, and we don't want 197 # the ON environment leaking out into shipped files. 198 # 199 my $prefix = join(' ', grep({ ! $lib_seen{$_}++ } @lib_prefix)); 200 $prefix .= ' '; 201 $retval[2] = $prefix . $retval[2]; # LDLOADLIBS 202 203 # By default any directories containing libraries are returned as part 204 # LD_RUN_PATH. When building Solaris/ON, we don't want this behaviour 205 # as it results in the proto area being stored in RPATH in the resulting 206 # perl module.so files, so we null it out here. 207 # 208 $retval[3] = ''; 209 return (@retval); 210} 211 2121; 213