1package Minilla::Profile::XS;
2use strict;
3use warnings;
4use utf8;
5use parent qw(Minilla::Profile::ModuleBuild);
6
7use File::Spec::Functions qw(catfile);
8use File::Basename qw(dirname);
9use Data::Section::Simple qw(get_data_section);
10
11use Minilla::Gitignore;
12use Minilla::Util qw(require_optional);
13use Minilla::Logger;
14
15sub module_pm_src {
16    join("\n",
17        'use XSLoader;',
18        'XSLoader::load(__PACKAGE__, $VERSION);'
19    );
20}
21
22sub generate {
23    my $self = shift;
24
25    require_optional( 'Devel/PPPort.pm', 'PPPort is required for XS support' );
26
27    $self->render('Module.pm', catfile('lib', $self->path));
28    $self->render('Module.xs', catfile('lib', dirname($self->path), $self->suffix . '.xs'));
29
30    my $ppport = catfile(dirname(catfile('lib', $self->path)), 'ppport.h');
31    infof("Writing ppport.h: %s\n", $ppport);
32    Devel::PPPort::WriteFile($ppport);
33
34    $self->render('Changes');
35    $self->render('t/00_compile.t');
36    $self->render('t/01_simple.t');
37    $self->render('.travis.yml');
38
39    $self->render('.gitignore');
40    my $gi = Minilla::Gitignore->load('.gitignore');
41    $gi->add(catfile('lib', dirname($self->path), $self->suffix . '.c'));
42    $gi->add("!$ppport"); # Import ppport.h!
43    $gi->save('.gitignore');
44
45    $self->write_file('LICENSE', Minilla::License::Perl_5->new(
46        holder => sprintf('%s <%s>', $self->author, $self->email)
47    )->fulltext);
48
49    $self->render('cpanfile');
50}
51
521;
53__DATA__
54
55@@ t/01_simple.t
56use strict;
57use Test::More;
58
59use <% $module %>;
60
61is(<% $module %>::hello(), 'Hello, world!');
62
63done_testing;
64
65@@ Module.xs
66#ifdef __cplusplus
67extern "C" {
68#endif
69
70#define PERL_NO_GET_CONTEXT /* we want efficiency */
71#include <EXTERN.h>
72#include <perl.h>
73#include <XSUB.h>
74
75#ifdef __cplusplus
76} /* extern "C" */
77#endif
78
79#define NEED_newSVpvn_flags
80#include "ppport.h"
81
82MODULE = <% $module %>    PACKAGE = <% $module %>
83
84PROTOTYPES: DISABLE
85
86void
87hello()
88CODE:
89{
90    ST(0) = newSVpvs_flags("Hello, world!", SVs_TEMP);
91}
92