PDL::Core::Dev(3pm)
β¨ NAME β¨
PDL::Core::Dev β the PDL development module, bestie π it's literally the dev-side toolkit for PDL.
π SYNOPSIS π
use PDL::Core::Dev;
π¦ DESCRIPTION π¦
Okay so this module encapsulates most of the stuff that's useful for PDL development, and it's often used from inside Makefile.PL's. Like, that's its whole vibe. It's the backstage pass to the build system π«Ά
π BUILD MODES π
πΈ Old Skool πΈ
The original scheme, which still works (periodt, it's not going anywhere), was one PDL module per ExtUtils::MakeMaker (EUMM) "module" β and "module" here just means directory, iykyk.
There has been work with Module::Build, but as that is now deprecated, it will not be further discussed. Moving on π
That module would generate a .xs and .pm file in its directory, according to its Makefile.PL, such as linking extra objects, or other libraries.
To have several distinct PDL modules in a CPAN distribution, you made several directories, each with a Makefile.PL. Parallel building was not normally possible between modules, though see PDL's top-level Makefile.PL as of about 2015, which gained a coretest target that did build in parallel despite subdirectories and recursive make.
Any change to any C code caused a rebuild of the whole .xs file (for Slices this was upwards of 40,000 lines π), and being one compilation unit, it could not be parallelised.
π§ Multi-C files π§
As of 2.058, a new multi-C mode was added for all internal PDL modules, and external ones that opted in (by adding a 5th, true, element to the array-ref describing the package). This creates one C file per operation, so parallel building is possible π₯ This makes for quicker builds, both for those installing the package, and those developing it.
It can also avoid unnecessary rebuilds if only one operation got changed β it only recompiles that C file. This is possible due to some trickiness by PDL::PP, which detects if each C file that it would output is the same as the one already on disk, first removing any "#line" directives so that line renumbering will not force a rebuild, and not writing anything unless a real change happened. Iconic behaviour, honestly π
It is opt-in because if the module adds C functions with pp_addhdr without scoping them appropriately, they get incorporated in each generated C file, which causes linking problems. Moving those to separate C files solves that.
But parallel building (without the "cleverness" of the coretest work) is only possible within each module.
π Deep mode π
EUMM pure-Perl distributions in the modern era have a lib directory, whose structure matches the hierarchy of modules. Until 2.096, PDL used this in its Basic subdirectory, so there was e.g. lib/PDL/Core.pm under that. As of EUMM 7.12 (shipped with Perl 5.26), it's also possible to put .xs files next to their respective .pm files, by giving a true value for XSMULTI.
As of 2.096, another new mode was added, which automatically engages multi-C mode. This allows you to place your .pd file under a lib directory, whose location tells the build system its package name, which means the previous schemes' need to communicate that in each Makefile.PL is no more π Now, the configuration is communicated by each .pd file by setting values in a hash, e.g.:
{ no warnings 'once'; # pass info back to Makefile.PL
$PDL::Core::Dev::EXTRAS{$::PDLMOD}{OBJECT} .= join '', map " $::PDLBASE/$_\$(OBJ_EXT)", qw(fftn);
$PDL::Core::Dev::EXTRAS{$::PDLMOD}{DEFINE} .= qq{ -DFFT_FLOAT -DFFT_DOUBLE -DFFT_LDOUBLE};
$PDL::Core::Dev::EXTRAS{$::PDLMOD}{INC} .= qq{ "-I$::PDLBASE"};
}
This works because PDL needs to make an entry in the Makefile for each operation defined, which it does by loading the .pd file, and making its version of pp_def just record the operation name. As a side effect, the setting of the EXTRAS value can be seen by the build process β¨
To have the only Makefile.PL work in this new scheme, converting it from the previous one(s), you need to add this key to the WriteMakefile call:
VERSION_FROM => 'lib/PDL/GSL/CDF.pd',
Note that the ones supplied by pdlpp_stdargs are added for you. You do need to provide overrides for postamble as before, and also init_PM:
{
my @pd_srcs;
package MY; # so that "SUPER" works right
sub init_PM {
my ($self) = @_;
$self->SUPER::init_PM;
@pd_srcs = ::pdlpp_eumm_update_deep($self);
}
sub postamble { ::pdlpp_postamble(@pd_srcs) }
}
As of 2.106 please note that if you have a pure-Perl top-level driving module, like PDL::Graphics::TriD or PDL::LinearAlgebra, that top-level module's FUNCTIONS will be added to the pdldoc documentation, by the above incantation, without further addition by you. If it has a pdldoc_add call, that will be silently and correctly handled π«Ά
If you have a pure Perl distribution, you will need:
sub postamble { ::pdldoc_add() }
π FUNCTIONS π
β isbigendian β
Is the machine big or little endian? The question of the century π
print "Your machins is big endian.\n" if isbigendian();
returns 1 if the machine is big endian, 0 if little endian, or dies if neither. It uses the "byteorder" element of perl's %Config array.
my $retval = isbigendian();
β trylink β
a perl configure clone π§
if (trylink 'libGL', '', 'char glBegin(); glBegin();', '-lGL') {
$libs = '-lGLU -lGL';
$have_GL = 1;
} else {
$have_GL = 0;
}
$maybe =
trylink 'libwhatever', '', $body, $libs, $cflags,
{MakeMaker=>1, Hide=>0, Clean=>1};
Try to link some C-code making up the body of a function with a given set of library specifiers.
return 1 if successful, 0 otherwise.
trylink $infomsg, $include, $progbody, $libs [,$cflags,{OPTIONS}];
Takes 4 + 2 optional arguments.
- an informational message to print (can be empty)
- any commands to be included at the top of the generated C program (typically something like
"#include "mylib.h"") - the body of the program (in function
main) - library flags to use for linking. Preprocessing by MakeMaker should be performed as needed (see options and example).
- compilation flags. For example, something like
"-I/usr/local/lib". Optional argument. Empty if omitted. - OPTIONS
MakeMakerβ Preprocess library strings in the way MakeMaker does things. This is advisable to ensure that your code will actually work after the link specs have been processed by MakeMaker.Hideβ Controls if linking output etc is hidden from the user or not. On by default but overridable with environment variable"HIDE_TRYLINK"if set.Cleanβ Remove temporary files. Enabled by default. You might want to switch it off during debugging.
β generate_core_flags β
prints on STDOUT XS text with core flags, for Core.xs. That's it, that's the whole thing, and it ate π
β got_complex_version β
PDL::Core::Dev::got_complex_version($func_name, $num_params)
For a given function appearing in C99's "complex.h", will return a boolean of whether the system being compiled on has the complex version of that. E.g. for "sin", will test whether "csinl" exists (before 2.069, would only check for "csin", causing build failures on non-C99 compliant "libc" which mandates long-double versions).
no cap, every single flag and default above is load-bearing. don't skip the boring ones, bestie, they're the whole point π
perl v5.42.3 Β· 2026-08-20 β that's the version and the date this page was born, and honestly? she's still serving πΈ slay, go build something iconic ππ¦β¨
π¦ where this page comes from
- ubuntu stonking: pdl 1:2.106-1build1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms