What tools can help build an XS project?
Asked Answered
D

3

7

I've recently started learning XS using perlxstut and the tutorial suggests that I create my module using the old h2xs tool to create an ExtUtils::MakeMaker-based project. However for pure Perl projects, h2xs/EUMM has long been disfavoured in favour of Module::Install, Module::Build or Dist::Zilla.

Is there a more modern way of creating XS projects? Can Module::Starter create XS projects? Can Module::Build or Dist::Zilla build XS projects? Their pod pages are silent on the matter.

On the flip side, does the criticism that was levelled at h2xs/EUMM apply to XS projects? If you need a C compiler anyway, is it reasonable to demand a make tool as well?

EDIT: I see this question answers my question about creating a project. I'd still like to know about building: is EUMM the only option, or are Module::Build and Dist::Zilla also capable of building XS?

Dahliadahlstrom answered 28/8, 2010 at 8:52 Comment(0)
D
4

It turns out that Module::Build is perfectly capable of compiling XS. Here is a complete Build.PL I managed to scrape together:

use strict;
use Module::Build;

my $build = Module::Build->new(
    module_name  => 'Chocolate::Belgian',
    dynamic_config => 1,
    license      => 'perl',
    requires     => {
        'Module::Build' => '0.19', # xs
        'Test::More' => 0,
    },
    extra_compiler_flags => '-Iinclude',
    extra_linker_flags   => '',
    c_source     => 'src',
    needs_compiler => 1,
    xs_files     => {
        './Belgian.xs' => 'lib/Chocolate/Belgian.xs',
    },

   );

$build->create_build_script;

This will build a distribution with .h include files (such as ppport.h) in the include/ directory, .c source files in the src/ directory, and an .xs file corresponding to package Chocolate::Belgian in the project base directory.

extra_compiler_flags corresponds to make CCFLAGS, while extra_linker_flags corresponds to LIBS (so you might want -lm there to link the C math library).

Dahliadahlstrom answered 28/8, 2010 at 8:52 Comment(3)
Since you were asking for feedback in a comment: This looks fine after a quick inspection. Nits: Maybe add a dependency on ExtUtils::CBuilder (needs_compiler might be doing this already). Are you quite certain you need dynamic_config: 1? I bet you don't. Furthermore, you may want to add Module::Build to configure_requires instead of requires. I believe it automatically adds a dependency on the most recent version if it doesn't find it at all. Try removing that line, running "./Build dist" and inspecting the generated META.yml/META.json for mention of Module::Build.Zone
@tsee: thanks very much for your review. I've made it community wiki, so you can put in any changes you want if you like.Dahliadahlstrom
Hmmm... The Module::Build::API page says that needs_compiler is available after M::B version .36, and that it is set to true automatically if c_source exists or xs code is found somewhere. If true, it automatically adds ExtUtils::CBuilder as a build_requires item.Intubate
F
2

Dist::Zilla is not a replacement for EUMM or Module::Build, what it will do is generate a Makefile.Pl (etc) for you, I would not be surprised to hear that it can't do this for an XS project, but there are ways of managing your own for a dzil project. It can work with whatever Makefile.Pl it is provided with (or Build.pl).

So my answer on the Dist::Zilla part of your question is, Dist::Zilla does not fill that role in a project.

Fagan answered 28/8, 2010 at 11:41 Comment(1)
Thanks for this, it has clarified dzil greatly in my mind. Investigating further identifies Dist::Zilla::Plugin::MakeMaker::Awesome which claims partial XS capability.Dahliadahlstrom
Z
1

I always just use some fairly simple XS distribution as a starting point. h2xs can do some of the XS generation by parsing a header, but most of the time, I found that too limited to be useful.

If you're planning to wrap C++, you may want to take a look at Module::Build::WithXSpp.

Zone answered 28/8, 2010 at 18:25 Comment(4)
Thanks for your answer. What do you use to build your distribution?Dahliadahlstrom
I started out using MakeMaker since that seemed the simplest. Nowadays, I usually use Module::Build (which, I'd say, has a bit more of a learnig curve for XS/C stuff) because I feel it gives me more flexibility without having to hack Makefiles. It was also fairly easy to extend to do the crazy magic in Module::Build::WithXSpp.Zone
could you provide a Module::Build example for XS or review the one in my answer? I'm new to this and I'm trying to find best practices for creating XS projects.Dahliadahlstrom
I'll point to only modules that I know because I'm too lazy to do much research. That obviously usually means my modules. They don't necessarily reflect best practices. If you plan to use XS++, then this is as simple as it gets: search.cpan.org/~smueller/Math-ThinPlateSpline-0.05 For plain XS, I have no utterly vanilla Build.PL. This is a complicated example, but you can simply remove all the special logic: search.cpan.org/~smueller/SOOT-0.09 Here's an example of using Module::Install (from Daisuke Maki): search.cpan.org/~dmaki/ZeroMQ-0.02Zone

© 2022 - 2024 — McMap. All rights reserved.