Building C and C++ libraries with Perl
-
Upload
alberto-simoes -
Category
Technology
-
view
805 -
download
1
description
Transcript of 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
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
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
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
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
Hey, u said 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
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
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
The Nuts and Bolts
Alberto Simoes Building C/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
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
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
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
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
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
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
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
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
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
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
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
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
Thank you!
Alberto Simoes Building C/C++ libraries with Perl