xref: /openbsd/gnu/usr.bin/perl/t/porting/extrefs.t (revision 5486feef)
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://github.com/Perl/perl5/issues/12824
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
15BEGIN {
16  require "./test.pl";
17  unshift @INC, ".." if -f "../TestInit.pm";
18}
19
20use TestInit qw(T A); # T is chdir to the top level, A makes paths absolute
21use strict;
22use warnings;
23use Config;
24use File::Path 'rmtree';
25use Cwd;
26use IPC::Cmd qw(can_run);
27
28if ($Config{'usecrosscompile'} && !can_run($Config{'cc'})) {
29    skip_all("compiler not available (cross-compiling)");
30} else {
31    plan(tests => 1);
32}
33
34my $VERBOSE = grep {$_ eq '-v'} @ARGV;
35
36ok(try_compile_and_link(<<'CODE'));
37#include "EXTERN.h"
38#include "perl.h"
39#include "XSUB.h"
40
41int main(int argc, char **argv) {
42  return 0;
43}
44CODE
45
46
47# from Time::HiRes's Makefile.PL with minor modifications
48sub try_compile_and_link {
49    my ($c, %args) = @_;
50
51    my $ld_exeext = ($^O eq 'cygwin' || $^O eq 'MSWin32' ||
52                 $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' :
53                (($^O eq 'vos') ? $Config{exe_ext} : '');
54
55    my ($ok) = 0;
56    my $tempdir = tempfile();
57    my $cwd = getcwd();
58    mkdir $tempdir;
59    chdir $tempdir;
60    my ($tmp) = "temp";
61
62    my $obj_ext = $Config{obj_ext} || ".o";
63
64    if (open(my $tmpc, ">$tmp.c")) {
65	print $tmpc $c;
66	unless (close($tmpc)) {
67	    chdir($cwd);
68	    rmtree($tempdir);
69	    warn "Failing closing code file: $!\n" if $VERBOSE;
70	    return 0;
71	}
72
73	my $COREincdir =
74	    File::Spec->catdir(File::Spec->updir, File::Spec->updir);
75
76	my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir"
77	 . ' -DPERL_NO_INLINE_FUNCTIONS';
78
79	if ($^O eq "MSWin32") {
80	    $ccflags .= " -I../../win32 -I../../win32/include "
81             . "-I../../win32/full";
82	}
83
84	my $libs = '';
85
86	# Include libs to be sure of linking against bufferoverflowU.lib for
87	# the SDK2003 compiler on Windows. See win32/Makefile for more details.
88	if ($^O eq "MSWin32" && $Config{cc} =~ /\bcl\b/i) {
89	    $libs = " /link $Config{'libs'}";
90	}
91
92	my $null = File::Spec->devnull;
93
94	my $errornull = $VERBOSE ? '' : ">$null 2>$null";
95
96	# Darwin g++ 4.2.1 is fussy and demands a space.
97	# FreeBSD g++ 4.2.1 does not.
98	# We do not know the reaction of either to the presence of brown M&Ms.
99	my $out_opt = "-o ";
100	if ($^O eq "MSWin32" && $Config{cc} =~ /\bcl\b/i) {
101	    $out_opt = "/Fe";
102	}
103
104	my $tmp_exe = "$tmp$ld_exeext";
105
106        my $cccmd = "$Config{'cc'} $out_opt$tmp_exe $ccflags $tmp.c $libs $errornull";
107
108	if ($^O eq 'VMS') {
109            $cccmd = "$Config{'cc'} $Config{'ccflags'}/include=($COREincdir) $tmp.c";
110        }
111
112       if ($^O eq 'VMS') {
113	    open( my $cmdfile, ">$tmp.com" );
114	    print $cmdfile "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n";
115	    print $cmdfile "\$ $cccmd\n";
116	    print $cmdfile "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate
117	    close $cmdfile;
118	    system("\@ $tmp.com");
119	    $ok = $?==0;
120	    chdir($cwd);
121	    rmtree($tempdir);
122        }
123        else
124        {
125	    printf "cccmd = $cccmd\n" if $VERBOSE;
126	    my $res = system($cccmd);
127	    $ok = defined($res) && $res == 0 && -s $tmp_exe && -x _;
128
129	    chdir($cwd);
130	    rmtree($tempdir);
131        }
132    }
133
134    return $ok;
135}
136