This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
test that perl headers don't introduce external references
[perl5.git] / t / porting / extrefs.t
CommitLineData
68fd3ca5
TC
1#!./perl -w
2
3# What does this test?
4# Test that changes to perl header files don't cause external
5# references by simplying #including them. This breaks library probe
6# code on CPAN, and can break cflags.SH.
7#
8# Why do we test this?
9# See https://rt.perl.org/rt3/Ticket/Display.html?id=116989
10#
11# It's broken - how do I fix it?
12# You added an initializer or static function to a header file that
13# references some symbol you didn't define, you need to remove it.
14
15use strict;
16use warnings;
17
18BEGIN {
19 require "./test.pl";
20 unshift @INC, ".." if -f "../TestInit.pm";
21}
22
23use TestInit qw(T A); # T is chdir to the top level, A makes paths absolute
24use Config;
25use File::Path 'rmtree';
26use Cwd;
27
28skip_all("we don't test this on Win32") if $^O eq "MSWin32";
29
30plan(tests => 1);
31
32ok(try_compile_and_link(<<'CODE'));
33#include "EXTERN.h"
34#include "perl.h"
35#include "XSUB.h"
36
37int main(int argc, char **argv) {
38 return 0;
39}
40CODE
41
42
43# from Time::HiRes's Makefile.PL with minor modifications
44sub try_compile_and_link {
45 my ($c, %args) = @_;
46
47 my $LIBS = [];
48 my $ld_exeext = ($^O eq 'cygwin' ||
49 $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' :
50 (($^O eq 'vos') ? $Config{exe_ext} : '');
51 my $VERBOSE = 1;
52
53 my ($ok) = 0;
54 my $tempdir = tempfile();
55 my $cwd = getcwd();
56 mkdir $tempdir;
57 chdir $tempdir;
58 my ($tmp) = "temp";
59 local(*TMPC);
60
61 my $obj_ext = $Config{obj_ext} || ".o";
62 unlink("$tmp.c", "$tmp$obj_ext");
63
64 if (open(TMPC, ">$tmp.c")) {
65 print TMPC $c;
66 close(TMPC);
67
68 my $cccmd = $args{cccmd};
69
70 my $errornull;
71
72 my $COREincdir;
73
74 if ($ENV{PERL_CORE}) {
75 my $updir = File::Spec->updir;
76 $COREincdir = File::Spec->catdir($updir);
77 } else {
78 $COREincdir = File::Spec->catdir($Config{'archlibexp'}, 'CORE');
79 }
80
81 if ($ENV{PERL_CORE}) {
82 unless (-f File::Spec->catfile($COREincdir, "EXTERN.h")) {
83 chdir($cwd);
84 rmtree($tempdir);
85 die <<__EOD__;
86Your environment variable PERL_CORE is '$ENV{PERL_CORE}' but there
87is no EXTERN.h in $COREincdir.
88Cannot continue, aborting.
89__EOD__
90 }
91 }
92
93 my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir"
94 . ' -DPERL_NO_INLINE_FUNCTIONS';
95
96 if ($^O eq 'VMS') {
97 $cccmd = "$Config{'cc'} /include=($COREincdir) $tmp.c";
98 }
99
100 if ($args{silent} || !$VERBOSE) {
101 $errornull = "2>/dev/null" unless defined $errornull;
102 } else {
103 $errornull = '';
104 }
105
106 $cccmd = "$Config{'cc'} -o $tmp $ccflags $tmp.c @$LIBS $errornull"
107 unless defined $cccmd;
108
109 if ($^O eq 'VMS') {
110 open( CMDFILE, ">$tmp.com" );
111 print CMDFILE "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n";
112 print CMDFILE "\$ $cccmd\n";
113 print CMDFILE "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate
114 close CMDFILE;
115 system("\@ $tmp.com");
116 $ok = $?==0;
117 chdir($cwd);
118 rmtree($tempdir);
119 #for ("$tmp.c", "$tmp$obj_ext", "$tmp.com", "$tmp$Config{exe_ext}") {
120 #1 while unlink $_;
121 #}
122 }
123 else
124 {
125 my $tmp_exe = "$tmp$ld_exeext";
126 printf "cccmd = $cccmd\n" if $VERBOSE;
127 my $res = system($cccmd);
128 $ok = defined($res) && $res == 0 && -s $tmp_exe && -x _;
129
130 if ( $ok && exists $args{run} && $args{run}) {
131 my $tmp_exe =
132 File::Spec->catfile(File::Spec->curdir, $tmp_exe);
133 printf "Running $tmp_exe..." if $VERBOSE;
134 if (system($tmp_exe) == 0) {
135 $ok = 1;
136 } else {
137 $ok = 0;
138 my $errno = $? >> 8;
139 local $! = $errno;
140 printf <<EOF;
141
142*** The test run of '$tmp_exe' failed: status $?
143*** (the status means: errno = $errno or '$!')
144*** DO NOT PANIC: this just means that *some* functionality will be missing.
145EOF
146 }
147 }
148 chdir($cwd);
149 rmtree($tempdir);
150 #unlink("$tmp.c", $tmp_exe);
151 }
152 }
153
154 return $ok;
155}