Home / Alt manpages / perlxs(1)

  • perlxs(1)
  • User command
  • linux

Build and Check a Small Perl XS Extension with xsubpp

You will turn a short XS definition into C glue that Perl can call. The example exposes a C-style function named twice, then checks that xsubpp generated the expected binding. It stops before linking or installing anything, so it is suitable for a quick inspection on a development machine.

Before you start

You need Perl, the Perl development documentation, a C compiler and xsubpp. This machine has Perl 5.38.2, package perl-doc version 5.38.2-3.2ubuntu0.6, and xsubpp version 3.51. The commands below do not need root privileges and do not alter system files. Allow about 10 minutes for this small check; a real extension also needs a C library, build files and tests.

XS is an interface description language for connecting Perl code to C code. An XSUB is its basic unit. xsubpp reads XSUB declarations and emits the stack handling, conversions and registration code needed by Perl. Those conversions are controlled by typemaps. The default typemap covers common types such as double, but a library-specific structure may need a supplementary typemap.

Checkpoint 1: confirm the local toolchain

Check the interpreter and compiler before debugging an XS file. The version matters when an extension depends on a newer XS feature.

perl -v
xsubpp -v
perl -V:make

Expected output includes Perl v5.38.2, an xsubpp version line, and the make program configured for this Perl. If xsubpp is missing, install the distribution's Perl development package using your normal package-management process. That is an administrative change, so confirm the package name for your distribution before using sudo.

Checkpoint 2: describe one XSUB

Save the following as Demo/Double.xs inside a temporary extension directory. The first line selects the module and package. The return type and XSUB name are deliberately on separate lines, which is the robust layout described by perlxs(1).

MODULE = Demo::Double  PACKAGE = Demo::Double

double
twice(value)
    double value
  CODE:
    RETVAL = value * 2;
  OUTPUT:
    RETVAL

This example uses a CODE: section because the C expression is supplied by the author rather than being a direct call to an existing C function. RETVAL is supplied by xsubpp for a non-void XSUB. Naming it in OUTPUT: tells the generated wrapper to return it to Perl. The double argument and return value use the standard typemap.

Do not add a C pointer merely because the underlying library uses one. In XS, * and & describe different semantics: a pointer may be read as input, while an address-style parameter can be used as an output location. Choose the declaration to match the C function's contract, then read perlxstypemap(1) before mapping a structure or ownership-sensitive pointer.

Checkpoint 3: generate and inspect the C

Run xsubpp from the directory containing the file. The -output option makes the result explicit, while -prototypes asks for Perl prototypes and -nolinenumbers keeps this inspection easier to read.

xsubpp -prototypes -nolinenumbers \
  -output Double.c Demo/Double.xs

There is no normal success message. A successful run creates Double.c. Verify the generated wrapper rather than trusting an empty exit status:

test -s Double.c
grep -n 'XS_Demo__Double_twice\|RETVAL = value \* 2' Double.c

You should see a generated function containing the multiplication and a registration entry for Demo::Double::twice. The C file is generated output, not the source of truth. Edit the XS file and generate it again.

How a full extension continues

Generating C alone does not produce a usable Perl module. A normal extension also has a Perl bootstrap module, commonly using XSLoader or DynaLoader, plus a Makefile.PL using ExtUtils::MakeMaker. The Makefile runs xsubpp, compiles the C wrapper, links it as a loadable library and installs it into the selected Perl library tree. The h2xs utility can scaffold that layout, while perlxstut(1) walks through the complete build and test process.

Keep the generated files in a disposable build directory until the binding has tests. Building does not require elevated privileges when the directory belongs to you. Installation into a system Perl directory does require administrative privileges and can affect every user of that interpreter. Prefer a local install path or a package-managed deployment. To undo this experiment, remove the temporary extension directory; do not delete files from a shared Perl library directory by hand.

Common traps

  • Unexpected arguments: the first two XSUB lines describe the return type and call signature. A misplaced type can make the generated C fail in a confusing way.
  • Missing return values: a value assigned in CODE: is not automatically returned. Put it in OUTPUT:, or use PPCODE: when you are explicitly pushing several values onto Perl's stack.
  • Unknown C types: a default typemap may not know how to convert a library-specific type. Add or select a typemap instead of guessing at casts.
  • Version surprises: the installed xsubpp reports 3.51, and this guide was checked with Perl 5.38.2. Test the extension against every Perl version you intend to support.

Done means

  • perl -v and xsubpp -v identify the toolchain you are using.
  • The XS file has a clear MODULE/PACKAGE line and a correctly typed XSUB.
  • xsubpp exits successfully and generates a non-empty C file.
  • The generated C contains the expected wrapper and return-value handling.
  • No system Perl files were changed; a full build can proceed in a disposable directory.