Permalink
Browse files

dynaloader dark magic

  • Loading branch information...
1 parent 3751b06 commit aa461fa81b4636f1c1482ed13d21532ade62ed22 @kmx kmx committed Mar 4, 2013
Showing with 121 additions and 144 deletions.
  1. +63 −92 Build.PL
  2. +3 −1 MANIFEST
  3. +31 −39 lib/SDL2/Internal/Loader.pm
  4. +6 −3 lib/SDL2/Rect.pm
  5. +6 −3 lib/SDL2/Renderer.pm
  6. +6 −3 lib/SDL2/Window.pm
  7. +6 −3 lib/SDL2pp.pm
View
155 Build.PL
@@ -2,110 +2,81 @@
use strict;
use warnings;
-use Carp;
use Alien::SDL2;
use Module::Build;
-# See perldoc Module::Build for details of how this works
-### Subsystems to build
-# <subsystem>
-# <file> = hash of the following 2 values:
-# <from> = location of source file
-# <to> = location of build file to get name right
-# <libraries> = list reqiured libraries, names the same as keys to hash %libraries
-my %subsystems = (
- SDL2 => {
- file => {
- from => 'src/SDL2pp.xs',
- to => 'lib/SDL2pp.xs',
- },
- libraries => [qw( SDL2 )],
- },
- Window => {
- file => {
- from => 'src/Core/objects/Window.xs',
- to => 'lib/SDL2/Window.xs',
- },
- libraries => [qw( SDL2 )],
- },
- Renderer => {
- file => {
- from => 'src/Core/objects/Renderer.xs',
- to => 'lib/SDL2/Renderer.xs',
- },
- libraries => [qw( SDL2 )],
- },
- Rect => {
- file => {
- from => 'src/Core/objects/Rect.xs',
- to => 'lib/SDL2/Rect.xs',
- },
- libraries => [qw( SDL2 )],
- }
+### All available subsystems to build
+my %mods = (
+ 'SDL2pp' => {
+ xs => [ 'src/SDL2pp.xs' => 'lib/SDL2pp.xs'],
+ libs => [qw( SDL2 )],
+ },
+ 'SDL2::Window' => {
+ xs => [ 'src/Core/objects/Window.xs' => 'lib/SDL2/Window.xs' ],
+ libs => [qw( SDL2 )],
+ },
+ 'SDL2::Renderer' => {
+ xs => [ 'src/Core/objects/Renderer.xs' => 'lib/SDL2/Renderer.xs' ],
+ libs => [qw( SDL2 )],
+ },
+ 'SDL2::Rect' => {
+ xs => [ 'src/Core/objects/Rect.xs' => 'lib/SDL2/Rect.xs' ],
+ libs => [qw( SDL2 )],
+ }
+);
- );
+### Check for available libs
+for my $m (keys %mods) {
+ my @libs = @{$mods{$m}{libs}};
+ if (!Alien::SDL2->havelib(@libs)) {
+ warn "WARNING: disabling '$m' (requires: " . join(',',@libs) . ")\n";
+ delete $mods{$m} ;
+ }
+}
-
-### External libraries
-# <library name> = symbolic library name
-# <define> = value that will be used as -D<value> option when compiling XS code
-# <header> = header related to the library that will be used for avalability detection,
-# could be a sigle value or an array of values
-# <lib> = value that will be used as -l<value> option when linking XS code
-my %libraries = (
- SDL => {
- define => 'HAVE_SDL2',
- header => 'SDL2/SDL.h',
- lib => 'SDL2',
- }
- );
-### Mangle the compilable files into a format Module::Build can understand
-my %xs =
- map { $subsystems{$_}{file}{from} => $subsystems{$_}{file}{to} }
- keys %subsystems;
-
-my $cflags = '-I. -Isrc '. Alien::SDL2->config('cflags');
-my $libs = Alien::SDL2->config('libs');
+### Prepare data we later pass to Module::Build
+my %xs = map { $mods{$_}{xs}[0] => $mods{$_}{xs}[1] } keys %mods;
+my %mod2lib = map { $_ => $mods{$_}{libs} } keys %mods;
+my $cflags = '-I. -Isrc '. Alien::SDL2->config('cflags');
+my $libs = Alien::SDL2->config('libs');
my $build = Module::Build->new(
- module_name => 'SDL2',
- license => 'perl',
- dist_version_from => 'lib/SDL2.pm',
- dist_abstract => 'XS bindings to libSDL2',
- configure_requires => {
+ module_name => 'SDL2',
+ license => 'perl',
+ dist_version_from => 'lib/SDL2.pm',
+ dist_abstract => 'XS bindings to libSDL2',
+ configure_requires => {
'Module::Build' => '0',
'ExtUtils::CBuilder' => '0.260301',
- 'Alien::SDL2' => '0',
+ 'Alien::SDL2' => '0',
'File::Find' => '0',
'File::ShareDir' => '1.0',
'Tie::Simple' => '0',
'Capture::Tiny' => '0',
- },
- build_requires => {
- 'Test::Simple' => '0.88',
- 'Capture::Tiny' => '0',
- 'Test::Most' => '0.21',
- 'Alien::SDL2' => '0',
- 'File::Find' => '0',
- 'File::ShareDir' => '1.0',
- 'Tie::Simple' => '0',
- 'Scalar::Util' => '0',
- },
- requires => {
- 'Scalar::Util' => '0',
- 'Tie::Simple' => '0',
- 'File::ShareDir' => '1.0',
- 'CPAN' => '1.92',
- 'perl' => '5.008000',
- },
- 'xs_files' => \%xs,
- 'extra_compiler_flags' => $cflags,
- 'extra_linker_flags' => $libs
-
- );
-print "Detecting available libraries ...\n";
-
-#my $build_systems = $build->find_subsystems( \%subsystems, \%libraries );
+ },
+ build_requires => {
+ 'Test::Simple' => '0.88',
+ 'Capture::Tiny' => '0',
+ 'Test::Most' => '0.21',
+ 'Alien::SDL2' => '0',
+ 'File::Find' => '0',
+ 'File::ShareDir' => '1.0',
+ 'Tie::Simple' => '0',
+ 'Scalar::Util' => '0',
+ },
+ requires => {
+ 'Scalar::Util' => '0',
+ 'Tie::Simple' => '0',
+ 'File::ShareDir' => '1.0',
+ 'CPAN' => '1.92',
+ 'perl' => '5.008000',
+ },
+ create_readme => 1,
+ xs_files => \%xs,
+ extra_compiler_flags => $cflags,
+ extra_linker_flags => $libs,
+ config_data => { mod2lib => \%mod2lib },
+);
- $build->create_build_script;
+$build->create_build_script;
View
@@ -5,4 +5,6 @@ Todo
Changes
Build.PL
lib/SDL2.pm
-t/001_load.t
+t/001_load.t
+META.yml
+META.json
@@ -4,57 +4,49 @@ use warnings;
use vars qw($VERSION @ISA @EXPORT @LIBREFS);
require Exporter;
our @ISA = qw(Exporter);
-our @EXPORT = qw(internal_load_dlls);
+our @EXPORT = qw(check_and_load);
our @LIBREFS = ();
our $VERSION = '0.01';
$VERSION = eval $VERSION;
-#use SDL2::ConfigData;
-#use Alien::SDL2;
+use SDL2::ConfigData;
+use Alien::SDL2;
-# SDL::Internal::Loader is a king of "Dynaloader kung-fu" that is
-# necessary in situations when you install Allien::SDL from sources
-# or from prebuilt binaries as in these scenarios the SDL stuff is
+# SDL2::Internal::Loader is a king of "Dynaloader kung-fu" that is
+# necessary in situations when you install Allien::SDL2 from sources
+# or from prebuilt binaries as in these scenarios the SDL2 stuff is
# installed into so called 'sharedir' somewhere in perl/lib/ tree
# on Windows box it is e.g.
-# C:\strawberry\perl\site\lib\auto\share\dist\Alien-SDL...
+# C:\strawberry\perl\site\lib\auto\share\dist\Alien-SDL2...
#
-# What happens is that for example XS module "SDL::Video" is linked
-# with -lSDL library which means that resulting "Video.(so|dll)" has
-# a dependency on "libSDL.(so|dll)" - however "libSDL.(so|dll)" is
+# What happens is that for example XS module "SDL2::Video" is linked
+# with -lSDL2 library which means that resulting "Video.(so|dll)" has
+# a dependency on "libSDL2.(so|dll)" - however "libSDL2.(so|dll)" is
# neither in PATH (Win) or in LD_LIBRARY_PATH (Unix) so Dynaloader
# will fail to load "Video.(so|dll)".
-#
-# To handle this we have internal_load_dlls() which has to be called
-# from XS modules (e.g. SDL::Video) linked with SDL libs like this:
-#
-# use SDL2::Internal::Loader;
-# internal_load_dlls(PACKAGE);
-
-sub internal_load_dlls($) {
- my $package = shift;
- ### check if some ld_shlib_map is defined
-
-=pod
- my $shlib_map = Alien::SDL2->config('ld_shlib_map');
- return unless $shlib_map; # empty shlib_map, nothing to do
-
- ### get list of lib nicknames based on packagename
- my $lib_nick = SDL2::ConfigData->config('SDL_lib_translate')->{$package};
- return unless $lib_nick; # no need to load anything
-
- ### let us load the corresponding shlibs (*.dll|*.so)
- require DynaLoader;
- foreach my $n (@$lib_nick) {
- my $file = $shlib_map->{$n};
- next unless $file && -e $file;
- my $libref = DynaLoader::dl_load_file( $file, 0 );
- push( @DynaLoader::dl_librefs, $libref ) if $libref;
- push( @LIBREFS, $libref ) if $libref;
- }
-=cut
+sub check_and_load($) {
+ my $package = shift;
+
+ ### get list of lib nicknames based on packagename
+ my $lib_nick = SDL2::ConfigData->config('mod2lib')->{$package};
+ return 0 unless $lib_nick; # $package is disabled (XS is not compiled)
+
+ ### get lib to DLL fullname mapping
+ my $shlib_map = Alien::SDL2->config('ld_shlib_map');
+ return 1 unless $shlib_map; # empty shlib_map, nothing to do
+
+ ### let us load the corresponding shlibs (*.dll|*.so)
+ require DynaLoader;
+ foreach my $n (@$lib_nick) {
+ my $file = $shlib_map->{$n};
+ next unless $file && -e $file;
+ my $libref = DynaLoader::dl_load_file($file, 0);
+ push( @DynaLoader::dl_librefs, $libref ) if $libref;
+ push( @LIBREFS, $libref ) if $libref;
+ }
+ return 1;
}
1;
View
@@ -7,9 +7,12 @@ require DynaLoader;
our @ISA = qw(Exporter DynaLoader);
use SDL2::Internal::Loader;
-internal_load_dlls(__PACKAGE__);
-
-bootstrap SDL2::Rect;
+if (check_and_load(__PACKAGE__)) {
+ bootstrap SDL2::Rect;
+}
+else {
+ warn "WARNING: " . __PACKAGE__ . " is not available\n";
+}
use base 'Exporter';
View
@@ -7,9 +7,12 @@ require DynaLoader;
our @ISA = qw(Exporter DynaLoader);
use SDL2::Internal::Loader;
-internal_load_dlls(__PACKAGE__);
-
-bootstrap SDL2::Renderer;
+if (check_and_load(__PACKAGE__)) {
+ bootstrap SDL2::Renderer;
+}
+else {
+ warn "WARNING: " . __PACKAGE__ . " is not available\n";
+}
use base 'Exporter';
View
@@ -7,9 +7,12 @@ require DynaLoader;
our @ISA = qw(Exporter DynaLoader);
use SDL2::Internal::Loader;
-internal_load_dlls(__PACKAGE__);
-
-bootstrap SDL2::Window;
+if (check_and_load(__PACKAGE__)) {
+ bootstrap SDL2::Window;
+}
+else {
+ warn "WARNING: " . __PACKAGE__ . " is not available\n";
+}
use base 'Exporter';
View
@@ -7,9 +7,12 @@ require DynaLoader;
our @ISA = qw(Exporter DynaLoader);
use SDL2::Internal::Loader;
-internal_load_dlls(__PACKAGE__);
-
-bootstrap SDL2pp;
+if (check_and_load(__PACKAGE__)) {
+ bootstrap SDL2pp;
+}
+else {
+ warn "WARNING: " . __PACKAGE__ . " is not available\n";
+}
use base 'Exporter';

0 comments on commit aa461fa

Please sign in to comment.