Can't do that :(
[sdlgit/SDL_perl.git] / make / lib / SDL / Build.pm
CommitLineData
bfd90409 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 SDL::Build;
32
33use strict;
084b921f 34use warnings;
35use Carp;
bfd90409 36use base 'Module::Build';
37
38use File::Spec;
39use Data::Dumper;
40use Config;
41
42# Module::Build doesn't seem to have a way to use separate flags for separate
43# XS files, so here's the override that makes separate files build correctly:
44sub process_xs
45{
46 my ($self, $file) = @_;
f3e4e3e6 47
48 #TODO: call this in MSWin32::process_xs
49 $file =~ s/\\/\//g if( $^O =~ /MSWin.*/ );
50
bfd90409 51 my $properties = $self->{properties};
52 my $file_args = $self->notes( 'file_flags' )->{$file};
53 my @old_values = @$properties{ keys %$file_args };
54 @$properties{ keys %$file_args } = values %$file_args;
55
56 $self->SUPER::process_xs( $file );
57 @$properties{ keys %$file_args } = @old_values;
58}
59
60
61# every platform has slightly different library and header paths
62sub get_arch
63{
64 my ($self, $os) = @_;
65 my $modpath = File::Spec->catfile(
66 'SDL', 'Build', ucfirst( $os ) . '.pm' );
67 my $module = 'SDL::Build::' . ucfirst( $os );
68
084b921f 69 require $modpath or croak "No module for $os platform\n";
bfd90409 70
71 return $module;
72}
73
74# which headers are installed?
75sub find_subsystems
76{
77 my ($self, $subsystems, $libraries) = @_;
78 my %includes_libs = $self->fetch_includes();
79 my %enabled;
80
81 while ( my ($name, $subsystem) = each %$subsystems )
82 {
83 for my $library (@{ $subsystem->{libraries} })
84 {
85 my $lib = $libraries->{$library}
084b921f 86 or croak "Unknown library '$library' for '$name'\n";
bfd90409 87
88 my ($inc_dir, $link_dir) =
89 $self->find_header( $lib->{header}, \%includes_libs );
90 $enabled{$name}{ $library } = $inc_dir ? [ $inc_dir, $link_dir ]
91 : 0;
92 }
93 }
94
95 return \%enabled;
96}
97
98# set the define flags for the libraries we have
99sub build_defines
100{
101 my ($self, $libraries, $build_systems) = @_;
102
103 my %defines;
104
105 while (my ($subsystem, $buildable) = each %$build_systems)
106 {
107 for my $build (grep { $buildable->{ $_ } } keys %$buildable)
108 {
109 push @{ $defines{ $subsystem } }, "-D$libraries->{$build}{define}";
110 }
111 }
112
113 return \%defines;
114}
115
116# set the include paths for the libraries we have
117sub build_includes
118{
119 my ($self, $libraries, $build_systems) = @_;
120
121 my %includes;
122
123 while (my ($subsystem, $buildable) = each %$build_systems)
124 {
125 my %sub_include;
126 for my $build (grep { $buildable->{ $_ } } keys %$buildable)
127 {
128 $sub_include{ $buildable->{ $build }[0] }++;
129 }
130
131 $includes{ $subsystem } = [ map { "-I$_" } keys %sub_include ];
132 }
133
134 return \%includes;
135}
136
137# set the linker paths and flags for the libraries we have
138sub build_links
139{
140 my ($self, $libraries, $build_systems) = @_;
141
142 my %links;
143
144 while (my ($subsystem, $buildable) = each %$build_systems)
145 {
146 my %sub_links;
147 for my $build (grep { $buildable->{ $_ } } keys %$buildable)
148 {
149 $sub_links{ $buildable->{ $build }[1] }++;
150 push @{ $links{ $subsystem }{libs} }, "-l$build";
151 }
152
153 $links{ $subsystem }{paths} = [ map { "-L$_" } keys %sub_links ];
154 }
155
156 return \%links;
157}
158
159# save this all in a format process_xs() can understand
160sub set_flags
161{
162 my ($self, $subsystems, $build, $defines, $includes, $links,
163 $sdl_compile, $sdl_link) = @_;
bfd90409 164 my %file_flags;
bfd90409 165 while (my ($subsystem, $buildable) = each %$build)
166 {
167 my $sub_file = $subsystems->{$subsystem}{file}{to};
168 my $sub_includes = join(' ', @{ $includes->{$subsystem} } );
bfd90409 169 $file_flags{ $sub_file } =
170 {
171 extra_compiler_flags =>
172 [
173 @{ $includes->{$subsystem} },
0cdd4aa7 174 (split(' ',$sdl_compile)),
bfd90409 175 @{ $defines->{$subsystem} },
176 ( defined $Config{usethreads} ? ('-DUSE_THREADS', '-fPIC') : ('-fPIC' )),
177 ],
178 extra_linker_flags =>
179 [
180 @{ $links->{$subsystem}{paths} },
0cdd4aa7 181 (split(' ',$sdl_link)),
bfd90409 182 @{ $links->{$subsystem}{libs} },
183 ],
184 },
185 }
186
187 $self->notes( 'file_flags' => \%file_flags );
188}
189
190# look for a header somewhere on the system
191sub find_header
192{
193 my ($self, $header, $includes) = @_;
194
195 for my $inc_dir (keys %$includes)
196 {
197 next unless -e File::Spec->catfile( $inc_dir, $header );
198 return ($inc_dir, $includes->{$inc_dir});
199 }
200}
201
202sub write_sdl_config
203{
204 my ($self, $config) = @_;
205 my $path = File::Spec->catfile(qw( lib SDL Config.pm ));
206 my $dd = Data::Dumper->new( [ $config ], [ 'sdl_config' ] );
207 my $hash = $dd->Dump();
208 (my $text = <<' END_HEADER' . $hash . <<' END_FOOTER');
209 package SDL::Config;
210
211 my $sdl_config;
212 END_HEADER
213
214 sub has
215 {
216 my ($class, $define) = @_;
217 scalar grep { $$sdl_config{$_}{$define} } keys %$sdl_config;
218 }
219
220 1;
221 END_FOOTER
222
223 $text =~ s/^\t//gm;
224
084b921f 225 open my $file, '>', $path or croak "Cannot write to '$path': $!\n";
bfd90409 226 print $file $text;
227}
228
9632eafc 229
230
bfd90409 231# Subclass Darwin to build Objective-C addons
232
233sub filter_support {
234 my $self = shift;
235 print STDERR "[SDL::Build] generic filter\n";
236 return ();
237}
238
239sub process_support_files {
240 my $self = shift;
241 my $p = $self->{properties};
242 return unless $p->{c_source};
243 return unless $p->{c_sources};
244
245 push @{$p->{include_dirs}}, $p->{c_source};
246 unless ( $p->{extra_compiler_flags} && $p->{extra_compiler_flags} =~ /DARCHNAME/) {
247 $p->{extra_compiler_flags} .= " -DARCHNAME=" . $self->{config}{archname};
248 }
249 print STDERR "[SDL::Build] extra compiler flags" . $p->{extra_compiler_flags} . "\n";
250
251 foreach my $file (map($p->{c_source} . "/$_", @{$p->{c_sources}})) {
252 push @{$p->{objects}}, $self->compile_c($file);
253 }
254}
255
9632eafc 256# get link flags with a given a sdl_dir
257sub alt_link_flags
258{
d02b2c8e 259 my $self = shift;
9632eafc 260 my $sdl_dir = shift;
261
262 return '-L"'.$sdl_dir.'\lib"';
263}
264
265# get compile flags with a given a sdl_dir
266sub alt_compile_flags
267{
d02b2c8e 268 my $self = shift;
9632eafc 269 my $sdl_dir = shift;
270
d02b2c8e 271 return '-I"'.$sdl_dir.'\include\SDL"';
9632eafc 272}
273
bfd90409 274# Override to create a MacOS Bundle
3a32e86d 275sub ACTION_bundle
bfd90409 276{
3a32e86d 277 my ($self) = @_;
278 $self->depends_on('build');
279 $self->get_arch($^O)->build_bundle();
bfd90409 280}
281
282# Override Install method for darwin
283sub ACTION_install {
284 my ($self) = @_;
285 require ExtUtils::Install;
286 $self->depends_on('build');
bfd90409 287 ExtUtils::Install::install($self->install_map, 1, 0, $self->{args}{uninst}||0);
288}
289
2901;