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