Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Perl's ExtUtils::MakeMaker, how can I compile an executable using the same settings as my XS module?

Given a Perl XS module using a C library, assume there is a Makefile.PL that is set up correctly so that all header and library locations, compiler and linker flags etc work correctly.

Now, let's say I want to include a small C program with said XS module that uses the same underlying C library. What is the correct, platform independent way to specify the target executable so that it gets built with the same settings and flags?

If I do the following

sub MY::postamble {
    return <<FRAG;
target$Config{exe_ext}: target$Config{obj_ext}

target$Config{obj_ext}: target.c

FRAG
}

I don't get those include locations, lists of libraries etc I set up in the arguments to WriteMakefile. If I start writing rules manually, I have to account for at least make, dmake, and nmake. I can't figure out a straightforward way to specify libraries to link against if use ExtUtils::CBuilder.

I must be missing something. I would appreciate it if you can point it out.

like image 954
Sinan Ünür Avatar asked Apr 18 '14 20:04

Sinan Ünür


2 Answers

EU::MM does not know how to create executable. If you need to do this, you will need to take into account various compiler toolchains. I've done this at least once, but I don't claim it's completely portable (just portable enough).

A long term solution would be a proper compilation framework, I've been working on that but it's fairly non-trivial.

like image 165
Leon Timmermans Avatar answered Oct 15 '22 12:10

Leon Timmermans


You might want to look at Dist::Zilla. I use it because I can never remember how to do this either. With a fairly small and boilerplaty dist.ini file to tell it which plugins to use, it'll generate the all the right building systems for you, including the whole of the necessary Makefile.PL. Think of it it as a makefile-maker-maker. I use it for one of my smaller and more broken C-based CPAN modules: https://github.com/morungos/p5-Algorithm-Diff-Fast, which doesn't work especially well as module but has a decent build. The magic needed is in the inc/DiffMakeMaker.pm.

However, the short answer is to look at the extra settings this component drops into Makefile.PL:

LIBS => [''],
INC => '-I.',
OBJECT => '$(O_FILES)', # link all the C files too

Just adding these options into your Makefile.PL should get it to build a Makefile that handles C as well as XS, and links them together for the Perl.

Because, although EU::MM doesn't know how to create an executable, most of what it does it to make a Makefile. And that's more than happy to make what's needed to glue the C and Perl together properly.

like image 28
Stuart Watt Avatar answered Oct 15 '22 13:10

Stuart Watt