Home | History | Annotate | Download | only in ExtUtils
      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