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