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