Find Your Way Around a Perl Core Source Tree
You will finish with a practical map of the Perl source tree, a way to locate the right kind of file, and a small command for checking the top-level manifest. The guide describes the installed perlsource(1) manual from Perl 5.38.2, supplied here by perl-doc version 5.38.2-3.2ubuntu0.6. Allow about fifteen minutes to read it and another fifteen to explore a checkout.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a Perl source checkout and an ordinary shell. You do not need root privileges, and none of the commands below edits, configures or builds Perl. Keep a clean checkout when you are only investigating: it makes later changes easier to review.
1. Confirm the installed reference
Start by checking that the documentation package and interpreter are the versions you expect. These are read-only commands:
$ dpkg-query -W -f='${Package} ${Version}\n' perl perl-doc
perl 5.38.2-3.2ubuntu0.6
perl-doc 5.38.2-3.2ubuntu0.6
$ perl -v
This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi
The exact package revision and architecture can differ. What matters here is that perlsource is a guide to the layout of the Perl core source tree, not a command that searches an arbitrary installed Perl library tree. Read its version-specific description when working on another Perl release.
Checkpoint
You have a source checkout and know which Perl documentation describes it.
2. Identify the top-level areas
Most C source and headers live in the root of the checkout. Platform-specific C code is kept in directories for particular systems, and some bundled modules contain C or XS code of their own. The root is therefore the right first stop for interpreter work, but not every implementation file will be beside perl.c or another familiar name.
Core modules are split into four areas. The distinction is about ownership and release expectations, not just file type:
lib/contains pure-Perl modules released only as part of the core. Their tests are next to the modules.ext/contains core-only modules in a CPAN-style layout, usually with their ownMakefile.PL. They may use improvements from the development version of Perl and are not expected to support earlier Perl 5 versions.dist/contains dual-life modules for which the Perl development tree is canonical. Some may not yet have a separate CPAN release.cpan/contains dual-life modules for which the CPAN distribution is canonical.
Safety boundary
Do not patch a module in cpan/ as though it were owned by the core tree. Submit the change to that module's CPAN maintainer; a later released version is what should be incorporated into Perl.
3. Find the tests that match your change
Tests are not all in one directory. A module under lib/ normally has its test beside it, such as lib/strict.pm and lib/strict.t. Modules under ext/, dist/ and cpan/ generally use a t/ subdirectory in their distribution layout.
The top-level t/ tree groups tests by language or runtime concern:
t/base/covers fundamental operations and runs first.t/cmd/covers control structures and subroutines, whilet/comp/covers parsing and compilation.t/io/covers built-in IO and command-line arguments.t/mro/covers method resolution order, andt/op/covers built-in functions without a more specific home.t/opbasic/tests built-ins that cannot uset/test.plbecause that helper depends on the functionality under test.t/re/covers regular-expression behaviour,t/run/covers execution andPERL*environment variables, andt/uni/covers Unicode.t/win32/contains Windows-specific tests andt/porting/checks source-tree conventions and common errors.
t/lib/ is the old home for module tests. Existing tests remain there, but new module tests should normally follow the current layout for the module they cover.
Use the checkout itself to verify what is present rather than assuming every release has the same files:
$ cd /path/to/perl-source
$ find lib ext dist cpan -maxdepth 2 -name 'strict.pm' -o -name 'strict.t' 2>/dev/null
$ find t -maxdepth 2 -type d | sort | sed -n '1,20p'
The first command is only a quick orientation search. For a real patch, inspect the module's own directory and its neighbouring tests before choosing a test location.
4. Separate user documentation from developer notes
Documentation for Perl users lives in pod/. A module can also carry documentation in its Module.pm file or in a matching Module.pod file under lib/, ext/, dist/ or cpan/.
Documentation for people working on the core belongs in Porting/. That directory also contains maintenance tools and notes. In particular, Porting/Maintainers, Porting/Maintainers.pl and Porting/Maintainers.pm describe module ownership. For a dual-life module, the manual gives this lookup pattern:
$ perl Porting/Maintainers -M Module::Name
Replace Module::Name with the module you are investigating. The command is informational; it does not change ownership or files. Porting/podtidy can tidy a POD file after a patch, while the Porting/check* scripts check areas such as C style and POD encoding.
5. Trace how a Perl build is assembled
On Unix-like systems, the build starts with Configure in the source-tree root. It generates a Makefile from Makefile.SH. Platform-specific build pieces live in directories such as win32/ and vms/, which have their own Configure-like scripts.
The system behind these scripts is called metaconfig. It is maintained separately from the Perl core. If your work involves cross-compilation, inspect Cross/README and the other files in Cross/ before changing build logic. Do not edit a generated Makefile as a durable fix: find the source template or configuration step that produced it.
6. Use the manifest when a filename is unclear
The root-level MANIFEST lists every file in the Perl core with a short description. The manual provides a compact way to list top-level C and header entries from it:
$ perl -lne 'print if /^[^\/]+\.[ch]\s+/' MANIFEST
The pattern selects entries whose path has no slash and whose filename ends in .c or .h. It is an overview, not a complete index of module or platform-specific code. Verify a candidate before editing:
$ test -f MANIFEST && echo 'manifest found'
manifest found
$ git status --short
An empty git status --short means the checkout has no uncommitted changes. If it prints paths, stop and understand those changes before adding anything. This guide does not require an elevated shell, and you should not use sudo to inspect a source tree.
Common traps
Do not treat every module as core-owned: cpan/ has a different upstream authority. Do not put every test under top-level t/ when the module already has adjacent tests. Do not infer build ownership from a generated Makefile. Finally, do not assume a directory exists in every Perl release; check the checkout and its MANIFEST for the version you are changing.
Done means
- You can distinguish root C code, core modules, dual-life modules and platform-specific areas.
- You know where the relevant module tests belong and which
t/category fits runtime changes. - You can separate user POD from core-developer material in
Porting/. - You know to trace Unix build changes through
ConfigureandMakefile.SH, not a generated Makefile. - You have checked
MANIFESTandgit status --shortbefore editing.