TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
Building C/C++ libs with Perl
1. Building C/C++ libraries with Perl
Alberto Manuel Brand˜o Sim˜es
a o
ambs@perl.pt
YAPC::EU::2012
Alberto Sim˜es
o Building C/C++ libraries with Perl
2. 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 Sim˜es
o Building C/C++ libraries with Perl
3. 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 Sim˜es
o Building C/C++ libraries with Perl
4. AutoTools
The autotools are the most used, but:
not portable (check Windows);
a mess:
Perl script that processes a DSL that
includes references to M4 macros,
and Shell snippets, and generate a
shell script. It also interpolates
makefiles, and other crazy stuff.
Most macros are copy & paste from
other projects
Few people really understand them
Alberto Sim˜es
o Building C/C++ libraries with Perl
5. 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 Sim˜es
o Building C/C++ libraries with Perl
7. 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 Sim˜es
o Building C/C++ libraries with Perl
8. 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 Sim˜es
o Building C/C++ libraries with Perl
9. What more do I need?
ExtUtils::CBuilder
Something that helps compiling C/C++ code
ExtUtils::ParseXS
Something that helps me parse XS files
ExtUtils::Mkbootstrap
Something to create DynaLoader bootstrap
files
ExtUtils::PkgConfig or PkgConfig
Something to detect libs that ship a .pc file
Config::AutoConf
Something that helps me detecting other
libraries. . .
ExtUtils::LibBuilder
Something that knows how to link a standard
library
Alberto Sim˜es
o Building C/C++ libraries with Perl
10. The Nuts and Bolts
Alberto Sim˜es
o Building C/C++ libraries with Perl
11. 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 Perl
module.
The build chain uses:
Module::Build;
ExtUtils::CBuilder;
ExtUtils::LibBuilder;
Config::AutoConf;
Alberto Sim˜es
o Building C/C++ libraries with Perl
12. 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 Perl
module.
The build chain uses:
Module::Build;
ExtUtils::CBuilder;
ExtUtils::LibBuilder;
Config::AutoConf;
Alberto Sim˜es
o Building C/C++ libraries with Perl
13. Case Study 1
Config::AutoConf is used to:
Detect libraries and headers (in Build.PL):
§ ¤
Config : : AutoConf−>check_header ( ” n c u r s e s . h ” ) ;
Config : : AutoConf−>check_lib ( ” n c u r s e s ” , ”t g o t o ” ) ;
¦ ¥
More details on the Build.PL script in the article.
Alberto Sim˜es
o Building C/C++ libraries with Perl
14. Case Study 1
I subclass Builder redefining methods:
§ ¤
sub ACTION_code {
my $self = s h i f t ;
# c r e a t e t h e L i b B u i l d e r o b j e c t and c a c h e 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 r e a t e m a n p a g e s ” ) ;
$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 Sim˜es
o Building C/C++ libraries with Perl
15. 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 . t a b . c ’ ;
my $parsey = ’ s r c / p a r s e . y ’ ;
r e t u r n i f $self−>up_to_date ( $parsey , $ytabc ) ;
my $yacc = Config : : AutoConf−>check_prog ( ”y a c c ” ,
”b i s o n ” ) ;
i f ( $yacc ) {
‘ $yacc −o $ytabc $parsey ‘ ;
}
}
¦ ¥
Alberto Sim˜es
o Building C/C++ libraries with Perl
16. 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 ;
n e x 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 Sim˜es
o Building C/C++ libraries with Perl
17. 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 s
my $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 a m e $ l i b p a t h ” }
# l i n k i f t h e l i b r a r y i s n o t up t o d a t e
i 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 Sim˜es
o Building C/C++ libraries with Perl
18. 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 ’ ) ;
...
# define flags
my $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 t h e e x e c u t a b l e
i f ( ! $self−>up_to_date ( $object , $exe_file ) ) {
$libbuilder−>link_executable (
exe_file => $exe_file ,
objects => [ $object ] ,
extra_linker_flags =>
”−L s 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 Sim˜es
o Building C/C++ libraries with Perl
19. 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 Sim˜es
o Building C/C++ libraries with Perl
20. 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 Sim˜es
o Building C/C++ libraries with Perl
21. 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 Sim˜es
o Building C/C++ libraries with Perl
22. Case Study 2
Compiling XS code as... standard XS code (mostly)
§ ¤
sub ACTION_compile_xscode {
...
# c r e a t e CLD . c c from CLD . x s
ExtUtils : : ParseXS : : process_file ( . . . ) ;
# c r e a t e CLD . o from CLD . c c
$cbuilder−>compile ( . . . ) ;
# C r e a t e . b s b o o t s t r a p f i l e , n e e d e d by D y n a l o a d e r .
ExtUtils : : Mkbootstrap : : Mkbootstrap ( . . . ) ;
# set linker flags
my $xlinkerflags = ”−L c l d −s r c − l c l d − l s t d c++” ;
$xlinkerflags .= ” − l g c c s ” i f $ˆO eq ’ n e t b s d ’ ;
# link
$cbuilder−>l i n k ( . . . ) ;
¦ ¥
Alberto Sim˜es
o Building C/C++ libraries with Perl
23. 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 Sim˜es
o Building C/C++ libraries with Perl
24. Thank you!
Alberto Sim˜es
o Building C/C++ libraries with Perl