09 January 2019

Perl XS

System: Slackware Linux (version 14.0)
CPUs: Intel(R) Atom(TM) CPU N270 @1.60GHz

I found J. Keiser's article on Perl and C++ in an archive, and created
a Github repository, including also D. Roehrich's perlobject.map file.

Starting with Perl 5.16, you can embed typemaps into your XS code
instead of or in addition to typemaps in a separate file.

The -C++ flag has been a no-op for many versions of perl, at least
as far back as perl5.003_07.

sh-4.2$ perl --version | grep version
This is perl 5, version 16, subversion 1 (v5.16.1) built for i486-linux-thread-multi
sh-4.2$ cd /tmp
sh-4.2$ h2xs -A -n MyPackage
Defaulting to backwards compatibility with perl 5.16.1
If you intend this module to be compatible with earlier perl versions, please
specify a minimum perl version with the -b option.

Writing MyPackage/ppport.h
Writing MyPackage/lib/MyPackage.pm
Writing MyPackage/MyPackage.xs
Writing MyPackage/Makefile.PL
Writing MyPackage/README
Writing MyPackage/t/MyPackage.t
Writing MyPackage/Changes
Writing MyPackage/MANIFEST

Modify MyPackage.xs as follows.

#ifdef __cplusplus
extern "C" {

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#ifdef __cplusplus

#include "ppport.h"

MODULE = MyPackage         PACKAGE = MyPackage


One needs the repository's perlobject.map file and to create a typemap file.

sh-4.2$ cp perlobject.map MyPackage
sh-4.2$ cat << EOF > MyPackage/typemap
> MyClass *         O_OBJECT

Modify Makefile.PL as follows.

use 5.016001;
use ExtUtils::MakeMaker;

my $CC = 'g++';
my $LD = '$(CC)';

# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
    NAME              => 'MyPackage',
    VERSION_FROM      => 'lib/MyPackage.pm', # finds $VERSION
    PREREQ_PM         => {}, # e.g., Module::Name => 1.1
    ($] >= 5.005 ?     ## Add these new keywords supported since 5.005
      (ABSTRACT_FROM  => 'lib/MyPackage.pm', # retrieve abstract from module
       AUTHOR         => 'Eric Lindblad <eric@slackware.lan>') : ()),
    LIBS              => [''], # e.g., '-lm'
    DEFINE            => '', # e.g., '-DHAVE_SOMETHING'
    CC                    => $CC,
    LD                     => $LD,

    INC               => '-I.', # e.g., '-I. -I/usr/include/other'
             # Un-comment this if you add C files to link with later:
    # OBJECT            => '$(O_FILES)', # link all the C files too
    TYPEMAPS        => ['perlobject.map'],

sh-4.2$ cd MyPackage
sh-4.2$ perl Makefile.PL
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for MyPackage
Writing MYMETA.yml and MYMETA.json
sh-4.2$ make test
Running Mkbootstrap for MyPackage ()
chmod 644 "MyPackage.bs"
"/usr/bin/perl5.16.1" -MExtUtils::Command::MM -e 'cp_nonempty' -- MyPackage.bs blib/arch/auto/MyPackage/MyPackage.bs 644
"/usr/bin/perl5.16.1" "/usr/local/share/perl5/ExtUtils/xsubpp"  -typemap '/usr/share/perl5/ExtUtils/typemap' -typemap '/tmp/MyPackage/perlobject.map' -typemap '/tmp/MyPackage/typemap'  MyPackage.xs > MyPackage.xsc
mv MyPackage.xsc MyPackage.c
g++ -c  -I. -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -march=i486 -mtune=i686   -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" -fPIC "-I/usr/lib/perl5/CORE"   MyPackage.c
rm -f blib/arch/auto/MyPackage/MyPackage.so
g++  -shared -O2 -march=i486 -mtune=i686 -L/usr/local/lib -fstack-protector  MyPackage.o  -o blib/arch/auto/MyPackage/MyPackage.so  \

chmod 755 blib/arch/auto/MyPackage/MyPackage.so
cp lib/MyPackage.pm blib/lib/MyPackage.pm
PERL_DL_NONLAZY=1 "/usr/bin/perl5.16.1" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/MyPackage.t .. ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs ( 0.10 usr  0.01 sys +  0.34 cusr  0.03 csys =  0.48 CPU)
Result: PASS

sh-4.2$ rm -f *.bs *.c *.json *.o *.yml
sh-4.2$ rm Makefile pm_to_blib
sh-4.2$ rm -fr blib
sh-4.2$ exit

For J. Keiser's examples in sections 1 and 2.

- #include <iostream.h>
+ #include <iostream>
+ using namespace std;

Where he writes "Put this into test.pl at the bottom:" read
this as "Put this into t/MyPackage.t at the bottom:".

sh-4.2$ perl Makefile.PL


sh-4.2$ make  


sh-4.2$ cp blib/lib/*pm .
sh-4.2$ cp blib/arch/auto/MyPackage/*.so .
sh-4.2$ perl t/MyPackage.t
ok 1 - use MyPackage;
I'm constructin' my bad self ... Hi.
Destruction is a way of life for me.
sh-4.2$ rm -f *.pm *.so
sh-4.2$ exit


[   ] [   ]
[   ] [   ]