3 package Config::Perl::V;
10 use vars qw($VERSION @ISA @EXPORT_OK %EXPORT_TAGS);
13 @EXPORT_OK = qw( plv2hash summary myconfig signature );
15 all => [ @EXPORT_OK ],
16 sig => [ "signature" ],
19 # Characteristics of this binary (from libperl):
20 # Compile-time options: DEBUGGING PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP
21 # USE_64_BIT_INT USE_LARGE_FILES USE_PERLIO
23 # The list are as the perl binary has stored it in PL_bincompat_options
25 # perl.c line 1669 S_Internals_V ()
26 # perl.h line 4505 PL_bincompat_options
27 my %BTD = map { $_ => 0 } qw(
36 PERL_HASH_FUNC_SIPHASH
39 PERL_HASH_FUNC_SUPERFAST
40 PERL_HASH_FUNC_MURMUR3
41 PERL_HASH_FUNC_ONE_AT_A_TIME
42 PERL_HASH_FUNC_ONE_AT_A_TIME_HARD
43 PERL_HASH_FUNC_ONE_AT_A_TIME_OLD
51 PERL_MEM_LOG_TIMESTAMP
52 PERL_NEW_COPY_ON_WRITE
53 PERL_PERTURB_KEYS_DETERMINISTIC
54 PERL_PERTURB_KEYS_DISABLED
55 PERL_PERTURB_KEYS_RANDOM
57 PERL_RELOCATABLE_INCPUSH
61 USE_ATTRIBUTES_FOR_PERLIO
63 USE_HASH_SEED_EXPLICIT
70 DEBUG_LEAKING_SCALARS_FORK_DUMP
79 PERL_DEBUG_READONLY_OPS
87 PERL_OLD_COPY_ON_WRITE
91 PERL_USES_PL_PIDSTATUS
109 VMS_SHORTEN_LONG_SYMBOLS
110 VMS_SYMBOL_CASE_AS_IS
113 # These are all the keys that are
114 # 1. Always present in %Config - lib/Config.pm #87 tie %Config
115 # 2. Reported by 'perl -V' (the rest)
116 my @config_vars = qw(
142 git_uncommitted_changes
146 package revision version_patchlevel_string
148 osname osvers archname
151 hint useposix d_sigaction
152 useithreads usemultiplicity
153 useperlio d_sfio uselargefiles usesocks
154 use64bitint use64bitall uselongdouble
155 usemymalloc bincompat5005
160 ccversion gccversion gccosandvers
161 intsize longsize ptrsize doublesize byteorder
162 d_longlong longlongsize d_longdbl longdblsize
163 ivtype ivsize nvtype nvsize lseektype lseeksize
170 libc so useshrplib libperl
173 dlsrc dlext d_dlsymun ccdlflags
188 for ( [ lseektype => "Off_t" ],
189 [ myuname => "uname" ],
190 [ perl_patchlevel => "patch" ],
192 my ($official, $derived) = @$_;
193 $conf->{config}{$derived} ||= $conf->{config}{$official};
194 $conf->{config}{$official} ||= $conf->{config}{$derived};
195 $conf->{derived}{$derived} = delete $conf->{config}{$derived};
198 if (exists $conf->{config}{version_patchlevel_string} &&
199 !exists $conf->{config}{api_version}) {
200 my $vps = $conf->{config}{version_patchlevel_string};
201 $vps =~ s{\b revision \s+ (\S+) }{}x and
202 $conf->{config}{revision} ||= $1;
204 $vps =~ s{\b version \s+ (\S+) }{}x and
205 $conf->{config}{api_version} ||= $1;
206 $vps =~ s{\b subversion \s+ (\S+) }{}x and
207 $conf->{config}{subversion} ||= $1;
208 $vps =~ s{\b patch \s+ (\S+) }{}x and
209 $conf->{config}{perl_patchlevel} ||= $1;
212 ($conf->{config}{version_patchlevel_string} ||= join " ",
213 map { ($_, $conf->{config}{$_} ) }
214 grep { $conf->{config}{$_} }
215 qw( api_version subversion perl_patchlevel )) =~ s/\bperl_//;
217 $conf->{config}{perl_patchlevel} ||= ""; # 0 is not a valid patchlevel
219 if ($conf->{config}{perl_patchlevel} =~ m{^git\w*-([^-]+)}i) {
220 $conf->{config}{git_branch} ||= $1;
221 $conf->{config}{git_describe} ||= $conf->{config}{perl_patchlevel};
230 for (split m/\n+/ => join "\n", @_) {
232 if (s/^Summary of my\s+(\S+)\s+\(\s*(.*?)\s*\)//) {
233 $config{"package"} = $1;
235 $rev =~ s/^ revision \s+ (\S+) \s*//x and $config{revision} = $1;
236 $rev and $config{version_patchlevel_string} = $rev;
237 my ($rel) = $config{package} =~ m{perl(\d)};
238 my ($vers, $subvers) = $rev =~ m{version\s+(\d+)\s+subversion\s+(\d+)};
239 defined $vers && defined $subvers && defined $rel and
240 $config{version} = "$rel.$vers.$subvers";
244 if (s/^\s+(Snapshot of:)\s+(\S+)//) {
245 $config{git_commit_id_title} = $1;
246 $config{git_commit_id} = $2;
250 my %kv = m/\G,?\s*([^=]+)=('[^']+?'|\S+)/gc;
252 while (my ($k, $v) = each %kv) {
255 $v =~ m/^'(.*)'$/ and $v = $1;
261 my $build = { %empty_build };
262 $build->{osname} = $config{osname};
263 return _make_derived ({
274 my $conf = shift || myconfig ();
275 ref $conf eq "HASH" &&
276 exists $conf->{config} && exists $conf->{build} or return;
279 exists $conf->{config}{$_} ? ( $_ => $conf->{config}{$_} ) : () }
280 qw( archname osname osvers revision patchlevel subversion version
281 cc ccversion gccversion config_args inc_version_list
282 d_longdbl d_longlong use64bitall use64bitint useithreads
283 uselongdouble usemultiplicity usemymalloc useperlio useshrplib
284 doublesize intsize ivsize nvsize longdblsize longlongsize lseeksize
286 $info{$_}++ for grep { $conf->{build}{options}{$_} } keys %{$conf->{build}{options}};
293 eval { require Digest::MD5 };
294 $@ and return "00000000000000000000000000000000";
296 my $conf = shift || summary ();
297 delete $conf->{config_args};
298 return Digest::MD5::md5_hex (join "\xFF" => map {
299 "$_=".(defined $conf->{$_} ? $conf->{$_} : "\xFE");
306 my %args = ref $args eq "HASH" ? %$args :
307 ref $args eq "ARRAY" ? @$args : ();
309 my $build = { %empty_build };
311 # 5.14.0 and later provide all the information without shelling out
312 my $stamp = eval { Config::compile_date () };
313 if (defined $stamp) {
314 $stamp =~ s/^Compiled at //;
315 $build->{osname} = $^O;
316 $build->{stamp} = $stamp;
317 $build->{patches} = [ Config::local_patches () ];
318 $build->{options}{$_} = 1 for Config::bincompat_options (),
319 Config::non_bincompat_options ();
322 #y $pv = qx[$^X -e"sub Config::myconfig{};" -V];
324 $pv =~ s{.*?\n\n}{}s;
325 $pv =~ s{\n(?: \s+|\t\s*)}{\0}g;
329 $pv =~ m{^\s+Built under\s+(.*)}m
330 and $build->{osname} = $1;
331 $pv =~ m{^\s+Compiled at\s+(.*)}m
332 and $build->{stamp} = $1;
333 $pv =~ m{^\s+Locally applied patches:(?:\s+|\0)(.*)}m
334 and $build->{patches} = [ split m/\0+/, $1 ];
335 $pv =~ m{^\s+Compile-time options:(?:\s+|\0)(.*)}m
336 and map { $build->{options}{$_} = 1 } split m/\s+|\0/ => $1;
339 my @KEYS = keys %ENV;
341 map { $_ => $ENV{$_} } grep m/^PERL/ => @KEYS;
343 map { $env{$_} = $ENV{$_} } grep m{$args{env}} => @KEYS;
345 my %config = map { $_ => $Config{$_} } @config_vars;
347 return _make_derived ({
349 environment => \%env,
362 Config::Perl::V - Structured data retrieval of perl -V output
368 my $local_config = Config::Perl::V::myconfig ();
369 print $local_config->{config}{osname};
373 =head2 $conf = myconfig ()
375 This function will collect the data described in L<the hash structure> below,
376 and return that as a hash reference. It optionally accepts an option to
377 include more entries from %ENV. See L<environment> below.
379 Note that this will not work on uninstalled perls when called with
380 C<-I/path/to/uninstalled/perl/lib>, but it works when that path is in
381 C<$PERL5LIB> or in C<$PERL5OPT>, as paths passed using C<-I> are not
382 known when the C<-V> information is collected.
384 =head2 $conf = plv2hash ($text [, ...])
386 Convert a sole 'perl -V' text block, or list of lines, to a complete
387 myconfig hash. All unknown entries are defaulted.
389 =head2 $info = summary ([$conf])
391 Return an arbitrary selection of the information. If no C<$conf> is
392 given, C<myconfig ()> is used instead.
394 =head2 $md5 = signature ([$conf])
396 Return the MD5 of the info returned by C<summary ()> without the
397 C<config_args> entry.
399 If C<Digest::MD5> is not available, it return a string with only C<0>'s.
401 =head2 The hash structure
403 The returned hash consists of 4 parts:
409 This information is extracted from the second block that is emitted by
410 C<perl -V>, and usually looks something like
412 Characteristics of this binary (from libperl):
413 Compile-time options: DEBUGGING USE_64_BIT_INT USE_LARGE_FILES
414 Locally applied patches:
418 Compiled at Jun 13 2005 10:44:20
420 /usr/lib/perl5/5.8.7/i686-linux-64int
422 /usr/lib/perl5/site_perl/5.8.7/i686-linux-64int
423 /usr/lib/perl5/site_perl/5.8.7
424 /usr/lib/perl5/site_perl
429 Characteristics of this binary (from libperl):
430 Compile-time options: DEBUGGING MULTIPLICITY
431 PERL_DONT_CREATE_GVSV PERL_IMPLICIT_CONTEXT
432 PERL_MALLOC_WRAP PERL_TRACK_MEMPOOL
433 PERL_USE_SAFE_PUTENV USE_ITHREADS
434 USE_LARGE_FILES USE_PERLIO
437 Compiled at Jan 28 2009 15:26:59
439 This information is not available anywhere else, including C<%Config>,
440 but it is the information that is only known to the perl binary.
442 The extracted information is stored in 5 entries in the C<build> hash:
448 This is most likely the same as C<$Config{osname}>, and was the name
449 known when perl was built. It might be different if perl was cross-compiled.
451 The default for this field, if it cannot be extracted, is to copy
452 C<$Config{osname}>. The two may be differing in casing (OpenBSD vs openbsd).
456 This is the time string for which the perl binary was compiled. The default
461 This is a hash with all the known defines as keys. The value is either 0,
462 which means unknown or unset, or 1, which means defined.
466 As some variables are reported by a different name in the output of C<perl -V>
467 than their actual name in C<%Config>, I decided to leave the C<config> entry
468 as close to reality as possible, and put in the entries that might have been
469 guessed by the printed output in a separate block.
473 This is a list of optionally locally applied patches. Default is an empty list.
479 By default this hash is only filled with the environment variables
480 out of %ENV that start with C<PERL>, but you can pass the C<env> option
481 to myconfig to get more
483 my $conf = Config::Perl::V::myconfig ({ env => qr/^ORACLE/ });
484 my $conf = Config::Perl::V::myconfig ([ env => qr/^ORACLE/ ]);
488 This hash is filled with the variables that C<perl -V> fills its report
489 with, and it has the same variables that C<Config::myconfig> returns
494 This is the list of default @INC.
500 This module was written to be able to return the configuration for the
501 currently used perl as deeply as needed for the CPANTESTERS framework.
502 Up until now they used the output of myconfig as a single text blob,
503 and so it was missing the vital binary characteristics of the running
504 perl and the optional applied patches.
508 Please feedback what is wrong
512 * Implement retrieval functions/methods
519 H.Merijn Brand <h.m.brand@xs4all.nl>
521 =head1 COPYRIGHT AND LICENSE
523 Copyright (C) 2009-2013 H.Merijn Brand
525 This library is free software; you can redistribute it and/or modify
526 it under the same terms as Perl itself.