A Year of **Alien** and **Platypus** Note: Today I would like to talk to you about the Alien and Platypus projects...
In the year since *The Perl Conference in Pittsburgh*, **Alien::Build** and **FFI::Platypus** have had some useful enhacements Note: ...and what we've accomplished in the past year since the last Perl Conference.
**Alien::Build** is a toolkit for defining external dependencies, and making them available for CPAN Note: For those of you who are not aware, Alien::Build is a toolkit for defining external (non-CPAN) dependencies and making them available for CPAN and your local Perl projects.
New **Alien** Tech: Note: New Alien tech this year includes:
The **Build::Copy**
*
Plugin for Alien::Build for aliens without a build step ```perl [5] use alienfile; ... share { start_url "https://github.com/..."; plugin 'Build::Copy'; } ```
*
Used by *Alien::wasmtime* and *Wasm*
Note: The Build::Copy plugin for aliens that lack complicated compile and build steps, and just need to copy files into their share directory. Alien::wasmtime uses this since wasmtime is distributed as Linux, macOS and Windows binary
The **Win32::Vcpkg** module and **Probe::Vcpkg** plugin makes it easier to use Visual C++ Perl ```perl [2] use alienfile; plugin 'Probe::Vcpkg' => 'libffi' if ```
*
Used by *Alien::FFI* and *FFI::Platypus*
Note: The Vcpkg module and plugin make it easier to build Perl modules with external dependencies on Visual C++ Perl This makes Platypus installs on Visual C++ Perl easy.
**Vcpkg** is a **cmake** based package management system for Visual C++ with a much larger set of open source packages that what is available to Strawberry Perl Note: Although Strawberry Perl is the defacto standard Perl on Windows, it is bad at handling external dependencies. Even with advanced Alien technology it is a challenge, and I think the vast array of open source Vcpkg packages coupled with Visual C++ Perl could give Strawberry a run for its money.
A number of adoptions of older broken *Alien* modules by the folks of *#native* on *irc.perl.org* 🎉 Note: The folks on the #native IRC channel have pushed to fix and/or adopt older borken Alien modules on CPAN. If you own one of these, please review the patches, put the modules up for adoption, or contact us on IRC for more help.
**FFI::Platypus** is for writing library bindings for Perl Note: Platypus is a library for writing library bindings in Perl. It is easier to learn and use than XS.
New **Platypus** Tech: Note: New Platypus tech this year includes:
**FFI::C** is an interface to C style nested data structures ```perl [1-18|3-7|9-13|15-18] use FFI::C; package ColorValue { FFI::C->struct([ red => 'uint8', green => 'uint8', blue => 'uint8', ]); } package NamedColor { FFI::C->struct([ name => 'string(22)', value => 'color_value_t', ]); } my $red = NamedColor->new({ name => "red", value => { red => 255 } }); ```
*
Used by *NewFangle* and *Wasm::Wasmtime*
Note: The FFI::C module is for defining datatypes common in the C programming language. In particular it was difficult in the past to work with nested data with Platypus. In this example 1. define a color type with red, green and blue values 2. nest that color type inside a named color type 3. and now we can create an instance of that named color, which can be a passed into C using Platypus.
**FFI::C** supports unions ```perl [1-17|3-10|12-13] use FFI::C; package AnyInt { FFI::C->union([ u32 => 'uint32', u64 => 'uint64', i32 => 'sint32', i64 => 'sint64', ]); } my $ai = AnyInt->new({ u32 => 0xffffffff }); say $ai->i32; # print signed ``` Note: You can also 1. define 2. and use unions.
**FFI::C** makes using enumerated types (*enum*) easier ```perl [1-14|3-9|11|13-14] use FFI::C; package Config { FFI::C->enum([ 'default', 'better', ['best' => 12], ]); } $ffi->attach( set_config => [ 'config_t' ] ); set_config( 'better' ); # passes 1 set_config( 'best' ); # passes 12 ``` Note: It also makes it easy to work with enumerated types by allowing you to 1. define an enum 2. define a function that takes an enum 3. and then by calling that function. The strings are translated to integer values for you.
Platypus now has an interface for **Bundling** code from other languages ```c [1-36|4-7|9-17|19-29|31-36] #include "ffi_platypus_bundle.h" #include "string.h" typedef struct { char *name; int value; } foo_t; foo_t* foo__new(const char *class_name, const char *name, int value) { (void)class_name; foo_t *self = malloc( sizeof( foo_t ) ); self->name = strdup(name); self->value = value; return self; } const char * foo__name(foo_t *self) { return self->name; } int foo__value(foo_t *self) { return self->value; } void foo__DESTROY(foo_t *self) { free(self->name); free(self); } ``` Note: Platypus now has an interface to make it easy to bundle code from other languages. In this example we 1. define a struct to represent a class 2. write a constructor for that class 3. along with some methods 5. and a destructor
```perl [1-21|13|15-20] package Foo; use FFI::Platypus 1.00; my $ffi = FFI::Platypus->new( api => 1 ); $ffi->type('object(Foo)' => 'foo_t'); $ffi->mangler(sub { my $name = shift; $name =~ s/^/foo__/; $name; }); $ffi->bundle; $ffi->attach( new => [ 'string', 'string', 'int' ] => 'foo_t', ); $ffi->attach( name => [ 'foo_t' ] => 'string' ); $ffi->attach( value => [ 'foo_t' ] => 'int' ); $ffi->attach( DESTROY => [ 'foo_t' ] => 'void' ); ``` Note: Now we can bind this interface to Perl by 1. calling the bundle method which tells Platypus to use the C code that came with this dist 2. and attaching the methods so they can be used in Perl.
Define constants from C using the bundle interface ```c [1-13|11|12] #include "ffi_platypus_bundle.h" #define FOO "BAR" #define ANSWER 42 void ffi_pl_bundle_constant( const char *package, ffi_platypus_constant_t *c) { set_str("FOO", FOO); set_uint("ANSWER", ANSWER); } ``` Note: The bundle interface also has entry points to make it easy to define 1. string 2. and integer constants for Perl from C
Platypus now supports variadic functions ```perl [1-9|4-8|9] use FFI::Platypus 1.00; my $ffi = FFI::Platypus->new( api => 1 ); my $printf = $ffi->function( 'printf' => [ 'string'] => [ 'string', 'int', 'float' ] ); $printf->call("%s %d %g\n", "hello", 42, 3.14); ``` Note: Variadic functions like printf are supported. 1. You can define a function using fixed and variable argument types 2. and call it.
Platypus now has support for **pass-by-value records** ```perl [1-15|14|15] use FFI::Platypus 1.00; my $ffi = FFI::Platypus->new( api => 1 ); package Color { use FFI::Platypus::Record; record_layout_1(qw( uint8 red uint8 green uint8 blue )); } $ffi->attach( set_color_value => [ 'record(Color)' ]); $ffi->attach( set_color_ptr => [ 'record(Color)*' ]); ``` Note: Platypus now supports passing records by value 1. This is the default when using the new version 1 api. 2. A star indicates a pointer if you need pass-by-reference
**Pass-by-value records** support is essential for modern languages like *Go* and *Rust* Note: Pass-by-value records are esenital for modern languages like Go and Rust...
(these languages typically store strings as a pointer/integer pair, which are passed by value) Note: ...since these languages typically store strings as pointer/integer pairs, which are passed by value.
* New **FFI::Platypus::Lang::Go** language plugin for *Go* * Improved **FFI::Platypus::Lang::Rust** language plugin for *Rust* Note: as a result, Go and Rust are easier to call with new and improved language plugins.
New Tech Built with **Alien** and **Platypus**: Note: With all these new toys, we've built some cool things with Alien and Platypus
**Wasm::Wasmtime**: bindings to the rust *Wasmtime* library for calling into *WebAssembly* from Perl Note: Like the wasmtime bindings for calling WebAssembly from Perl. If you missed the talk that I gave about this project earlier in the week, you can check it out on the Perl Conference YouTube channel.
**NewFangle**: bindings to the *libnewrelic* library to replace the no longer supported `NewRelic::Agent` and `NewRelic::Agent::FFI` Note: We also have new bindings for NewRelic. Useful for NewRelic users in Perl, since the older libraries never left beta and are no longer supported.
What about next year? Note: What about next year?
Maybe write some *libclang* bindings using Platypus... Note: Maybe someone could write some libclang bindings...
...and write a code generator (**h2ffi**) that will reduce the tedius part of writing FFI bindings Note: and we can write a code generator to make writing FFI bindings with lots of functions less tedius.
Maybe migrate some of your *XS* or *FFI* code to use an *Alien*... Note: Maybe you can migrate some of your XS or FFI code to use an Alien...
...and make life easier for your users Note: ...and make it easier for your users to install
Please join us to see what we can accomplish in the next year * The *#native* chanel on *irc.perl.org* * The *Perl5-FFI* and *Perl5-Alien* organization on GitHub Note: If you are interested in Alien and Platypus tech, please join us on the #native channel on IRC or the appropriate project orgs on GitHub Since I have a few more seconds I also want to mention that we are planning on migrating these organizations to new ones that do not have five in the name thanks to the Perl 7 announcement earlier in the week. The Alien and Platypus teams are excited about this change.