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 42 package ExtUtils::MM_Solaris_ON; 43 use strict; 44 use warnings; 45 our ($VERSION, @ISA); 46 $VERSION = '1.3'; 47 require ExtUtils::MM_Any; 48 require ExtUtils::MM_Unix; 49 @ISA = qw(ExtUtils::MM_Any ExtUtils::MM_Unix); 50 use 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 # 61 our $real_parse_args; 62 BEGIN { 63 $real_parse_args = *ExtUtils::MakeMaker::parse_args{CODE}; 64 no warnings qw(redefine); 65 *ExtUtils::MakeMaker::parse_args = \&parse_args; 66 } 67 sub 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 # 83 sub 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 # 146 sub 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 216 1; 217