xref: /openbsd-src/gnu/usr.bin/perl/t/porting/extrefs.t (revision 5486feefcc8cb79b19e014ab332cc5dfd05b3b33)
191f110e0Safresh1#!./perl -w
291f110e0Safresh1
391f110e0Safresh1# What does this test?
491f110e0Safresh1# Test that changes to perl header files don't cause external
591f110e0Safresh1# references by simplying #including them.  This breaks library probe
691f110e0Safresh1# code on CPAN, and can break cflags.SH.
791f110e0Safresh1#
891f110e0Safresh1# Why do we test this?
9de8cc8edSafresh1# See https://github.com/Perl/perl5/issues/12824
1091f110e0Safresh1#
1191f110e0Safresh1# It's broken - how do I fix it?
1291f110e0Safresh1# You added an initializer or static function to a header file that
1391f110e0Safresh1# references some symbol you didn't define, you need to remove it.
1491f110e0Safresh1
1591f110e0Safresh1BEGIN {
1691f110e0Safresh1  require "./test.pl";
1791f110e0Safresh1  unshift @INC, ".." if -f "../TestInit.pm";
1891f110e0Safresh1}
1991f110e0Safresh1
2091f110e0Safresh1use TestInit qw(T A); # T is chdir to the top level, A makes paths absolute
2191f110e0Safresh1use strict;
2291f110e0Safresh1use warnings;
2391f110e0Safresh1use Config;
2491f110e0Safresh1use File::Path 'rmtree';
2591f110e0Safresh1use Cwd;
266fb12b70Safresh1use IPC::Cmd qw(can_run);
2791f110e0Safresh1
286fb12b70Safresh1if ($Config{'usecrosscompile'} && !can_run($Config{'cc'})) {
296fb12b70Safresh1    skip_all("compiler not available (cross-compiling)");
306fb12b70Safresh1} else {
3191f110e0Safresh1    plan(tests => 1);
326fb12b70Safresh1}
3391f110e0Safresh1
3491f110e0Safresh1my $VERBOSE = grep {$_ eq '-v'} @ARGV;
3591f110e0Safresh1
3691f110e0Safresh1ok(try_compile_and_link(<<'CODE'));
3791f110e0Safresh1#include "EXTERN.h"
3891f110e0Safresh1#include "perl.h"
3991f110e0Safresh1#include "XSUB.h"
4091f110e0Safresh1
4191f110e0Safresh1int main(int argc, char **argv) {
4291f110e0Safresh1  return 0;
4391f110e0Safresh1}
4491f110e0Safresh1CODE
4591f110e0Safresh1
4691f110e0Safresh1
4791f110e0Safresh1# from Time::HiRes's Makefile.PL with minor modifications
4891f110e0Safresh1sub try_compile_and_link {
4991f110e0Safresh1    my ($c, %args) = @_;
5091f110e0Safresh1
5191f110e0Safresh1    my $ld_exeext = ($^O eq 'cygwin' || $^O eq 'MSWin32' ||
5291f110e0Safresh1                 $^O eq 'os2' && $Config{ldflags} =~ /-Zexe\b/) ? '.exe' :
5391f110e0Safresh1                (($^O eq 'vos') ? $Config{exe_ext} : '');
5491f110e0Safresh1
5591f110e0Safresh1    my ($ok) = 0;
5691f110e0Safresh1    my $tempdir = tempfile();
5791f110e0Safresh1    my $cwd = getcwd();
5891f110e0Safresh1    mkdir $tempdir;
5991f110e0Safresh1    chdir $tempdir;
6091f110e0Safresh1    my ($tmp) = "temp";
6191f110e0Safresh1
6291f110e0Safresh1    my $obj_ext = $Config{obj_ext} || ".o";
6391f110e0Safresh1
6491f110e0Safresh1    if (open(my $tmpc, ">$tmp.c")) {
6591f110e0Safresh1	print $tmpc $c;
6691f110e0Safresh1	unless (close($tmpc)) {
6791f110e0Safresh1	    chdir($cwd);
6891f110e0Safresh1	    rmtree($tempdir);
6991f110e0Safresh1	    warn "Failing closing code file: $!\n" if $VERBOSE;
7091f110e0Safresh1	    return 0;
7191f110e0Safresh1	}
7291f110e0Safresh1
735759b3d2Safresh1	my $COREincdir =
745759b3d2Safresh1	    File::Spec->catdir(File::Spec->updir, File::Spec->updir);
7591f110e0Safresh1
7691f110e0Safresh1	my $ccflags = $Config{'ccflags'} . ' ' . "-I$COREincdir"
7791f110e0Safresh1	 . ' -DPERL_NO_INLINE_FUNCTIONS';
7891f110e0Safresh1
7991f110e0Safresh1	if ($^O eq "MSWin32") {
80*5486feefSafresh1	    $ccflags .= " -I../../win32 -I../../win32/include "
81*5486feefSafresh1             . "-I../../win32/full";
8291f110e0Safresh1	}
8391f110e0Safresh1
8491f110e0Safresh1	my $libs = '';
8591f110e0Safresh1
8691f110e0Safresh1	# Include libs to be sure of linking against bufferoverflowU.lib for
8791f110e0Safresh1	# the SDK2003 compiler on Windows. See win32/Makefile for more details.
8891f110e0Safresh1	if ($^O eq "MSWin32" && $Config{cc} =~ /\bcl\b/i) {
8991f110e0Safresh1	    $libs = " /link $Config{'libs'}";
9091f110e0Safresh1	}
9191f110e0Safresh1
9291f110e0Safresh1	my $null = File::Spec->devnull;
9391f110e0Safresh1
9491f110e0Safresh1	my $errornull = $VERBOSE ? '' : ">$null 2>$null";
9591f110e0Safresh1
9691f110e0Safresh1	# Darwin g++ 4.2.1 is fussy and demands a space.
9791f110e0Safresh1	# FreeBSD g++ 4.2.1 does not.
9891f110e0Safresh1	# We do not know the reaction of either to the presence of brown M&Ms.
9991f110e0Safresh1	my $out_opt = "-o ";
10091f110e0Safresh1	if ($^O eq "MSWin32" && $Config{cc} =~ /\bcl\b/i) {
10191f110e0Safresh1	    $out_opt = "/Fe";
10291f110e0Safresh1	}
10391f110e0Safresh1
10491f110e0Safresh1	my $tmp_exe = "$tmp$ld_exeext";
10591f110e0Safresh1
10691f110e0Safresh1        my $cccmd = "$Config{'cc'} $out_opt$tmp_exe $ccflags $tmp.c $libs $errornull";
10791f110e0Safresh1
10891f110e0Safresh1	if ($^O eq 'VMS') {
109*5486feefSafresh1            $cccmd = "$Config{'cc'} $Config{'ccflags'}/include=($COREincdir) $tmp.c";
11091f110e0Safresh1        }
11191f110e0Safresh1
11291f110e0Safresh1       if ($^O eq 'VMS') {
11391f110e0Safresh1	    open( my $cmdfile, ">$tmp.com" );
11491f110e0Safresh1	    print $cmdfile "\$ SET MESSAGE/NOFACILITY/NOSEVERITY/NOIDENT/NOTEXT\n";
11591f110e0Safresh1	    print $cmdfile "\$ $cccmd\n";
11691f110e0Safresh1	    print $cmdfile "\$ IF \$SEVERITY .NE. 1 THEN EXIT 44\n"; # escalate
11791f110e0Safresh1	    close $cmdfile;
11891f110e0Safresh1	    system("\@ $tmp.com");
11991f110e0Safresh1	    $ok = $?==0;
12091f110e0Safresh1	    chdir($cwd);
12191f110e0Safresh1	    rmtree($tempdir);
12291f110e0Safresh1        }
12391f110e0Safresh1        else
12491f110e0Safresh1        {
12591f110e0Safresh1	    printf "cccmd = $cccmd\n" if $VERBOSE;
12691f110e0Safresh1	    my $res = system($cccmd);
12791f110e0Safresh1	    $ok = defined($res) && $res == 0 && -s $tmp_exe && -x _;
12891f110e0Safresh1
12991f110e0Safresh1	    chdir($cwd);
13091f110e0Safresh1	    rmtree($tempdir);
13191f110e0Safresh1        }
13291f110e0Safresh1    }
13391f110e0Safresh1
13491f110e0Safresh1    return $ok;
13591f110e0Safresh1}
136