Commit | Line | Data |
---|---|---|
8e232993 | 1 | package FindExt; |
28b605d8 | 2 | |
a1f2e719 | 3 | our $VERSION = '1.02'; |
28b605d8 | 4 | |
8e232993 | 5 | use strict; |
ca58f2ae | 6 | use warnings; |
8e232993 | 7 | |
ca58f2ae | 8 | my $no = join('|',qw(GDBM_File ODBM_File NDBM_File DB_File |
b699af07 | 9 | VMS VMS-DCLsym VMS-Stdio Sys-Syslog IPC-SysV I18N-Langinfo)); |
8e232993 NIS |
10 | $no = qr/^(?:$no)$/i; |
11 | ||
557ab4cb TC |
12 | sub apply_config { |
13 | my ($config) = @_; | |
14 | my @no; | |
15 | ||
21339399 SH |
16 | push @no, 'Sys-Syslog' if $^O eq 'MSWin32'; |
17 | ||
557ab4cb TC |
18 | # duplicates logic from Configure (mostly) |
19 | push @no, "DB_File" unless $config->{i_db}; | |
20 | push @no, "GDBM_File" unless $config->{i_gdbm}; | |
21 | push @no, "I18N-Langinfo" unless $config->{i_langinfo} && $config->{i_nl_langinfo}; | |
22 | push @no, "IPC-SysV" unless $config->{d_msg} || $config->{d_sem} || $config->{d_shm}; | |
23 | push @no, "NDBM_File" unless $config->{d_ndbm}; | |
24 | push @no, "ODBM_File" | |
25 | unless ($config->{i_dbm} || $config->{i_rpcsvcdbm}) && !$config->{d_cplusplus}; | |
26 | push @no, "VMS.*" unless $^O eq "VMS"; | |
27 | push @no, "Win32.*" unless $^O eq "MSWin32" || $^O eq "cygwin"; | |
28 | ||
29 | $no = join('|', @no); | |
30 | $no = qr/^(?:$no)$/i; | |
31 | } | |
32 | ||
8e232993 | 33 | my %ext; |
ca58f2ae YST |
34 | my %static; |
35 | ||
a1f2e719 | 36 | sub set_static_extensions { |
ca58f2ae YST |
37 | # adjust results of scan_ext, and also save |
38 | # statics in case scan_ext hasn't been called yet. | |
a1f2e719 VK |
39 | # if '*' is passed then all XS extensions are static |
40 | # (with possible exclusions) | |
ca58f2ae | 41 | %static = (); |
a1f2e719 | 42 | my @list = @_; |
14f183f1 | 43 | if (@_ and $_[0] eq '*') { |
a1f2e719 VK |
44 | my %excl = map {$_=>1} map {m/^!(.*)$/} @_[1 .. $#_]; |
45 | @list = grep {!exists $excl{$_}} keys %ext; | |
46 | } | |
47 | for (@list) { | |
ca58f2ae YST |
48 | $static{$_} = 1; |
49 | $ext{$_} = 'static' if $ext{$_} && $ext{$_} eq 'dynamic'; | |
50 | } | |
21339399 SH |
51 | |
52 | # Encode is a special case. If we are building Encode as a static | |
53 | # extension, we need to explicitly list its subextensions as well. | |
54 | # For other nested extensions, this is handled automatically by | |
55 | # the appropriate Makefile.PL. | |
56 | if ($ext{Encode} && $ext{Encode} eq 'static') { | |
2b7bd0cd NC |
57 | require File::Find; |
58 | File::Find::find({ | |
59 | no_chdir => 1, | |
60 | wanted => sub { | |
61 | return unless m!\b(Encode/.+)/Makefile\.PL!; | |
62 | $static{$1} = 1; | |
63 | $ext{$1} = 'static'; | |
64 | }, | |
65 | }, "../cpan/Encode"); | |
21339399 | 66 | } |
ca58f2ae YST |
67 | } |
68 | ||
8e232993 NIS |
69 | sub scan_ext |
70 | { | |
d57db09d | 71 | my $dir = shift; |
1f8a0b38 | 72 | find_ext("$dir/"); |
d57db09d | 73 | extensions(); |
8e232993 NIS |
74 | } |
75 | ||
442749d5 NC |
76 | sub _ext_eq { |
77 | my $key = shift; | |
78 | sub { | |
79 | sort grep $ext{$_} eq $key, keys %ext; | |
80 | } | |
ca58f2ae YST |
81 | } |
82 | ||
442749d5 NC |
83 | *dynamic_ext = _ext_eq('dynamic'); |
84 | *static_ext = _ext_eq('static'); | |
85 | *nonxs_ext = _ext_eq('nonxs'); | |
8e232993 | 86 | |
442749d5 NC |
87 | sub _ext_ne { |
88 | my $key = shift; | |
89 | sub { | |
90 | sort grep $ext{$_} ne $key, keys %ext; | |
91 | } | |
ca58f2ae YST |
92 | } |
93 | ||
442749d5 NC |
94 | *extensions = _ext_ne('known'); |
95 | # faithfully copy Configure in not including nonxs extensions for the nonce | |
96 | *known_extensions = _ext_ne('nonxs'); | |
ca58f2ae YST |
97 | |
98 | sub is_static | |
99 | { | |
100 | return $ext{$_[0]} eq 'static' | |
8e232993 NIS |
101 | } |
102 | ||
0a3660e3 NC |
103 | sub has_xs_or_c { |
104 | my $dir = shift; | |
105 | opendir my $dh, $dir or die "opendir $dir: $!"; | |
106 | while (defined (my $item = readdir $dh)) { | |
107 | return 1 if $item =~ /\.xs$/; | |
108 | return 1 if $item =~ /\.c$/; | |
109 | } | |
110 | return 0; | |
111 | } | |
112 | ||
1f8a0b38 | 113 | # Function to find available extensions, ignoring DynaLoader |
8e232993 NIS |
114 | sub find_ext |
115 | { | |
3380c781 | 116 | my $ext_dir = shift; |
1f8a0b38 | 117 | opendir my $dh, "$ext_dir"; |
3380c781 NC |
118 | while (defined (my $item = readdir $dh)) { |
119 | next if $item =~ /^\.\.?$/; | |
120 | next if $item eq "DynaLoader"; | |
1f8a0b38 NC |
121 | next unless -d "$ext_dir$item"; |
122 | my $this_ext = $item; | |
f44bdcee NC |
123 | my $leaf = $item; |
124 | ||
125 | $this_ext =~ s!-!/!g; | |
126 | $leaf =~ s/.*-//; | |
127 | ||
4d33dfde NC |
128 | # Temporary hack to cope with smokers that are not clearing directories: |
129 | next if $ext{$this_ext}; | |
130 | ||
88a6f4fc | 131 | if (has_xs_or_c("$ext_dir$item")) { |
3380c781 | 132 | $ext{$this_ext} = $static{$this_ext} ? 'static' : 'dynamic'; |
3380c781 | 133 | } else { |
1f8a0b38 | 134 | $ext{$this_ext} = 'nonxs'; |
ca58f2ae | 135 | } |
3380c781 | 136 | $ext{$this_ext} = 'known' if $ext{$this_ext} && $item =~ $no; |
ca58f2ae | 137 | } |
8e232993 NIS |
138 | } |
139 | ||
140 | 1; | |
3380c781 NC |
141 | # Local variables: |
142 | # cperl-indent-level: 4 | |
143 | # indent-tabs-mode: nil | |
144 | # End: | |
145 | # | |
146 | # ex: set ts=8 sts=4 sw=4 et: |