PageRenderTime 24ms CodeModel.GetById 1ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 1ms

/inc/My/Builder.pm

http://github.com/PerlGameDev/SDL
Perl | 196 lines | 126 code | 26 blank | 44 comment | 16 complexity | d0dcdb469721d258b1182f25d749f9ab MD5 | raw file
  1#!/usr/bin/env perl
  2#
  3# Build.pm
  4#
  5# Copyright (C) 2005 David J. Goehrig <dgoehrig@cpan.org>
  6#
  7# ------------------------------------------------------------------------------
  8#
  9# This library is free software; you can redistribute it and/or
 10# modify it under the terms of the GNU Lesser General Public
 11# License as published by the Free Software Foundation; either
 12# version 2.1 of the License, or (at your option) any later version.
 13#
 14# This library is distributed in the hope that it will be useful,
 15# but WITHOUT ANY WARRANTY; without even the implied warranty of
 16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17# Lesser General Public License for more details.
 18#
 19# You should have received a copy of the GNU Lesser General Public
 20# License along with this library; if not, write to the Free Software
 21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22#
 23# ------------------------------------------------------------------------------
 24#
 25# Please feel free to send questions, suggestions or improvements to:
 26#
 27#	David J. Goehrig
 28#	dgoehrig@cpan.org
 29#
 30
 31package My::Builder;
 32
 33use strict;
 34use warnings;
 35use base 'Module::Build';
 36
 37use Carp;
 38use File::Spec;
 39use Config;
 40use Alien::SDL::ConfigData;
 41
 42our $config = {};
 43
 44# Module::Build doesn't seem to have a way to use separate flags for separate
 45# XS files, so here's the override that makes separate files build correctly:
 46sub process_xs {
 47	my ( $self, $file ) = @_;
 48
 49	my $properties = $self->{properties};
 50	my $file_args  = $self->notes('file_flags')->{$file};
 51
 52	return unless defined($file_args);
 53
 54	my @old_values = @$properties{ keys %$file_args };
 55	@$properties{ keys %$file_args } = values %$file_args;
 56
 57	$self->SUPER::process_xs($file);
 58	@$properties{ keys %$file_args } = @old_values;
 59}
 60
 61# which headers are installed?
 62sub find_subsystems {
 63	my ( $self, $subsystems, $libraries ) = @_;
 64	my %found;
 65	my %enabled;
 66	while ( my ( $name, $subsystem ) = each %$subsystems ) {
 67		my $param;
 68		for my $library ( @{ $subsystem->{libraries} } ) {
 69			my $lib = $libraries->{$library}
 70				or Carp::confess "Unknown library '$library' for '$name'\n";
 71			my $h =
 72				ref( $lib->{header} ) eq 'ARRAY'
 73				? $lib->{header}
 74				: [ $lib->{header} ];
 75			my $need_check = 0;
 76			foreach (@$h) {
 77				$need_check = 1 unless $found{$_};
 78			}
 79			if ( !$need_check || Alien::SDL->check_header(@$h) ) {
 80				$found{$_} = 1 foreach (@$h);
 81				$param->{libs}->{$library} = 1;
 82				push @{ $param->{defines} }, "-D$libraries->{$library}{define}";
 83				push @{ $param->{links} },   "-l$libraries->{$library}{lib}";
 84			} else {
 85
 86				# I disabled that, so the libs are compiled but the HAVE_* defines are not set
 87				# so we can e.g. 'use SDL::Pango;' (FROGGS)
 88				# $param = undef;
 89
 90				print "###WARNING### Disabling subsystem '$name'\n";
 91				last;
 92			}
 93		}
 94		$enabled{$name} = $param if $param;
 95	}
 96	return \%enabled;
 97}
 98
 99# create mapping table: { SDL::Any::Lib => [ list of libs ], SDL::Any::OtherLib => [ list of libs ] ... }
100# to keep information what libs (.dll|.so) to load via Dynaloader for which module
101sub translate_table {
102	my ( $self, $subsystems, $libraries ) = @_;
103	my %ret;
104	foreach my $m ( keys %$subsystems ) {
105		my $p = $subsystems->{$m}->{file}->{to};
106		$p =~ s|^lib/(.*)\.xs|$1|;
107		$p =~ s|/|::|g;
108		my @list =
109			map ( $libraries->{$_}->{lib}, @{ $subsystems->{$m}->{libraries} } );
110		$ret{$p} = \@list;
111	}
112	return \%ret;
113}
114
115# save this all in a format process_xs() can understand
116sub set_file_flags {
117	my $self = shift;
118	my %file_flags;
119	my %build_systems = %{ $self->notes('build_systems') };
120
121	#TODO:  Search for execinfo.h signal.h and turn this on.
122	#	This should also be turned on only during CPAN tests
123	my $debug = ' -DNOSIGCATCH '; #default until headers found
124	if ( Alien::SDL->check_header(qw(execinfo.h signal.h))
125		&& $ENV{AUTOMATED_TESTING} )
126	{
127		$debug .= ' -g -rdynamic ' unless ( $^O =~ /(win|darwin|bsd)/i );
128
129	} else {
130		$debug .= ' -O2 ';
131	}
132
133	my $arch = ' ';
134	$arch = '-arch' . $ENV{SDL_ARCH} if $ENV{SDL_ARCH};
135
136	while ( my ( $subsystem, $param ) = each %build_systems ) {
137		my $sub_file = $self->notes('subsystems')->{$subsystem}{file}{to};
138		my $extra_compiler_flags = [
139			( split( ' ', $arch . $debug . $self->notes('sdl_cflags') ) ),
140			@{ $param->{defines} },
141		];
142		push(@{$extra_compiler_flags}, '-DUSE_THREADS') if defined $Config{usethreads};
143		push(@{$extra_compiler_flags}, '-fPIC')         if $^O ne 'MSWin32';
144		$file_flags{$sub_file} = {
145			extra_compiler_flags => $extra_compiler_flags,
146			extra_linker_flags => [
147				( split( ' ', $self->notes('sdl_libs') ) ),
148				@{ $param->{links} },
149			],
150		};
151	}
152	$self->notes( 'file_flags' => \%file_flags );
153}
154
155# override the following functions in My::Builder::<platform> if necessary
156sub ACTION_build {
157	my $self = shift;
158
159	printf(
160		"[Alien::SDL] Build option used:\n\t%s\n",
161		${ Alien::SDL::ConfigData->config('build_params') }{'title'} || 'n.a.'
162	);
163	$self->SUPER::ACTION_build;
164	$self->ACTION_bundle;
165}
166
167# both special to MacOS/Darwin, somebody should review whether it is still necessary
168sub special_build_settings { }
169sub build_bundle           { }
170
171# build_bundle() currently defined only for MacOS
172sub ACTION_bundle {
173	my ($self) = @_;
174	$self->depends_on('build');
175	$self->build_bundle();
176}
177
178# inc/My/Darwin.pm will override Install method for MacOS
179sub ACTION_install {
180	my ($self) = @_;
181	require ExtUtils::Install;
182	$self->depends_on('build');
183	ExtUtils::Install::install(
184		$self->install_map, 1, 0,
185		$self->{args}{uninst} || 0
186	);
187}
188
189sub ACTION_test {
190	my ($self) = @_;
191	$self->depends_on('build');
192
193	$self->SUPER::ACTION_test();
194}
195
1961;