File: 40-autodetect-loadable-object.t

package info (click to toggle)
libextutils-builder-compiler-perl 0.032-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 252 kB
  • sloc: perl: 1,252; makefile: 2
file content (109 lines) | stat: -rw-r--r-- 2,544 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#! perl

use strict;
use warnings;

use Test::More 0.89;

use Config;
plan(skip_all => 'No dynamic linking') if not $Config{usedl};
use Cwd 'getcwd';
use ExtUtils::Builder::Planner 0.007;
use File::Basename qw/basename dirname/;
use File::Spec::Functions qw/catfile/;
use File::Temp 'tempdir';

my $olddir = getcwd;
my $dir = tempdir(CLEANUP => 1);

chdir $dir;

my $planner = ExtUtils::Builder::Planner->new;
$planner->load_extension('ExtUtils::Builder::AutoDetect::C', undef,
	profile => '@Perl', type => 'loadable-object',
);

mkdir 't';
my $source_file = File::Spec->catfile('t', 'compilet.c');
{
	open my $fh, '>', $source_file or die "Can't create $source_file: $!";
	my $content = <<END;
#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

XS(exported) {
#ifdef dVAR
	dVAR;
#endif
	dXSARGS;

	PERL_UNUSED_VAR(cv); /* -W */
	PERL_UNUSED_VAR(items); /* -W */

	XSRETURN_IV(42);
}

#ifndef XS_EXTERNAL
#define XS_EXTERNAL(foo) XS(foo)
#endif

XS_EXTERNAL(boot_compilet) {
#ifdef dVAR
	dVAR;
#endif
	dXSARGS;

	PERL_UNUSED_VAR(cv); /* -W */
	PERL_UNUSED_VAR(items); /* -W */

	newXS("main::exported", exported, __FILE__);
}

END
	print $fh $content or die "Can't write to $source_file: $!";
	close $fh or die "Can't close $source_file: $!";
}
ok(-e $source_file, "source file '$source_file' created");

my $object_file = catfile(dirname($source_file), basename($source_file, '.c') . $Config{obj_ext});
$planner->compile($source_file, $object_file);

my $lib_file = catfile(dirname($source_file), basename($object_file, $Config{obj_ext}) . ".$Config{dlext}");
$planner->link([$object_file], $lib_file, dl_name => 'compilet');

my $plan = $planner->materialize;
ok $plan;

ok eval { $plan->run($lib_file, logger => \&note); 1 } or diag "Got exception: $@";

ok(-e $object_file, "object file $object_file has been created");
ok(-e $lib_file, "lib file $lib_file has been created");

require DynaLoader;
my $libref = DynaLoader::dl_load_file($lib_file, 0);
ok($libref, 'libref is defined');
my $symref = DynaLoader::dl_find_symbol($libref, "boot_compilet");
ok($symref, 'symref is defined');

my $boot_compilet = DynaLoader::dl_install_xsub("boot_compilet", $symref, $source_file);
is(eval { boot_compilet(); 1 }, 1, 'compilet lives');

is(eval { exported() }, 42, 'exported returns 42');

END { 
	for ($source_file, $object_file, $lib_file) {
		next if not defined;
		1 while unlink;
	}
	if ($^O eq 'VMS') {
		1 while unlink 'COMPILET.LIS';
		1 while unlink 'COMPILET.OPT';
	}
}

chdir $olddir;

done_testing;