xref: /onnv-gate/usr/src/cmd/perl/5.8.4/utils/lib/ExtUtils/MM_Solaris_ON.pm (revision 7298:b69e27387f74)
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