| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Alien::Base; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 2 |  |  | 2 |  | 16 | use strict; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 62 |  | 
| 4 | 2 |  |  | 2 |  | 16 | use warnings; | 
|  | 2 |  |  |  |  | 5 |  | 
|  | 2 |  |  |  |  | 110 |  | 
| 5 |  |  |  |  |  |  |  | 
| 6 |  |  |  |  |  |  | our $VERSION = '0.043_01'; | 
| 7 |  |  |  |  |  |  | $VERSION = eval $VERSION; | 
| 8 |  |  |  |  |  |  |  | 
| 9 | 2 |  |  | 2 |  | 17 | use Carp; | 
|  | 2 |  |  |  |  | 4 |  | 
|  | 2 |  |  |  |  | 205 |  | 
| 10 | 2 |  |  | 2 |  | 1002 | use File::ShareDir (); | 
|  | 2 |  |  |  |  | 11735 |  | 
|  | 2 |  |  |  |  | 59 |  | 
| 11 | 2 |  |  | 2 |  | 20 | use File::Spec; | 
|  | 2 |  |  |  |  | 10 |  | 
|  | 2 |  |  |  |  | 63 |  | 
| 12 | 2 |  |  | 2 |  | 13 | use Scalar::Util qw/blessed/; | 
|  | 2 |  |  |  |  | 6 |  | 
|  | 2 |  |  |  |  | 159 |  | 
| 13 | 2 |  |  | 2 |  | 16 | use Capture::Tiny 0.17 qw/capture_merged/; | 
|  | 2 |  |  |  |  | 129 |  | 
|  | 2 |  |  |  |  | 137 |  | 
| 14 | 2 |  |  | 2 |  | 482 | use Text::ParseWords qw/shellwords/; | 
|  | 2 |  |  |  |  | 1039 |  | 
|  | 2 |  |  |  |  | 255 |  | 
| 15 |  |  |  |  |  |  |  | 
| 16 |  |  |  |  |  |  | =encoding UTF-8 | 
| 17 |  |  |  |  |  |  |  | 
| 18 |  |  |  |  |  |  | =head1 NAME | 
| 19 |  |  |  |  |  |  |  | 
| 20 |  |  |  |  |  |  | Alien::Base - Base classes for Alien:: modules | 
| 21 |  |  |  |  |  |  |  | 
| 22 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 23 |  |  |  |  |  |  |  | 
| 24 |  |  |  |  |  |  | package Alien::MyLibrary; | 
| 25 |  |  |  |  |  |  |  | 
| 26 |  |  |  |  |  |  | use strict; | 
| 27 |  |  |  |  |  |  | use warnings; | 
| 28 |  |  |  |  |  |  |  | 
| 29 |  |  |  |  |  |  | use parent 'Alien::Base'; | 
| 30 |  |  |  |  |  |  |  | 
| 31 |  |  |  |  |  |  | 1; | 
| 32 |  |  |  |  |  |  |  | 
| 33 |  |  |  |  |  |  | (for details on the C or C and L | 
| 34 |  |  |  |  |  |  | that should be bundled with your L subclass, please see | 
| 35 |  |  |  |  |  |  | L). | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | Then a C can use C in its C: | 
| 38 |  |  |  |  |  |  |  | 
| 39 |  |  |  |  |  |  | use Alien::MyLibrary; | 
| 40 |  |  |  |  |  |  | use Module::Build 0.28; # need at least 0.28 | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | my $builder = Module::Build->new( | 
| 43 |  |  |  |  |  |  | ... | 
| 44 |  |  |  |  |  |  | extra_compiler_flags => Alien::MyLibrary->cflags, | 
| 45 |  |  |  |  |  |  | extra_linker_flags   => Alien::MyLibrary->libs, | 
| 46 |  |  |  |  |  |  | ... | 
| 47 |  |  |  |  |  |  | ); | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | $builder->create_build_script; | 
| 50 |  |  |  |  |  |  |  | 
| 51 |  |  |  |  |  |  | Or if you prefer L, in its C: | 
| 52 |  |  |  |  |  |  |  | 
| 53 |  |  |  |  |  |  | use Alien::MyLibrary | 
| 54 |  |  |  |  |  |  | use ExtUtils::MakeMaker; | 
| 55 |  |  |  |  |  |  | use Config; | 
| 56 |  |  |  |  |  |  |  | 
| 57 |  |  |  |  |  |  | WriteMakefile( | 
| 58 |  |  |  |  |  |  | ... | 
| 59 |  |  |  |  |  |  | CCFLAGS => Alien::MyLibrary->cflags . " $Config{ccflags}", | 
| 60 |  |  |  |  |  |  | LIBS   => ALien::MyLibrary->libs, | 
| 61 |  |  |  |  |  |  | ... | 
| 62 |  |  |  |  |  |  | ); | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | Or if you are using L: | 
| 65 |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  | use ExtUtils::MakeMaker; | 
| 67 |  |  |  |  |  |  | use ExtUtils::Depends; | 
| 68 |  |  |  |  |  |  | my $eud = ExtUtils::Depends->new(qw( MyLibrary::XS Alien::MyLibrary )); | 
| 69 |  |  |  |  |  |  | WriteMakefile( | 
| 70 |  |  |  |  |  |  | ... | 
| 71 |  |  |  |  |  |  | $eud->get_makefile_vars | 
| 72 |  |  |  |  |  |  | ); | 
| 73 |  |  |  |  |  |  |  | 
| 74 |  |  |  |  |  |  | In your C module, you may need to use L if | 
| 75 |  |  |  |  |  |  | dynamic libraries are used: | 
| 76 |  |  |  |  |  |  |  | 
| 77 |  |  |  |  |  |  | package MyLibrary::XS; | 
| 78 |  |  |  |  |  |  |  | 
| 79 |  |  |  |  |  |  | use Alien::MyLibrary; | 
| 80 |  |  |  |  |  |  |  | 
| 81 |  |  |  |  |  |  | ... | 
| 82 |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  | Or you can use it from an FFI module: | 
| 84 |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  | package MyLibrary::FFI; | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | use Alien::MyLibrary; | 
| 88 |  |  |  |  |  |  | use FFI::Platypus; | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  | my $ffi = FFI::Platypus->new; | 
| 91 |  |  |  |  |  |  | $ffi->lib(Alien::MyLibrary->dynamic_libs); | 
| 92 |  |  |  |  |  |  |  | 
| 93 |  |  |  |  |  |  | $ffi->attach( 'my_library_function' => [] => 'void' ); | 
| 94 |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  | You can even use it with L (C and C++ languages are supported): | 
| 96 |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  | package MyLibrary::Inline; | 
| 98 |  |  |  |  |  |  |  | 
| 99 |  |  |  |  |  |  | use Alien::MyLibrary; | 
| 100 |  |  |  |  |  |  | # Inline 0.56 or better is required | 
| 101 |  |  |  |  |  |  | use Inline 0.56 with => 'Alien::MyLibrary'; | 
| 102 |  |  |  |  |  |  | ... | 
| 103 |  |  |  |  |  |  |  | 
| 104 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 105 |  |  |  |  |  |  |  | 
| 106 |  |  |  |  |  |  | B: L is no longer bundled with L and has been spun off into a separate distribution. | 
| 107 |  |  |  |  |  |  | L will be a prerequisite for L until October 1, 2017.  If you are using L | 
| 108 |  |  |  |  |  |  | you need to make sure it is declared as a C in your C.  You may want to also consider using L and | 
| 109 |  |  |  |  |  |  | L as a more modern alternative. | 
| 110 |  |  |  |  |  |  |  | 
| 111 |  |  |  |  |  |  | L comprises base classes to help in the construction of C modules. Modules in the L namespace are used to locate and install (if necessary) external libraries needed by other Perl modules. | 
| 112 |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  | This is the documentation for the L module itself. To learn more about the system as a whole please see L. | 
| 114 |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  | =cut | 
| 116 |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  | sub import { | 
| 118 | 0 |  |  | 0 |  | 0 | my $class = shift; | 
| 119 |  |  |  |  |  |  |  | 
| 120 | 0 | 0 |  |  |  | 0 | return if $class->runtime_prop; | 
| 121 |  |  |  |  |  |  |  | 
| 122 | 0 | 0 |  |  |  | 0 | return if $class->install_type('system'); | 
| 123 |  |  |  |  |  |  |  | 
| 124 | 0 |  |  |  |  | 0 | require DynaLoader; | 
| 125 |  |  |  |  |  |  |  | 
| 126 |  |  |  |  |  |  | # Sanity check in order to ensure that dist_dir can be found. | 
| 127 |  |  |  |  |  |  | # This will throw an exception otherwise. | 
| 128 | 0 |  |  |  |  | 0 | $class->dist_dir; | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | # get a reference to %Alien::MyLibrary::AlienLoaded | 
| 131 |  |  |  |  |  |  | # which contains names of already loaded libraries | 
| 132 |  |  |  |  |  |  | # this logic may be replaced by investigating the DynaLoader arrays | 
| 133 | 0 |  |  |  |  | 0 | my $loaded = do { | 
| 134 | 2 |  |  | 2 |  | 17 | no strict 'refs'; | 
|  | 2 |  |  |  |  | 6 |  | 
|  | 2 |  |  |  |  | 64 |  | 
| 135 | 2 |  |  | 2 |  | 19 | no warnings 'once'; | 
|  | 2 |  |  |  |  | 7 |  | 
|  | 2 |  |  |  |  | 5324 |  | 
| 136 | 0 |  |  |  |  | 0 | \%{ $class . "::AlienLoaded" }; | 
|  | 0 |  |  |  |  | 0 |  | 
| 137 |  |  |  |  |  |  | }; | 
| 138 |  |  |  |  |  |  |  | 
| 139 | 0 |  |  |  |  | 0 | my @libs = $class->split_flags( $class->libs ); | 
| 140 |  |  |  |  |  |  |  | 
| 141 | 0 |  |  |  |  | 0 | my @L = grep { s/^-L// } @libs; | 
|  | 0 |  |  |  |  | 0 |  | 
| 142 | 0 |  |  |  |  | 0 | my @l = grep { /^-l/ } @libs; | 
|  | 0 |  |  |  |  | 0 |  | 
| 143 |  |  |  |  |  |  |  | 
| 144 | 0 |  |  |  |  | 0 | unshift @DynaLoader::dl_library_path, @L; | 
| 145 |  |  |  |  |  |  |  | 
| 146 | 0 |  |  |  |  | 0 | my @libpaths; | 
| 147 | 0 |  |  |  |  | 0 | foreach my $l (@l) { | 
| 148 | 0 | 0 |  |  |  | 0 | next if $loaded->{$l}; | 
| 149 |  |  |  |  |  |  |  | 
| 150 | 0 |  |  |  |  | 0 | my $path = DynaLoader::dl_findfile( $l ); | 
| 151 | 0 | 0 |  |  |  | 0 | unless ($path) { | 
| 152 | 0 |  |  |  |  | 0 | carp "Could not resolve $l"; | 
| 153 | 0 |  |  |  |  | 0 | next; | 
| 154 |  |  |  |  |  |  | } | 
| 155 |  |  |  |  |  |  |  | 
| 156 | 0 |  |  |  |  | 0 | push @libpaths, $path; | 
| 157 | 0 |  |  |  |  | 0 | $loaded->{$l} = $path; | 
| 158 |  |  |  |  |  |  | } | 
| 159 |  |  |  |  |  |  |  | 
| 160 | 0 |  |  |  |  | 0 | push @DynaLoader::dl_resolve_using, @libpaths; | 
| 161 |  |  |  |  |  |  |  | 
| 162 | 0 |  |  |  |  | 0 | my @librefs = map { DynaLoader::dl_load_file( $_, 0x01 ) } grep !/\.(a|lib)$/, @libpaths; | 
|  | 0 |  |  |  |  | 0 |  | 
| 163 | 0 |  |  |  |  | 0 | push @DynaLoader::dl_librefs, @librefs; | 
| 164 |  |  |  |  |  |  |  | 
| 165 |  |  |  |  |  |  | } | 
| 166 |  |  |  |  |  |  |  | 
| 167 |  |  |  |  |  |  | =head1 METHODS | 
| 168 |  |  |  |  |  |  |  | 
| 169 |  |  |  |  |  |  | In the example snippets here, C represents any | 
| 170 |  |  |  |  |  |  | subclass of L. | 
| 171 |  |  |  |  |  |  |  | 
| 172 |  |  |  |  |  |  | =head2 dist_dir | 
| 173 |  |  |  |  |  |  |  | 
| 174 |  |  |  |  |  |  | my $dir = Alien::MyLibrary->dist_dir; | 
| 175 |  |  |  |  |  |  |  | 
| 176 |  |  |  |  |  |  | Returns the directory that contains the install root for | 
| 177 |  |  |  |  |  |  | the packaged software, if it was built from install (i.e., if | 
| 178 |  |  |  |  |  |  | C is C). | 
| 179 |  |  |  |  |  |  |  | 
| 180 |  |  |  |  |  |  | =cut | 
| 181 |  |  |  |  |  |  |  | 
| 182 |  |  |  |  |  |  | sub dist_dir { | 
| 183 | 14 |  |  | 14 | 1 | 60 | my $class = shift; | 
| 184 |  |  |  |  |  |  |  | 
| 185 | 14 |  | 33 |  |  | 94 | my $dist = blessed $class || $class; | 
| 186 | 14 |  |  |  |  | 79 | $dist =~ s/::/-/g; | 
| 187 |  |  |  |  |  |  |  | 
| 188 | 14 | 50 |  |  |  | 218 | my $dist_dir = | 
| 189 |  |  |  |  |  |  | $class->config('finished_installing') | 
| 190 |  |  |  |  |  |  | ? File::ShareDir::dist_dir($dist) | 
| 191 |  |  |  |  |  |  | : $class->config('working_directory'); | 
| 192 |  |  |  |  |  |  |  | 
| 193 | 14 | 50 | 33 |  |  | 1292 | croak "Failed to find share dir for dist '$dist'" | 
| 194 |  |  |  |  |  |  | unless defined $dist_dir && -d $dist_dir; | 
| 195 |  |  |  |  |  |  |  | 
| 196 | 14 |  |  |  |  | 360 | return $dist_dir; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  |  | 
| 199 | 1 |  |  | 1 | 0 | 18 | sub new { return bless {}, $_[0] } | 
| 200 |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  | sub _flags | 
| 202 |  |  |  |  |  |  | { | 
| 203 | 12 |  |  | 12 |  | 26 | my($class, $key) = @_; | 
| 204 |  |  |  |  |  |  |  | 
| 205 | 12 |  |  |  |  | 26 | my $config = $class->runtime_prop; | 
| 206 | 12 |  |  |  |  | 24 | my $flags = $config->{$key}; | 
| 207 |  |  |  |  |  |  |  | 
| 208 | 12 |  |  |  |  | 20 | my $prefix = $config->{prefix}; | 
| 209 | 12 | 50 |  |  |  | 62 | $prefix =~ s{\\}{/}g if $^O =~ /^(MSWin32|msys)$/; | 
| 210 | 12 |  |  |  |  | 20 | my $distdir = $config->{distdir}; | 
| 211 | 12 | 50 |  |  |  | 35 | $distdir =~ s{\\}{/}g if $^O =~ /^(MSWin32|msys)$/; | 
| 212 |  |  |  |  |  |  |  | 
| 213 | 12 | 50 |  |  |  | 38 | if($prefix ne $distdir) | 
| 214 |  |  |  |  |  |  | { | 
| 215 |  |  |  |  |  |  | $flags = join ' ', map { | 
| 216 | 12 |  |  |  |  | 34 | s/^(-I|-L|-LIBPATH:)?\Q$prefix\E/$1$distdir/; | 
|  | 29 |  |  |  |  | 1448 |  | 
| 217 | 29 |  |  |  |  | 61 | s/(\s)/\\$1/g; | 
| 218 | 29 |  |  |  |  | 71 | $_; | 
| 219 |  |  |  |  |  |  | } $class->split_flags($flags); | 
| 220 |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  |  | 
| 222 | 12 |  |  |  |  | 119 | $flags; | 
| 223 |  |  |  |  |  |  | } | 
| 224 |  |  |  |  |  |  |  | 
| 225 |  |  |  |  |  |  | =head2 cflags | 
| 226 |  |  |  |  |  |  |  | 
| 227 |  |  |  |  |  |  | my $cflags = Alien::MyLibrary->cflags; | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | use Text::ParseWords qw( shellwords ); | 
| 230 |  |  |  |  |  |  | my @cflags = shellwords( Alien::MyLibrary->cflags ); | 
| 231 |  |  |  |  |  |  |  | 
| 232 |  |  |  |  |  |  | Returns the C compiler flags necessary to compile an XS | 
| 233 |  |  |  |  |  |  | module using the alien software.  If you need this in list | 
| 234 |  |  |  |  |  |  | form (for example if you are calling system with a list | 
| 235 |  |  |  |  |  |  | argument) you can pass this value into C from | 
| 236 |  |  |  |  |  |  | the Perl core L module. | 
| 237 |  |  |  |  |  |  |  | 
| 238 |  |  |  |  |  |  | =cut | 
| 239 |  |  |  |  |  |  |  | 
| 240 |  |  |  |  |  |  | sub cflags { | 
| 241 | 7 |  |  | 7 | 1 | 4271 | my $class = shift; | 
| 242 | 7 | 100 |  |  |  | 35 | return $class->runtime_prop ? $class->_flags('cflags') : $class->_pkgconfig_keyword('Cflags'); | 
| 243 |  |  |  |  |  |  | } | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | sub cflags_static { | 
| 246 | 3 |  |  | 3 | 0 | 1372 | my $class = shift; | 
| 247 | 3 | 50 |  |  |  | 10 | return $class->runtime_prop ? $class->_flags('cflags_static') : $class->_pkgconfig_keyword('Cflags', 'static'); | 
| 248 |  |  |  |  |  |  | } | 
| 249 |  |  |  |  |  |  |  | 
| 250 |  |  |  |  |  |  | =head2 libs | 
| 251 |  |  |  |  |  |  |  | 
| 252 |  |  |  |  |  |  | my $libs = Alien::MyLibrary->libs; | 
| 253 |  |  |  |  |  |  |  | 
| 254 |  |  |  |  |  |  | use Text::ParseWords qw( shellwords ); | 
| 255 |  |  |  |  |  |  | my @cflags = shellwords( Alien::MyLibrary->libs ); | 
| 256 |  |  |  |  |  |  |  | 
| 257 |  |  |  |  |  |  | Returns the library linker flags necessary to link an XS | 
| 258 |  |  |  |  |  |  | module against the alien software.  If you need this in list | 
| 259 |  |  |  |  |  |  | form (for example if you are calling system with a list | 
| 260 |  |  |  |  |  |  | argument) you can pass this value into C from | 
| 261 |  |  |  |  |  |  | the Perl core L module. | 
| 262 |  |  |  |  |  |  |  | 
| 263 |  |  |  |  |  |  | =cut | 
| 264 |  |  |  |  |  |  |  | 
| 265 |  |  |  |  |  |  | sub libs { | 
| 266 | 7 |  |  | 7 | 1 | 1916 | my $class = shift; | 
| 267 | 7 | 100 |  |  |  | 35 | return $class->runtime_prop ? $class->_flags('libs') : $class->_pkgconfig_keyword('Libs'); | 
| 268 |  |  |  |  |  |  | } | 
| 269 |  |  |  |  |  |  |  | 
| 270 |  |  |  |  |  |  | sub libs_static { | 
| 271 | 3 |  |  | 3 | 0 | 1630 | my $class = shift; | 
| 272 | 3 | 50 |  |  |  | 8 | return $class->runtime_prop ? $class->_flags('libs_static') : $class->_pkgconfig_keyword('Libs', 'static'); | 
| 273 |  |  |  |  |  |  | } | 
| 274 |  |  |  |  |  |  |  | 
| 275 |  |  |  |  |  |  | =head2 version | 
| 276 |  |  |  |  |  |  |  | 
| 277 |  |  |  |  |  |  | my $version = Alien::MyLibrary->version; | 
| 278 |  |  |  |  |  |  |  | 
| 279 |  |  |  |  |  |  | Returns the version of the Alienized library or tool that was | 
| 280 |  |  |  |  |  |  | determined at install time. | 
| 281 |  |  |  |  |  |  |  | 
| 282 |  |  |  |  |  |  | =cut | 
| 283 |  |  |  |  |  |  |  | 
| 284 |  |  |  |  |  |  | sub version { | 
| 285 | 4 |  |  | 4 | 1 | 828 | my $self = shift; | 
| 286 | 4 |  |  |  |  | 21 | my $version = $self->config('version'); | 
| 287 | 4 |  |  |  |  | 22 | chomp $version; | 
| 288 | 4 |  |  |  |  | 20 | return $version; | 
| 289 |  |  |  |  |  |  | } | 
| 290 |  |  |  |  |  |  |  | 
| 291 |  |  |  |  |  |  | =head2 install_type | 
| 292 |  |  |  |  |  |  |  | 
| 293 |  |  |  |  |  |  | my $install_type = Alien::MyLibrary->install_type; | 
| 294 |  |  |  |  |  |  |  | 
| 295 |  |  |  |  |  |  | Returns the install type that was used when C was | 
| 296 |  |  |  |  |  |  | installed.  Types include: | 
| 297 |  |  |  |  |  |  |  | 
| 298 |  |  |  |  |  |  | =over 4 | 
| 299 |  |  |  |  |  |  |  | 
| 300 |  |  |  |  |  |  | =item system | 
| 301 |  |  |  |  |  |  |  | 
| 302 |  |  |  |  |  |  | The library was provided by the operating system | 
| 303 |  |  |  |  |  |  |  | 
| 304 |  |  |  |  |  |  | =item share | 
| 305 |  |  |  |  |  |  |  | 
| 306 |  |  |  |  |  |  | The library was not available when C was installed, so | 
| 307 |  |  |  |  |  |  | it was built from source code, either downloaded from the Internet | 
| 308 |  |  |  |  |  |  | or bundled with C. | 
| 309 |  |  |  |  |  |  |  | 
| 310 |  |  |  |  |  |  | =back | 
| 311 |  |  |  |  |  |  |  | 
| 312 |  |  |  |  |  |  | =cut | 
| 313 |  |  |  |  |  |  |  | 
| 314 |  |  |  |  |  |  | sub install_type { | 
| 315 | 19 |  |  | 19 | 1 | 1199 | my $self = shift; | 
| 316 | 19 |  |  |  |  | 80 | my $type = $self->config('install_type'); | 
| 317 | 19 | 100 |  |  |  | 123 | return @_ ? $type eq $_[0] : $type; | 
| 318 |  |  |  |  |  |  | } | 
| 319 |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  | sub _pkgconfig_keyword { | 
| 321 | 8 |  |  | 8 |  | 46 | my $self = shift; | 
| 322 | 8 |  |  |  |  | 31 | my $keyword = shift; | 
| 323 | 8 |  |  |  |  | 23 | my $static = shift; | 
| 324 |  |  |  |  |  |  |  | 
| 325 |  |  |  |  |  |  | # use pkg-config if installed system-wide | 
| 326 | 8 | 100 |  |  |  | 67 | if ($self->install_type('system')) { | 
| 327 | 6 |  |  |  |  | 25 | my $name = $self->config('name'); | 
| 328 | 6 |  |  |  |  | 75 | require Alien::Base::PkgConfig; | 
| 329 | 6 | 50 |  |  |  | 91 | my $command = Alien::Base::PkgConfig->pkg_config_command . " @{[ $static ? '--static' : '' ]} --\L$keyword\E $name"; | 
|  | 6 |  |  |  |  | 154003 |  | 
| 330 |  |  |  |  |  |  |  | 
| 331 | 6 |  |  |  |  | 27 | $! = 0; | 
| 332 | 6 |  |  | 6 |  | 231 | chomp ( my $pcdata = capture_merged { system( $command ) } ); | 
|  | 6 |  |  |  |  | 1233987 |  | 
| 333 |  |  |  |  |  |  |  | 
| 334 |  |  |  |  |  |  | # if pkg-config fails for whatever reason, then we try to | 
| 335 |  |  |  |  |  |  | # fallback on alien_provides_* | 
| 336 | 6 | 50 | 33 |  |  | 18059 | $pcdata = '' if $! || $?; | 
| 337 |  |  |  |  |  |  |  | 
| 338 | 6 |  |  |  |  | 121 | $pcdata =~ s/\s*$//; | 
| 339 |  |  |  |  |  |  |  | 
| 340 | 6 | 50 |  |  |  | 91 | if($self->config('system_provides')) { | 
| 341 | 6 | 50 |  |  |  | 39 | if(my $system_provides = $self->config('system_provides')->{$keyword}) { | 
| 342 | 0 | 0 |  |  |  | 0 | $pcdata = length $pcdata ? "$pcdata $system_provides" : $system_provides; | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  | } | 
| 345 |  |  |  |  |  |  |  | 
| 346 | 6 |  |  |  |  | 144 | return $pcdata; | 
| 347 |  |  |  |  |  |  | } | 
| 348 |  |  |  |  |  |  |  | 
| 349 |  |  |  |  |  |  | # use parsed info from build .pc file | 
| 350 | 2 |  |  |  |  | 23 | my $dist_dir = $self->dist_dir; | 
| 351 | 2 |  |  |  |  | 18 | my @pc = $self->_pkgconfig(@_); | 
| 352 |  |  |  |  |  |  | my @strings = | 
| 353 |  |  |  |  |  |  | grep defined, | 
| 354 | 2 |  |  |  |  | 8 | map { $_->keyword($keyword, | 
|  | 2 |  |  |  |  | 22 |  | 
| 355 |  |  |  |  |  |  | #{ pcfiledir => $dist_dir } | 
| 356 |  |  |  |  |  |  | ) } | 
| 357 |  |  |  |  |  |  | @pc; | 
| 358 |  |  |  |  |  |  |  | 
| 359 | 2 | 50 | 33 |  |  | 208 | if(defined $self->config('original_prefix') && $self->config('original_prefix') ne $self->dist_dir) | 
| 360 |  |  |  |  |  |  | { | 
| 361 | 2 |  |  |  |  | 10 | my $dist_dir = $self->dist_dir; | 
| 362 | 2 | 50 |  |  |  | 14 | $dist_dir =~ s{\\}{/}g if $^O eq 'MSWin32'; | 
| 363 | 2 |  |  |  |  | 11 | my $old = quotemeta $self->config('original_prefix'); | 
| 364 |  |  |  |  |  |  | @strings = map { | 
| 365 | 3 |  |  |  |  | 3404 | s{^(-I|-L|-LIBPATH:)?($old)}{$1.$dist_dir}e; | 
|  | 2 |  |  |  |  | 18 |  | 
| 366 | 3 |  |  |  |  | 14 | s/(\s)/\\$1/g; | 
| 367 | 3 |  |  |  |  | 17 | $_; | 
| 368 | 2 |  |  |  |  | 9 | } map { $self->split_flags($_) } @strings; | 
|  | 2 |  |  |  |  | 30 |  | 
| 369 |  |  |  |  |  |  | } | 
| 370 |  |  |  |  |  |  |  | 
| 371 | 2 |  |  |  |  | 24 | return join( ' ', @strings ); | 
| 372 |  |  |  |  |  |  | } | 
| 373 |  |  |  |  |  |  |  | 
| 374 |  |  |  |  |  |  | sub _pkgconfig { | 
| 375 | 2 |  |  | 2 |  | 7 | my $self = shift; | 
| 376 | 2 |  |  |  |  | 6 | my %all = %{ $self->config('pkgconfig') }; | 
|  | 2 |  |  |  |  | 8 |  | 
| 377 |  |  |  |  |  |  |  | 
| 378 |  |  |  |  |  |  | # merge in found pc files | 
| 379 | 2 |  |  |  |  | 18 | require File::Find; | 
| 380 |  |  |  |  |  |  | my $wanted = sub { | 
| 381 | 14 | 50 | 66 | 14 |  | 976 | return if ( -d or not /\.pc$/ ); | 
| 382 | 0 |  |  |  |  | 0 | require Alien::Base::PkgConfig; | 
| 383 | 0 |  |  |  |  | 0 | my $pkg = Alien::Base::PkgConfig->new($_); | 
| 384 | 0 |  |  |  |  | 0 | $all{$pkg->{package}} = $pkg; | 
| 385 | 2 |  |  |  |  | 20 | }; | 
| 386 | 2 |  |  |  |  | 10 | File::Find::find( $wanted, $self->dist_dir ); | 
| 387 |  |  |  |  |  |  |  | 
| 388 | 2 | 50 |  |  |  | 18 | croak "No Alien::Base::PkgConfig objects are stored!" | 
| 389 |  |  |  |  |  |  | unless keys %all; | 
| 390 |  |  |  |  |  |  |  | 
| 391 |  |  |  |  |  |  | # Run through all pkgconfig objects and ensure that their modules are loaded: | 
| 392 | 2 |  |  |  |  | 9 | for my $pkg_obj (values %all) { | 
| 393 | 4 |  |  |  |  | 31 | my $perl_module_name = blessed $pkg_obj; | 
| 394 | 4 |  |  |  |  | 247 | eval "require $perl_module_name"; | 
| 395 |  |  |  |  |  |  | } | 
| 396 |  |  |  |  |  |  |  | 
| 397 | 2 | 50 |  |  |  | 21 | return @all{@_} if @_; | 
| 398 |  |  |  |  |  |  |  | 
| 399 | 2 |  |  |  |  | 9 | my $manual = delete $all{_manual}; | 
| 400 |  |  |  |  |  |  |  | 
| 401 | 2 | 50 |  |  |  | 10 | if (keys %all) { | 
| 402 | 2 |  |  |  |  | 22 | return values %all; | 
| 403 |  |  |  |  |  |  | } else { | 
| 404 | 0 |  |  |  |  | 0 | return $manual; | 
| 405 |  |  |  |  |  |  | } | 
| 406 |  |  |  |  |  |  | } | 
| 407 |  |  |  |  |  |  |  | 
| 408 |  |  |  |  |  |  | =head2 config | 
| 409 |  |  |  |  |  |  |  | 
| 410 |  |  |  |  |  |  | my $value = Alien::MyLibrary->config($key); | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | Returns the configuration data as determined during the install | 
| 413 |  |  |  |  |  |  | of L.  For the appropriate config keys, see | 
| 414 |  |  |  |  |  |  | L. | 
| 415 |  |  |  |  |  |  |  | 
| 416 |  |  |  |  |  |  | This is not typically used by L and L, | 
| 417 |  |  |  |  |  |  | but a compatible interface will be provided. | 
| 418 |  |  |  |  |  |  |  | 
| 419 |  |  |  |  |  |  | =cut | 
| 420 |  |  |  |  |  |  |  | 
| 421 |  |  |  |  |  |  | # helper method to call Alien::MyLib::ConfigData->config(@_) | 
| 422 |  |  |  |  |  |  | sub config { | 
| 423 | 69 |  |  | 69 | 1 | 179 | my $class = shift; | 
| 424 | 69 |  | 66 |  |  | 418 | $class = blessed $class || $class; | 
| 425 |  |  |  |  |  |  |  | 
| 426 | 69 | 100 |  |  |  | 258 | if(my $ab_config = $class->runtime_prop) | 
| 427 |  |  |  |  |  |  | { | 
| 428 | 25 |  |  |  |  | 45 | my $key = shift; | 
| 429 | 25 |  |  |  |  | 111 | return $ab_config->{legacy}->{$key}; | 
| 430 |  |  |  |  |  |  | } | 
| 431 |  |  |  |  |  |  |  | 
| 432 | 44 |  |  |  |  | 165 | my $config = $class . '::ConfigData'; | 
| 433 | 44 |  |  |  |  | 3196 | eval "require $config"; | 
| 434 | 44 | 50 |  |  |  | 258 | warn $@ if $@; | 
| 435 |  |  |  |  |  |  |  | 
| 436 | 44 |  |  |  |  | 375 | return $config->config(@_); | 
| 437 |  |  |  |  |  |  | } | 
| 438 |  |  |  |  |  |  |  | 
| 439 |  |  |  |  |  |  | # helper method to split flags based on the OS | 
| 440 |  |  |  |  |  |  | sub split_flags { | 
| 441 | 14 |  |  | 14 | 0 | 35 | my ($class, $line) = @_; | 
| 442 | 14 | 50 |  |  |  | 41 | if( $^O eq 'MSWin32' ) { | 
| 443 | 0 |  |  |  |  | 0 | $class->split_flags_windows($line); | 
| 444 |  |  |  |  |  |  | } else { | 
| 445 |  |  |  |  |  |  | # $os eq 'Unix' | 
| 446 | 14 |  |  |  |  | 44 | $class->split_flags_unix($line); | 
| 447 |  |  |  |  |  |  | } | 
| 448 |  |  |  |  |  |  | } | 
| 449 |  |  |  |  |  |  |  | 
| 450 |  |  |  |  |  |  | sub split_flags_unix { | 
| 451 | 15 |  |  | 15 | 0 | 6384 | my ($class, $line) = @_; | 
| 452 | 15 |  |  |  |  | 52 | shellwords($line); | 
| 453 |  |  |  |  |  |  | } | 
| 454 |  |  |  |  |  |  |  | 
| 455 |  |  |  |  |  |  | sub split_flags_windows { | 
| 456 |  |  |  |  |  |  | # NOTE a better approach would be to write a function that understands cmd.exe metacharacters. | 
| 457 | 3 |  |  | 3 | 0 | 4618 | my ($class, $line) = @_; | 
| 458 |  |  |  |  |  |  |  | 
| 459 |  |  |  |  |  |  | # Double the backslashes so that when they are unescaped by shellwords(), | 
| 460 |  |  |  |  |  |  | # they become a single backslash. This should be fine on Windows since | 
| 461 |  |  |  |  |  |  | # backslashes are not used to escape metacharacters in cmd.exe. | 
| 462 | 3 |  |  |  |  | 19 | $line =~ s,\\,\\\\,g; | 
| 463 | 3 |  |  |  |  | 14 | shellwords($line); | 
| 464 |  |  |  |  |  |  | } | 
| 465 |  |  |  |  |  |  |  | 
| 466 |  |  |  |  |  |  | =head2 dynamic_libs | 
| 467 |  |  |  |  |  |  |  | 
| 468 |  |  |  |  |  |  | my @dlls = Alien::MyLibrary->dynamic_libs; | 
| 469 |  |  |  |  |  |  | my($dll) = Alien::MyLibrary->dynamic_libs; | 
| 470 |  |  |  |  |  |  |  | 
| 471 |  |  |  |  |  |  | Returns a list of the dynamic library or shared object files for the | 
| 472 |  |  |  |  |  |  | alien software. | 
| 473 |  |  |  |  |  |  |  | 
| 474 |  |  |  |  |  |  | =cut | 
| 475 |  |  |  |  |  |  |  | 
| 476 |  |  |  |  |  |  | sub dynamic_libs { | 
| 477 | 2 |  |  | 2 | 1 | 581 | my ($class) = @_; | 
| 478 |  |  |  |  |  |  |  | 
| 479 | 2 |  |  |  |  | 20 | require FFI::CheckLib; | 
| 480 |  |  |  |  |  |  |  | 
| 481 | 2 | 100 |  |  |  | 7 | if($class->install_type('system')) { | 
| 482 |  |  |  |  |  |  |  | 
| 483 | 1 |  |  |  |  | 3 | my $name = $class->config('ffi_name'); | 
| 484 | 1 | 50 |  |  |  | 5 | unless(defined $name) { | 
| 485 | 1 |  |  |  |  | 3 | $name = $class->config('name'); | 
| 486 |  |  |  |  |  |  | # strip leading lib from things like libarchive or libffi | 
| 487 | 1 |  |  |  |  | 3 | $name =~ s/^lib//; | 
| 488 |  |  |  |  |  |  | # strip trailing version numbers | 
| 489 | 1 |  |  |  |  | 3 | $name =~ s/-[0-9\.]+$//; | 
| 490 |  |  |  |  |  |  | } | 
| 491 |  |  |  |  |  |  |  | 
| 492 | 1 |  |  |  |  | 13 | return FFI::CheckLib::find_lib(lib => $name); | 
| 493 |  |  |  |  |  |  |  | 
| 494 |  |  |  |  |  |  | } else { | 
| 495 |  |  |  |  |  |  |  | 
| 496 | 1 |  |  |  |  | 5 | my $dir = $class->dist_dir; | 
| 497 | 1 |  |  |  |  | 5 | my $dynamic = File::Spec->catfile($class->dist_dir, 'dynamic'); | 
| 498 |  |  |  |  |  |  |  | 
| 499 | 1 | 50 |  |  |  | 13 | if(-d $dynamic) | 
| 500 |  |  |  |  |  |  | { | 
| 501 | 1 |  |  |  |  | 10 | return FFI::CheckLib::find_lib( | 
| 502 |  |  |  |  |  |  | lib        => '*', | 
| 503 |  |  |  |  |  |  | libpath    => $dynamic, | 
| 504 |  |  |  |  |  |  | systempath => [], | 
| 505 |  |  |  |  |  |  | ); | 
| 506 |  |  |  |  |  |  | } | 
| 507 |  |  |  |  |  |  |  | 
| 508 | 0 |  |  |  |  | 0 | return FFI::CheckLib::find_lib( | 
| 509 |  |  |  |  |  |  | lib        => '*', | 
| 510 |  |  |  |  |  |  | libpath    => $dir, | 
| 511 |  |  |  |  |  |  | systempath => [], | 
| 512 |  |  |  |  |  |  | recursive  => 1, | 
| 513 |  |  |  |  |  |  | ); | 
| 514 |  |  |  |  |  |  | } | 
| 515 |  |  |  |  |  |  | } | 
| 516 |  |  |  |  |  |  |  | 
| 517 |  |  |  |  |  |  | =head2 bin_dir | 
| 518 |  |  |  |  |  |  |  | 
| 519 |  |  |  |  |  |  | my(@dir) = Alien::MyLibrary->bin_dir | 
| 520 |  |  |  |  |  |  |  | 
| 521 |  |  |  |  |  |  | Returns a list of directories with executables in them.  For a C | 
| 522 |  |  |  |  |  |  | install this will be an empty list.  For a C install this will be | 
| 523 |  |  |  |  |  |  | a directory under C named C if it exists.  You may wish | 
| 524 |  |  |  |  |  |  | to override the default behavior if you have executables or scripts that | 
| 525 |  |  |  |  |  |  | get installed into non-standard locations. | 
| 526 |  |  |  |  |  |  |  | 
| 527 |  |  |  |  |  |  | Example usage: | 
| 528 |  |  |  |  |  |  |  | 
| 529 |  |  |  |  |  |  | use Env qw( @PATH ); | 
| 530 |  |  |  |  |  |  |  | 
| 531 |  |  |  |  |  |  | unshft @PATH, Alien::MyLibrary->bin_dir; | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | =cut | 
| 534 |  |  |  |  |  |  |  | 
| 535 |  |  |  |  |  |  | sub bin_dir { | 
| 536 | 3 |  |  | 3 | 1 | 2304 | my ($class) = @_; | 
| 537 | 3 | 100 |  |  |  | 8 | if($class->install_type('system')) | 
| 538 |  |  |  |  |  |  | { | 
| 539 | 1 |  |  |  |  | 4 | my $prop = $class->runtime_prop; | 
| 540 | 1 | 50 |  |  |  | 4 | return unless defined $prop; | 
| 541 | 1 | 50 |  |  |  | 7 | return unless defined $prop->{system_bin_dir}; | 
| 542 | 0 | 0 |  |  |  | 0 | return ref $prop->{system_bin_dir} ? @{ $prop->{system_bin_dir} } : ($prop->{system_bin_dir}); | 
|  | 0 |  |  |  |  | 0 |  | 
| 543 |  |  |  |  |  |  | } | 
| 544 |  |  |  |  |  |  | else | 
| 545 |  |  |  |  |  |  | { | 
| 546 | 2 |  |  |  |  | 5 | my $dir = File::Spec->catfile($class->dist_dir, 'bin'); | 
| 547 | 2 | 50 |  |  |  | 44 | return -d $dir ? ($dir) : (); | 
| 548 |  |  |  |  |  |  | } | 
| 549 |  |  |  |  |  |  | } | 
| 550 |  |  |  |  |  |  |  | 
| 551 |  |  |  |  |  |  | =head2 alien_helper | 
| 552 |  |  |  |  |  |  |  | 
| 553 |  |  |  |  |  |  | my $helpers = Alien::MyLibrary->alien_helper; | 
| 554 |  |  |  |  |  |  |  | 
| 555 |  |  |  |  |  |  | Returns a hash reference of helpers provided by the Alien module. | 
| 556 |  |  |  |  |  |  | The keys are helper names and the values are code references.  The | 
| 557 |  |  |  |  |  |  | code references will be executed at command time and the return value | 
| 558 |  |  |  |  |  |  | will be interpolated into the command before execution.  The default | 
| 559 |  |  |  |  |  |  | implementation returns an empty hash reference, and you are expected | 
| 560 |  |  |  |  |  |  | to override the method to create your own helpers. | 
| 561 |  |  |  |  |  |  |  | 
| 562 |  |  |  |  |  |  | For use with commands specified in and L or in your C | 
| 563 |  |  |  |  |  |  | when used with L. | 
| 564 |  |  |  |  |  |  |  | 
| 565 |  |  |  |  |  |  | Helpers allow users of your Alien module to use platform or environment | 
| 566 |  |  |  |  |  |  | determined logic to compute command names or arguments in your installer | 
| 567 |  |  |  |  |  |  | logic.  Helpers allow you to do this without making your Alien module a | 
| 568 |  |  |  |  |  |  | requirement when a build from source code is not necessary. | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | As a concrete example, consider L, which provides the | 
| 571 |  |  |  |  |  |  | helper C: | 
| 572 |  |  |  |  |  |  |  | 
| 573 |  |  |  |  |  |  | package Alien::gmake; | 
| 574 |  |  |  |  |  |  |  | 
| 575 |  |  |  |  |  |  | ... | 
| 576 |  |  |  |  |  |  |  | 
| 577 |  |  |  |  |  |  | sub alien_helper { | 
| 578 |  |  |  |  |  |  | my($class) = @_; | 
| 579 |  |  |  |  |  |  | return { | 
| 580 |  |  |  |  |  |  | gmake => sub { | 
| 581 |  |  |  |  |  |  | # return the executable name for GNU make, | 
| 582 |  |  |  |  |  |  | # usually either make or gmake depending on | 
| 583 |  |  |  |  |  |  | # the platform and environment | 
| 584 |  |  |  |  |  |  | $class->exe; | 
| 585 |  |  |  |  |  |  | } | 
| 586 |  |  |  |  |  |  | }, | 
| 587 |  |  |  |  |  |  | } | 
| 588 |  |  |  |  |  |  |  | 
| 589 |  |  |  |  |  |  | Now consider L.  C requires GNU Make to build from | 
| 590 |  |  |  |  |  |  | source code, but if the system C package is installed we don't | 
| 591 |  |  |  |  |  |  | need it.  From the L of C: | 
| 592 |  |  |  |  |  |  |  | 
| 593 |  |  |  |  |  |  | use alienfile; | 
| 594 |  |  |  |  |  |  |  | 
| 595 |  |  |  |  |  |  | plugin 'Probe::CommandLine' => ( | 
| 596 |  |  |  |  |  |  | command => 'nasm', | 
| 597 |  |  |  |  |  |  | args    => ['-v'], | 
| 598 |  |  |  |  |  |  | match   => qr/NASM version/, | 
| 599 |  |  |  |  |  |  | ); | 
| 600 |  |  |  |  |  |  |  | 
| 601 |  |  |  |  |  |  | share { | 
| 602 |  |  |  |  |  |  | ... | 
| 603 |  |  |  |  |  |  | plugin 'Extract' => 'tar.gz'; | 
| 604 |  |  |  |  |  |  | plugin 'Build::MSYS' => (); | 
| 605 |  |  |  |  |  |  |  | 
| 606 |  |  |  |  |  |  | build [ | 
| 607 |  |  |  |  |  |  | 'sh configure --prefix=%{alien.install.prefix}', | 
| 608 |  |  |  |  |  |  | '%{gmake}', | 
| 609 |  |  |  |  |  |  | '%{gmake} install', | 
| 610 |  |  |  |  |  |  | ]; | 
| 611 |  |  |  |  |  |  | }; | 
| 612 |  |  |  |  |  |  |  | 
| 613 |  |  |  |  |  |  | ... | 
| 614 |  |  |  |  |  |  |  | 
| 615 |  |  |  |  |  |  | =cut | 
| 616 |  |  |  |  |  |  |  | 
| 617 |  |  |  |  |  |  | sub alien_helper { | 
| 618 | 0 |  |  | 0 | 1 | 0 | {}; | 
| 619 |  |  |  |  |  |  | } | 
| 620 |  |  |  |  |  |  |  | 
| 621 |  |  |  |  |  |  | =head2 inline_auto_include | 
| 622 |  |  |  |  |  |  |  | 
| 623 |  |  |  |  |  |  | my(@headers) = Alien::MyLibrary->inline_auto_include; | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | List of header files to automatically include in inline C and C++ | 
| 626 |  |  |  |  |  |  | code when using L or L.  This is provided | 
| 627 |  |  |  |  |  |  | as a public interface primarily so that it can be overidden at run | 
| 628 |  |  |  |  |  |  | time.  This can also be specified in your C with | 
| 629 |  |  |  |  |  |  | L using the C | 
| 630 |  |  |  |  |  |  | property. | 
| 631 |  |  |  |  |  |  |  | 
| 632 |  |  |  |  |  |  | =cut | 
| 633 |  |  |  |  |  |  |  | 
| 634 |  |  |  |  |  |  | sub inline_auto_include { | 
| 635 | 0 |  |  | 0 | 1 | 0 | my ($class) = @_; | 
| 636 | 0 | 0 |  |  |  | 0 | return [] unless $class->config('inline_auto_include'); | 
| 637 | 0 |  |  |  |  | 0 | $class->config('inline_auto_include') | 
| 638 |  |  |  |  |  |  | } | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  | sub Inline { | 
| 641 | 0 |  |  | 0 | 0 | 0 | my ($class, $language) = @_; | 
| 642 | 0 | 0 |  |  |  | 0 | return if $language !~ /^(C|CPP)$/; | 
| 643 | 0 |  |  |  |  | 0 | my $config = { | 
| 644 |  |  |  |  |  |  | CCFLAGSEX    => $class->cflags, | 
| 645 |  |  |  |  |  |  | LIBS         => $class->libs, | 
| 646 |  |  |  |  |  |  | }; | 
| 647 |  |  |  |  |  |  |  | 
| 648 | 0 | 0 |  |  |  | 0 | if (@{ $class->inline_auto_include } > 0) { | 
|  | 0 |  |  |  |  | 0 |  | 
| 649 | 0 |  |  |  |  | 0 | $config->{AUTO_INCLUDE} = join "\n", map { "#include \"$_\"" } @{ $class->inline_auto_include }; | 
|  | 0 |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  | 0 |  | 
| 650 |  |  |  |  |  |  | } | 
| 651 |  |  |  |  |  |  |  | 
| 652 | 0 |  |  |  |  | 0 | $config; | 
| 653 |  |  |  |  |  |  | } | 
| 654 |  |  |  |  |  |  |  | 
| 655 |  |  |  |  |  |  | =head2 runtime_prop | 
| 656 |  |  |  |  |  |  |  | 
| 657 |  |  |  |  |  |  | my $hashref = Alien::MyLibrary->runtime_prop; | 
| 658 |  |  |  |  |  |  |  | 
| 659 |  |  |  |  |  |  | Returns a hash reference of the runtime properties computed by L during its | 
| 660 |  |  |  |  |  |  | install process.  If the L based L was not built using L, | 
| 661 |  |  |  |  |  |  | then this will return undef. | 
| 662 |  |  |  |  |  |  |  | 
| 663 |  |  |  |  |  |  | =cut | 
| 664 |  |  |  |  |  |  |  | 
| 665 |  |  |  |  |  |  | { | 
| 666 |  |  |  |  |  |  | my %alien_build_config_cache; | 
| 667 |  |  |  |  |  |  |  | 
| 668 |  |  |  |  |  |  | sub runtime_prop | 
| 669 |  |  |  |  |  |  | { | 
| 670 | 104 |  |  | 104 | 1 | 726 | my($class) = @_; | 
| 671 |  |  |  |  |  |  |  | 
| 672 |  |  |  |  |  |  | return $alien_build_config_cache{$class} if | 
| 673 | 104 | 100 |  |  |  | 548 | exists $alien_build_config_cache{$class}; | 
| 674 |  |  |  |  |  |  |  | 
| 675 | 6 |  | 66 |  |  | 40 | $alien_build_config_cache{$class} ||= do { | 
| 676 | 6 | 100 |  |  |  | 26 | my $dist = ref $class ? ref $class : $class; | 
| 677 | 6 |  |  |  |  | 26 | $dist =~ s/::/-/g; | 
| 678 | 6 |  |  |  |  | 17 | my $dist_dir = eval { File::ShareDir::dist_dir($dist) }; | 
|  | 6 |  |  |  |  | 43 |  | 
| 679 | 6 | 100 |  |  |  | 1142 | return if $@; | 
| 680 | 5 |  |  |  |  | 79 | my $alien_json = File::Spec->catfile($dist_dir, '_alien', 'alien.json'); | 
| 681 | 5 | 100 |  |  |  | 153 | return unless -r $alien_json; | 
| 682 | 2 |  |  |  |  | 69 | open my $fh, '<', $alien_json; | 
| 683 | 2 |  |  |  |  | 8 | my $json = do { local $/; <$fh> }; | 
|  | 2 |  |  |  |  | 11 |  | 
|  | 2 |  |  |  |  | 43 |  | 
| 684 | 2 |  |  |  |  | 18 | close $fh; | 
| 685 | 2 |  |  |  |  | 904 | require JSON::PP; | 
| 686 | 2 |  |  |  |  | 18067 | my $config = JSON::PP::decode_json($json); | 
| 687 | 2 |  |  |  |  | 12307 | $config->{distdir} = $dist_dir; | 
| 688 | 2 |  |  |  |  | 34 | $config; | 
| 689 |  |  |  |  |  |  | }; | 
| 690 |  |  |  |  |  |  | } | 
| 691 |  |  |  |  |  |  | } | 
| 692 |  |  |  |  |  |  |  | 
| 693 |  |  |  |  |  |  | 1; | 
| 694 |  |  |  |  |  |  |  | 
| 695 |  |  |  |  |  |  | __END__ |