Alien-Libgit2
view release on metacpan or search on metacpan
.claude/skills/perl-alien/SKILL.md view on Meta::CPAN
---
name: perl-alien
description: "Use when a distribution provides a C library or tool through Alien::Build â writing or debugging an alienfile, probe/system/share builds, pkg-config detection, bundling a source tarball, or consuming cflags and libs from Alien::Base i...
---
# Alien â providing a C library to CPAN
An `Alien::Foo` distribution answers one question at install time: **is a usable
libfoo already here, and if not, how is one built?** Everything downstream â the XS
module that links against it, the FFI module that dlopens it â asks the resulting
class for flags and never repeats that logic.
Two halves, both small:
- The **`alienfile`** in the distribution root describes probing and building.
- **`lib/Alien/Foo.pm`** is `use parent 'Alien::Base';` plus POD. There is no logic
to write there â `Alien::Base` supplies `cflags`, `libs`, `dynamic_libs`,
`bin_dir`, `version`, `runtime_prop`.
Build details, properties and the plugin catalogue:
[references/alienfile.md](references/alienfile.md).
The XS/FFI side, `cpanfile`, and `Test::Alien`:
[references/consuming-and-testing.md](references/consuming-and-testing.md).
## The shape
```perl
use alienfile;
use Path::Tiny;
plugin 'PkgConfig' => (
pkg_name => 'libssh',
minimum_version => '0.9',
);
share {
start_url 'file://' . path('share/libssh-0.10.6.tar.xz')->absolute->stringify;
plugin 'Fetch::Local';
plugin 'Extract' => 'tar.xz';
plugin 'Build::CMake';
build [
[ '%{cmake}', '-DCMAKE_INSTALL_PREFIX=%{.install.prefix}',
'-DCMAKE_BUILD_TYPE=Release', '%{.install.extract}' ],
'%{make}',
'%{make} install',
];
};
```
| Block | Runs when | Holds |
|---|---|---|
| `probe` | always, first | the test for a usable system library |
| `sys` | probe said `system` | how to gather flags from what is installed |
| `share` | probe said `share` | fetch, extract, build into the Alien's own prefix |
## Let the PkgConfig plugin write the probe
`plugin 'PkgConfig'` covers probe and `sys` in one line: it tests with pkg-config,
gathers `cflags`/`libs`/`version` from it, and leaves only `share` to write. A
hand-rolled `probe [ 'pkg-config --exists libfoo' ]` plus a `sys { gather sub { ⦠} }`
that shells out to pkg-config is the same thing with more places to be wrong â and
it quietly has no version check.
For a library with no stable system packaging, skip the probe entirely:
```perl
probe sub { 'share' };
```
## minimum_version earns its keep
A system library that is present but too old is worse than none: it links, it runs,
and it misbehaves. State the floor in the probe, and **say in a comment what the
floor is for** â an API that appeared, or a bug that was fixed, with the measurement
if there was one. Without that sentence the number becomes unfalsifiable, and nobody
( run in 1.200 second using v1.01-cache-2.11-cpan-80ec619307d )