Commit | Line | Data |
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 | |
31 | package SDL::Build; |
32 | |
33 | use strict; |
084b921f |
34 | use warnings; |
35 | use Carp; |
bfd90409 |
36 | use base 'Module::Build'; |
37 | |
38 | use File::Spec; |
39 | use Data::Dumper; |
40 | use 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: |
44 | sub 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 |
62 | sub 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? |
75 | sub 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 |
99 | sub 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 |
117 | sub 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 |
138 | sub 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 |
160 | sub 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 |
191 | sub 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 | |
202 | sub 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 | |
233 | sub filter_support { |
234 | my $self = shift; |
235 | print STDERR "[SDL::Build] generic filter\n"; |
236 | return (); |
237 | } |
238 | |
239 | sub 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 |
257 | sub 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 |
266 | sub 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 |
275 | sub 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 |
283 | sub 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 | |
290 | 1; |