Building C and C++ libraries with Perl

24
Building C/C++ libraries with Perl Alberto Manuel Brand˜ ao Sim˜ oes [email protected] YAPC::EU::2012 AlbertoSim˜oes Building C/C++ libraries with Perl

description

Presentation from YAPC::EU::2012 describing my toolchain to compile C and C++ applications and libraries with Perl.

Transcript of Building C and C++ libraries with Perl

Page 1: Building C and C++ libraries with Perl

Building C/C++ libraries with Perl

Alberto Manuel Brandao [email protected]

YAPC::EU::2012

Alberto Simoes Building C/C++ libraries with Perl

Page 2: Building C and C++ libraries with Perl

Disclaimer

This is my point of view;

This is not the best approach. . .

. . . surely . . .

. . . just not sure what it is!

This is the way I decided to go. . .

And it is working (so far!)

Alberto Simoes Building C/C++ libraries with Perl

Page 3: Building C and C++ libraries with Perl

Standard Source Packaging

Perl modules are not a problem.

C/C++ libraries or apps are usually:

bundled with a autoconf script;bundled with a cmake;

Alberto Simoes Building C/C++ libraries with Perl

Page 4: Building C and C++ libraries with Perl

AutoTools

The autotools are the most used, but:

not portable (check Windows);a mess:Perl script that processes a DSL thatincludes references to M4 macros,and Shell snippets, and generate ashell script. It also interpolatesmakefiles, and other crazy stuff.

Most macros are copy & paste fromother projects

Few people really understand them

Alberto Simoes Building C/C++ libraries with Perl

Page 5: Building C and C++ libraries with Perl

AutoTools Dependencies

To use AutoTools we need:

AutoConf;AutoMake;LibTool;Perl;shell;

I know end-users should only require sh. Is that really true?

Alberto Simoes Building C/C++ libraries with Perl

Page 6: Building C and C++ libraries with Perl

Hey, u said Perl?

Page 7: Building C and C++ libraries with Perl

Use Perl as a Build System

Use Perl as a Build System.

What are the (my) options?

ExtUtils::MakeMaker;Module::Build;

ExtUtils::MakeMaker is not suitable:

Constructing a Makefile string is error prone;Most system detection needs to be defined at configure time;

Module::Build is easy to subclass:

Gives all the power of Perl (that can be bad);Easier to develop and debug.

Alberto Simoes Building C/C++ libraries with Perl

Page 8: Building C and C++ libraries with Perl

Use Perl as a Build System

Use Perl as a Build System.

What are the (my) options?

ExtUtils::MakeMaker;Module::Build;

ExtUtils::MakeMaker is not suitable:

Constructing a Makefile string is error prone;Most system detection needs to be defined at configure time;

Module::Build is easy to subclass:

Gives all the power of Perl (that can be bad);Easier to develop and debug.

Alberto Simoes Building C/C++ libraries with Perl

Page 9: Building C and C++ libraries with Perl

What more do I need?

ExtUtils::CBuilderSomething that helps compiling C/C++ code

ExtUtils::ParseXSSomething that helps me parse XS files

ExtUtils::MkbootstrapSomething to create DynaLoader bootstrapfiles

ExtUtils::PkgConfig or PkgConfigSomething to detect libs that ship a .pc file

Config::AutoConfSomething that helps me detecting otherlibraries. . .

ExtUtils::LibBuilderSomething that knows how to link a standardlibrary

Alberto Simoes Building C/C++ libraries with Perl

Page 10: Building C and C++ libraries with Perl

The Nuts and Bolts

Alberto Simoes Building C/C++ libraries with Perl

Page 11: Building C and C++ libraries with Perl

Case Study 1

Lingua::Jspell

A Morphological Analyzer for NLP;

It is a standard C app based on ispell code;

It includes Perl bindings (through Open3 atm);

There is no real reason to bundle the app with the Perlmodule.

The build chain uses:

Module::Build;

ExtUtils::CBuilder;

ExtUtils::LibBuilder;

Config::AutoConf;

Alberto Simoes Building C/C++ libraries with Perl

Page 12: Building C and C++ libraries with Perl

Case Study 1

Lingua::Jspell

A Morphological Analyzer for NLP;

It is a standard C app based on ispell code;

It includes Perl bindings (through Open3 atm);

There is no real reason to bundle the app with the Perlmodule.

The build chain uses:

Module::Build;

ExtUtils::CBuilder;

ExtUtils::LibBuilder;

Config::AutoConf;

Alberto Simoes Building C/C++ libraries with Perl

Page 13: Building C and C++ libraries with Perl

Case Study 1

Config::AutoConf is used to:

Detect libraries and headers (in Build.PL):

� �Config : : AutoConf−>check_header ( ”n cu r s e s . h ” ) ;Config : : AutoConf−>check_lib ( ”n cu r s e s ” , ”tgo to ” ) ;� �

More details on the Build.PL script in the article.

Alberto Simoes Building C/C++ libraries with Perl

Page 14: Building C and C++ libraries with Perl

Case Study 1

I subclass Builder redefining methods:� �sub ACTION_code {

my $self = s h i f t ;

# c r e a t e the L i bBu i l d e r o b j e c t and cache i t$self−>notes ( libbuilder => ExtUtils : : LibBuilder−>new ) ;

# d i s p a t c h e v e r y needed a c t i o n$self−>dispatch ( ” c r e a t e b l i b f o l d e r s ” ) ;$self−>dispatch ( ”c rea te manpages ” ) ;$self−>dispatch ( ”c r e a t e y a c c ” ) ;$self−>dispatch ( ”c r e a t e o b j e c t s ” ) ;$self−>dispatch ( ” c r e a t e l i b r a r y ” ) ;$self−>dispatch ( ” c r e a t e b i n a r i e s ” ) ;

# and now , c a l l s u p e r c l a s s .$self−>SUPER : : ACTION_code ;

}� �Alberto Simoes Building C/C++ libraries with Perl

Page 15: Building C and C++ libraries with Perl

Case Study 1

The create yacc action also uses Config::AutoConf� �sub ACTION_create_yacc {

my $self = s h i f t ;

my $ytabc = ’ s r c /y . tab . c ’ ;my $parsey = ’ s r c / pa r s e . y ’ ;

r e t u r n i f $self−>up_to_date ( $parsey , $ytabc ) ;

my $yacc = Config : : AutoConf−>check_prog ( ”yacc ” ,”b i s on ”) ;

i f ( $yacc ) {‘ $yacc −o $ytabc $parsey ‘ ;

}}� �

Alberto Simoes Building C/C++ libraries with Perl

Page 16: Building C and C++ libraries with Perl

Case Study 1

Build object files (plain ExtUtils::CBuilder usage):� �sub ACTION_create_objects {

my $self = s h i f t ;

my $cbuilder = $self−>cbuilder ;my $c_files = $self−>rscan_dir ( ’ s r c ’ , qr /\ . c$ / ) ;my $xtr_comp_flags = ”−g ”. $self−>notes ( ’ c c u r s e s ’ ) ;

f o r my $file ( @$c_files ) {my $object = $file =˜ s /\ . c / . o/r ;nex t i f $self−>up_to_date ( $file , $object ) ;

$cbuilder−>compile ( object_file => $object ,source => $file ,include_dirs => [ ”s r c ”] ,extra_compiler_flags =>

$xtr_comp_flags ) ;}

}� �Alberto Simoes Building C/C++ libraries with Perl

Page 17: Building C and C++ libraries with Perl

Case Study 1

And the main stuff, build a standard library� �sub ACTION_create_library {

my $self = s h i f t ;my $libbuilder = $self−>notes ( ’ l i b b u i l d e r ’ ) ;. . .# d e f i n e the l i n k e r f l a g smy $xlinkerflags = $self−>notes ( ’ l c u r s e s ’ )

. $self−>notes ( ’ c c u r s e s ’ ) ;i f ($ˆO =˜ /darwin /) {

$xlinkerflags .= ” − i n s t a l l n am e $ l i b p a t h ” }

# l i n k i f the l i b r a r y i s not up to datei f ( ! $self−>up_to_date (\ @objs , $libfile ) ) {

$libbuilder−> l i n k ( module_name => ’ l i b j s p e l l ’ ,extra_linker_flags => $xlinkerflags ,objects => \@objects ,lib_file => $libfile ) ;

}. . .� �

Alberto Simoes Building C/C++ libraries with Perl

Page 18: Building C and C++ libraries with Perl

Case Study 1

And build the C binaries.� �sub ACTION_create_binaries {

my $self = s h i f t ;my $libbuilder = $self−>notes ( ’ l i b b u i l d e r ’ ) ;. . .# d e f i n e f l a g smy $extralinkerflags = $self−>notes ( ’ l c u r s e s ’ )

. $self−>notes ( ’ c c u r s e s ’ ) ;. . .# i f needed , l i n k the e x e c u t a b l ei f ( ! $self−>up_to_date ( $object , $exe_file ) ) {

$libbuilder−>link_executable (exe_file => $exe_file ,objects => [ $object ] ,extra_linker_flags =>

”−Ls r c − l j s p e l l $ e x t r a l i n k e r f l a g s ” ) ;}. . .� �

Alberto Simoes Building C/C++ libraries with Perl

Page 19: Building C and C++ libraries with Perl

Case Study 1

Work out a testing environment.� �sub ACTION_test {

my $self = s h i f t ;

i f ($ˆO =˜ /mswin32/i ) {$ENV{PATH} = $self−>blib . ”/ u s r l i b ; $ENV{PATH} ”;

}e l s i f ($ˆO =˜ /darwin/i ) {

$ENV{DYLD_LIBRARY_PATH} = $self−>blib . ”/ u s r l i b ” ;}e l s i f ($ˆO =˜/linux | bsd | sun | sol | dragon | hpux | irix/i ) {

$ENV{LD_LIBRARY_PATH} = $self−>blib . ”/ u s r l i b ” ;}e l s i f ($ˆO =˜ /aix/i ) {my $oldlibpath = $ENV{LIBPATH} | | ’ / l i b : / u s r / l i b ’ ;$ENV{LIBPATH} = $self−>blib . ”/ u s r l i b : $ o l d l i b p a t h ”;

}$self−>SUPER : : ACTION_test

}� �Alberto Simoes Building C/C++ libraries with Perl

Page 20: Building C and C++ libraries with Perl

Case Study 2

Lingua::Identify::CLD

Interface to Google’s Compact Language Detector;

It bundles a standard C++ library;

It includes Perl bindings (through XS);

The build chain uses:

Module::Build;

ExtUtils::CBuilder;

ExtUtils::LibBuilder;

Config::AutoConf;

ExtUtils::ParseXS;

ExtUtils::Mkbootstrap;

Alberto Simoes Building C/C++ libraries with Perl

Page 21: Building C and C++ libraries with Perl

Case Study 2

Lingua::Identify::CLD

Interface to Google’s Compact Language Detector;

It bundles a standard C++ library;

It includes Perl bindings (through XS);

The build chain uses:

Module::Build;

ExtUtils::CBuilder;

ExtUtils::LibBuilder;

Config::AutoConf;

ExtUtils::ParseXS;

ExtUtils::Mkbootstrap;

Alberto Simoes Building C/C++ libraries with Perl

Page 22: Building C and C++ libraries with Perl

Case Study 2

Compiling XS code as... standard XS code (mostly)� �sub ACTION_compile_xscode {

. . .# c r e a t e CLD. cc from CLD. xsExtUtils : : ParseXS : : process_file ( . . . ) ;

# c r e a t e CLD. o from CLD. cc$cbuilder−>compile ( . . . ) ;

# Crea te . bs boo t s t r a p f i l e , needed by Dyna loader .ExtUtils : : Mkbootstrap : : Mkbootstrap ( . . . ) ;

# s e t l i n k e r f l a g smy $xlinkerflags = ”−Lcld−s r c − l c l d − l s t d c++”;$xlinkerflags .= ” − l g c c s ” i f $ˆO eq ’ ne tbsd ’ ;

# l i n k$cbuilder−> l i n k ( . . . ) ;� �

Alberto Simoes Building C/C++ libraries with Perl

Page 23: Building C and C++ libraries with Perl

Concluding

It works!

The process is similar for all modules;

Then, this can be generalized in a module;

Works on UNIX systems;

Works on Strawberry Win32;

Alberto Simoes Building C/C++ libraries with Perl

Page 24: Building C and C++ libraries with Perl

Thank you!

Alberto Simoes Building C/C++ libraries with Perl